Boost Graph Library:邻接矩阵的子图同构问题求助
问题分析与解决方案
错误根源
adjacency_matrix不支持bidirectionalS:Boost的adjacency_matrix设计中,Directed模板参数仅允许directedS(有向图)或undirectedS(无向图),静态断言直接禁止了bidirectionalS的使用,这是你遇到第一个编译错误的原因。vf2_subgraph_iso要求双向图概念:该算法需要输入图满足BidirectionalGraph概念(支持入边查询、入度统计等接口),但adjacency_matrix<directedS>默认仅实现了DirectedGraph的基础接口,无法通过概念检查,导致第二个编译错误。
解决方案
我们可以为adjacency_matrix<directedS>补充BidirectionalGraph所需的接口,让它满足算法要求。以下是修改后的完整代码:
#include <boost/graph/adjacency_matrix.hpp> #include <boost/graph/vf2_sub_graph_iso.hpp> #include <iostream> #include <vector> typedef boost::adjacency_matrix<boost::directedS> Graph; // 实现入边查询函数,返回顶点v的所有入边 template <> std::pair<std::vector<typename boost::graph_traits<Graph>::edge_descriptor>::iterator, std::vector<typename boost::graph_traits<Graph>::edge_descriptor>::iterator> in_edges(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph& g) { typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; typedef typename boost::graph_traits<Graph>::edge_descriptor Edge; static std::vector<Edge> edges; edges.clear(); for (Vertex u = 0; u < boost::num_vertices(g); ++u) { auto edge_result = boost::edge(u, v, g); if (edge_result.second) { edges.push_back(edge_result.first); } } return std::make_pair(edges.begin(), edges.end()); } // 实现入度统计函数 template <> typename boost::graph_traits<Graph>::degree_size_type in_degree(typename boost::graph_traits<Graph>::vertex_descriptor v, const Graph& g) { typename boost::graph_traits<Graph>::degree_size_type count = 0; typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; for (Vertex u = 0; u < boost::num_vertices(g); ++u) { if (boost::edge(u, v, g).second) { ++count; } } return count; } // 特化graph_traits,将定向类别改为双向图标签,通过概念检查 namespace boost { template <> struct graph_traits<Graph> { typedef typename graph_traits<adjacency_matrix<directedS>>::vertex_descriptor vertex_descriptor; typedef typename graph_traits<adjacency_matrix<directedS>>::edge_descriptor edge_descriptor; typedef typename graph_traits<adjacency_matrix<directedS>>::vertex_iterator vertex_iterator; typedef typename graph_traits<adjacency_matrix<directedS>>::edge_iterator edge_iterator; typedef typename graph_traits<adjacency_matrix<directedS>>::out_edge_iterator out_edge_iterator; typedef std::vector<edge_descriptor>::iterator in_edge_iterator; typedef typename graph_traits<adjacency_matrix<directedS>>::adjacency_iterator adjacency_iterator; typedef typename graph_traits<adjacency_matrix<directedS>>::vertices_size_type vertices_size_type; typedef typename graph_traits<adjacency_matrix<directedS>>::edges_size_type edges_size_type; typedef typename graph_traits<adjacency_matrix<directedS>>::degree_size_type degree_size_type; typedef bidirectional_tag directed_category; typedef typename graph_traits<adjacency_matrix<directedS>>::edge_parallel_category edge_parallel_category; typedef typename graph_traits<adjacency_matrix<directedS>>::traversal_category traversal_category; }; } int main(int argc, char* argv[]) { Graph g_small(3); boost::add_edge(0, 1, g_small); boost::add_edge(1, 2, g_small); boost::add_edge(2, 0, g_small); Graph g_large(5); boost::add_edge(0, 1, g_large); boost::add_edge(1, 2, g_large); boost::add_edge(2, 3, g_large); boost::add_edge(3, 4, g_large); boost::add_edge(4, 2, g_large); auto callback = [&](auto f, auto f_inv) { std::cout << "isomorphism found" << std::endl; return true; // 继续查找其他同构匹配 }; boost::vf2_subgraph_iso(g_small, g_large, callback); return 0; }
注意事项
- 入边查询函数使用静态
vector避免重复内存分配,可根据实际需求调整实现方式; - 对于超大图,入边查询的O(V)复杂度可能存在性能开销,但
adjacency_matrix的O(1)边查询效率仍优于adjacency_list在大图场景下的表现; - 该方案兼容Boost 1.66至1.83版本,符合你的环境要求。
内容的提问来源于stack exchange,提问作者Edward Doolittle
相关产品推荐
相关产品推荐

