pythongraphundirected-graph

How to find the maximum number of pair of nodes that can be matched in a graph?


I am trying to find a way in Python to pair up nodes in an undirected graph such that the maximal amounts of nodes is reached, while no node appears more than once.

Example:

Input1: Graph with 3 nodes and edges [A, B], [A, C], [B, C]

Output1: should be 2 because there is no way to choose more than one edge such that no node is repeated.

Input2: Graph with 6 nodes and edges [A, B], [A, C], [A, D], [B, D], [B, E], [B, F], [C, D], [C, F], [E, F]

Output2: should be 6 because all nodes can be paired. For example, with edges [A, B], [C, D], [E, F].


Solution

  • LOOP N1N2 over edges
        C = Count of unique nodes connected to the two nodes connected by edge
        Store N1N2 in MM, a multimap keyed by C
    LOOP N1N2 over MM, from smallest C
        Add N1N2 to RESULT
        Remove all edges connecting N1 or N2 from MM
    OUTPUT RESULT
    

    N1N2 is a single variable indexing the edge between nodes N1 and N2

    Here is a C++ implementation of this algorithm

    void cGraph::solve()
    {
        myResult.clear();
        std::multimap <int, int > edgeMap;
    
        // loop over edges
        int i = -1;
        for (auto &n1n2 : vEdge)
        {
            i++;
            int c = countNeighbors(n1n2);
    
            // store edge index keyed by count of neigbors
            edgeMap.insert({ c, i });
        }
    
        // while edges remain unassigned
        while( edgeMap.size() )
        {
            // assign pair with fewest neigbors to result
            auto pair =  vEdge[ edgeMap.begin()->second ];
            myResult.push_back( pair );
    
            // remove edges that connect nodes in result
            bool done = false;
            while( ! done )
            {
                done = true;
    
                // loop over edges in map
                for(
                std::multimap <int, int >::iterator it = edgeMap.begin();
                it != edgeMap.end();
                it++ )
                {
                    // check for edge connecting node just added to result
                    auto e = vEdge[it->second];
                    if( e.n1 == pair.n1 ||
                     e.n2 == pair.n1 ||
                     e.n1 == pair.n2 ||
                     e.n2 == pair.n2 ) {
    
                        // remove the edge, to prevent duplicate nodes in result
                        edgeMap.erase( it );
    
                        // continue search for edges that connect edges in result
                        done = false;
                        break;
                     }
                }
            }
        }
    
    }
    

    The output is

    test 1
    2 paired nodes found
    1 2
    test 2
    6 paired nodes found
    1 4
    2 5
    3 6
    

    The complete code for the application is here https://gist.github.com/JamesBremner/266e273899df4ca2815762d4bc803474