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].
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