简体   繁体   中英

Boost - Find maximum matching edges in a graph

I am a Boost (and C++) newbie, going through the graph library tutorial . I can create a graph and give it vertices and edges. I would like to use maximum cardinality matching in Boost to return a set of edges that form the maximum matching in the graph.

I have looked through max_cardinality_matching.hpp , but am not quite sure how to use it, or which functions to use, to return the maximum matching set of edges.

Here is my code so far:

#include <iostream>
#include <boost/graph/max_cardinality_matching.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>

using namespace boost;


int main(int argc, const char * argv[]) {
    // create a typedef for the Graph type
    typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;

    // Make convenient labels for the vertices
    enum { A, B, C, D, E, F, N };
    const int num_vertices = N;
//    const char* name = "ABCDE";

    // writing out the edges in the graph
    typedef std::pair<int, int> Edge;
    Edge edge_array[] =
    { Edge(A,B), Edge(B,C), Edge(C,D), Edge(D,E), Edge(E,F) };
//    const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);

    // declare a graph object and add the edges
    Graph g(edge_array, edge_array + sizeof(edge_array) / sizeof(Edge), num_vertices);

    // get the property map for vertex indices
    // property_map<Graph, property type>
    typedef property_map<Graph, vertex_index_t>::type IndexMap;
    IndexMap index = get(vertex_index, g);

    // Create an iterator for vertices
    typedef graph_traits<Graph>::vertex_iterator vertex_iter;
    std::cout << "vertices(g) = ";

    // Vertices returns a pair of vertex iterators
    // The first iter points to the beginning of the vertices
    // The second points past the end
    std::pair<vertex_iter, vertex_iter> vp;

    // vertices() returns the vertices in graph g
    for (vp = vertices(g); vp.first != vp.second; ++vp.first)
        std::cout << index[*vp.first] <<  " ";
    std::cout << std::endl;

    graph_traits<Graph>::edge_iterator ei, ei_end;
    std::cout << "edges(g) = ";
    // For each tuple of vertices (an edge), till the end of the edge list ...
    for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
        // ... print out the source and target vertices in the edge
        std::cout << "(" << index[source(*ei, g)] << "," << index[target(*ei, g)] << ") ";
    std::cout << std::endl;

    // Return the set of edges that form a maximum matching in graph g

    return 0;
}

All you need to do is create read-write property map and pass it as second argument to

template <typename Graph, typename MateMap>
bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate);

You can create ordinary std::map where key and value are vertex descriptors and adapts it by associative_property_map in order to use it with checked_edmonds_maximum_cardinality_matching . From this map you can read all edges which create maximum cardinality of your graph.

// Return the set of edges that form a maximum matching in graph g
   typedef graph_traits<Graph>::vertex_descriptor VD;

   std::map<VD,  VD> match;
   boost::associative_property_map< std::map<VD,VD> > mapAdapter(match);

   bool rc = checked_edmonds_maximum_cardinality_matching(g,mapAdapter);
   if (rc)
   {
      std::set<graph_traits<Graph>::edge_descriptor> edges;
      for (auto& i : match)
      {
        std::pair<Graph::edge_descriptor,bool> e = boost::edge(i.first,i.second,g);
        if (e.second)
            edges.insert(e.first);
        std::cout << i.first << " is matched to " << i.second << std::endl;
      }

      // print edges
      for (auto& e : edges)
          std::cout << "edge: " << e << std::endl;
   }

As output you can see:

0 is matched to 1
1 is matched to 0
2 is matched to 3
3 is matched to 2
4 is matched to 5
5 is matched to 4
edge: (0,1)
edge: (2,3)
edge: (4,5)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM