首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Boost的vf2_subgraph_iso检测子图同构?

如何使用Boost的vf2_subgraph_iso检测子图同构?
EN

Stack Overflow用户
提问于 2018-09-28 15:56:31
回答 1查看 338关注 0票数 5

我正在尝试使用Boost的vf2_subgraph_iso()来检测子图同构。

我可以在简单的图上成功地做到这一点,但在multigraph (允许有多条边的图)上做不到。

考虑检测以下G1和G2之间的子图同构:

G1是G2的一个子图,我想使用以下代码来检测它:

代码语言:javascript
复制
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/vf2_sub_graph_iso.hpp>

int main()
{
  // Define edge property
  typedef boost::property<
    boost::edge_name_t,
    char
  > edge_property;

  // Define graph type
  typedef boost::adjacency_list<
    boost::vecS,           // OutEdgeListS
    boost::vecS,           // VertexListS
    boost::bidirectionalS, // DirectedS
    boost::no_property,    // VertexProperties
    edge_property,         // EdgeProperties
    boost::no_property,    // GraphProperties
    boost::listS           // EdgeListS
  > MyGraphType;

  // Build graph G1
  MyGraphType g1;
  std::vector<MyGraphType::vertex_descriptor> v1(3);
  for (auto itr = v1.begin(); itr != v1.end(); ++itr) {
    *itr = boost::add_vertex(g1);
  }
  boost::add_edge(v1[0], v1[1], edge_property('a'), g1);
  boost::add_edge(v1[0], v1[2], edge_property('a'), g1);
  boost::add_edge(v1[1], v1[2], edge_property('b'), g1);

  // Build graph G2
  MyGraphType g2;
  std::vector<MyGraphType::vertex_descriptor> v2(3);
  for (auto itr = v2.begin(); itr != v2.end(); ++itr) {
    *itr = boost::add_vertex(g2);
  }
  boost::add_edge(v2[0], v2[1], edge_property('a'), g2);
  boost::add_edge(v2[0], v2[2], edge_property('a'), g2);
  boost::add_edge(v2[1], v2[2], edge_property('a'), g2);
  boost::add_edge(v2[1], v2[2], edge_property('b'), g2);

  // Create predicate of edge
  typedef boost::property_map<MyGraphType, boost::edge_name_t>::type edge_name_map_t;
  typedef boost::property_map_equivalent<edge_name_map_t, edge_name_map_t> edge_comp_t;
  edge_comp_t edge_comp = boost::make_property_map_equivalent(
    boost::get(boost::edge_name, g1), boost::get(boost::edge_name, g2));

  // Create callback
  boost::vf2_print_callback<MyGraphType, MyGraphType> callback(g1, g2);

  // Execute
  const bool result = boost::vf2_subgraph_iso(
    g1, g2, callback, boost::vertex_order_by_mult(g1),
    boost::edges_equivalent(edge_comp));

  std::cout << "subgraph isomorphic? " << std::boolalpha << result << std::endl;

  return 0;
}

预期结果:

代码语言:javascript
复制
(0, 0) (1, 1) (2, 2)
subgraph isomorphic? true

实际结果:

代码语言:javascript
复制
subgraph isomorphic? false

我的代码哪里错了?

对不起,我的英语很差。谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-03-17 16:05:24

vf2_subgraph_iso将比较edge的属性。在你的代码中,边1->2的属性在graph1中是'b‘,但在graph2中是'a','b’。所以它们不是相同的结构。

如果你想在只匹配所有属性的一部分时返回true,你可以根据你的规则使用一个结构和重载操作符"==“。对于您的示例,以下代码就可以了。

代码语言:javascript
复制
#include <vector>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/vf2_sub_graph_iso.hpp>

int main()
{
  // Define edge property
  struct  EdgeProperties {
      EdgeProperties() {}
      EdgeProperties(char elabel) { _elabels.emplace_back(elabel);}
      EdgeProperties(std::vector<char>& elabels) :_elabels(elabels) {}
      /* overload == */
      bool operator==(EdgeProperties const& other) const {
        for (auto& my_l:_elabels) {
          for (auto& o_l:other._elabels) {
            if (my_l == o_l) return true;
          }
        }
        return false;
      }
      std::vector<char> _elabels;
  };

  typedef boost::property<
    boost::edge_name_t,
    EdgeProperties
  > edge_property;

  // Define graph type
  typedef boost::adjacency_list<
    boost::vecS,           // OutEdgeListS
    boost::vecS,           // VertexListS
    boost::bidirectionalS, // DirectedS
    boost::no_property,    // VertexProperties
    edge_property,         // EdgeProperties
    boost::no_property,    // GraphProperties
    boost::listS           // EdgeListS
  > MyGraphType;

  // Build graph G1
  MyGraphType g1;
  std::vector<MyGraphType::vertex_descriptor> v1(3);
  for (auto itr = v1.begin(); itr != v1.end(); ++itr) {
    *itr = boost::add_vertex(g1);
  }
  boost::add_edge(v1[0], v1[1], edge_property('a'), g1);
  boost::add_edge(v1[0], v1[2], edge_property('a'), g1);
  boost::add_edge(v1[1], v1[2], edge_property('b'), g1);

  // Build graph G2
  MyGraphType g2;
  std::vector<MyGraphType::vertex_descriptor> v2(3);
  for (auto itr = v2.begin(); itr != v2.end(); ++itr) {
    *itr = boost::add_vertex(g2);
  }
  boost::add_edge(v2[0], v2[1], edge_property('a'), g2);
  boost::add_edge(v2[0], v2[2], edge_property('a'), g2);
  std::vector<char> tmp;
  tmp.emplace_back('a');
  tmp.emplace_back('b');
  boost::add_edge(v2[1], v2[2], edge_property(tmp), g2);

  // Create predicate of edge
  typedef boost::property_map<MyGraphType, boost::edge_name_t>::type edge_name_map_t;
  typedef boost::property_map_equivalent<edge_name_map_t, edge_name_map_t> edge_comp_t;
  edge_comp_t edge_comp = boost::make_property_map_equivalent(
    boost::get(boost::edge_name, g1), boost::get(boost::edge_name, g2));

  // Create callback
  boost::vf2_print_callback<MyGraphType, MyGraphType> callback(g1, g2);

  // Execute
  const bool result = boost::vf2_subgraph_iso(
    g1, g2, callback, boost::vertex_order_by_mult(g1),
    boost::edges_equivalent(edge_comp));

  std::cout << "subgraph isomorphic? " << std::boolalpha << result << std::endl;

  return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52550846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档