C++ 如何使用Boost';s vf2_子图_iso?

C++ 如何使用Boost';s vf2_子图_iso?,c++,boost,graph,boost-graph,isomorphism,C++,Boost,Graph,Boost Graph,Isomorphism,我试图用Boost来检测子图同构 我可以在简单的图上成功地做到这一点,但在(允许有多条边的图)上做不到 考虑检测以下G1和G2之间的子图同构: G1是G2的一个子图,我想使用以下代码检测它: #包括 #包括 #包括 int main() { //定义边属性 typedef boost::属性< boost::edge_name_t, 烧焦 >边缘性质; //定义图形类型 typedef boost::邻接列表< boost::vecS,//outedgelist boost::vecS,//顶

我试图用Boost来检测子图同构

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

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

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

#包括
#包括
#包括
int main()
{
//定义边属性
typedef boost::属性<
boost::edge_name_t,
烧焦
>边缘性质;
//定义图形类型
typedef boost::邻接列表<
boost::vecS,//outedgelist
boost::vecS,//顶点列表
boost::双向,//DirectedS
boost::no_属性,//VertexProperties
edge_属性,//EdgeProperties
boost::no_属性,//GraphProperties
boost::列表//边缘列表
>MyGraphType;
//构建图G1
mygraphtypeg1;
std::载体v1(3);
对于(自动itr=v1.begin();itr!=v1.end();++itr){
*itr=boost::添加顶点(g1);
}
boost::add_edge(v1[0],v1[1],edge_属性('a'),g1);
boost::add_edge(v1[0],v1[2],edge_属性('a'),g1);
boost::添加边(v1[1],v1[2],边属性('b'),g1);
//构建图G2
MygraphtypeG2;
std::载体v2(3);
对于(自动itr=v2.begin();itr!=v2.end();++itr){
*itr=boost::添加顶点(g2);
}
boost::add_edge(v2[0],v2[1],edge_属性('a'),g2);
boost::add_edge(v2[0],v2[2],edge_属性('a'),g2);
boost::add_edge(v2[1],v2[2],edge_属性('a'),g2);
boost::add_edge(v2[1],v2[2],edge_属性('b'),g2);
//创建边的谓词
typedef boost::property_map::type edge_name_map\t;
typedef boost::属性映射等效边组件;
edge\u comp\t edge\u comp=boost::使属性映射等效(
boost::get(boost::edge_name,g1),boost::get(boost::edge_name,g2);
//创建回调
boost::vf2_print_回调(g1、g2);
//执行
const bool result=boost::vf2\u子图\u iso(
g1,g2,回调,boost::顶点顺序(g1),
boost::边缘与等效物(边缘与复合物));

std::coutvf2\u子图\u iso将比较edge的属性。在您的代码中,edge 1->2的属性在graph1中是'b',但在graph2中是'a','b'。因此它们的结构不同

如果只匹配所有属性的一部分时希望返回true,则可以根据规则使用struct和重载运算符“==”。 对于您的示例,以下代码可以

#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;
}
#包括
#包括
#包括
int main()
{
//定义边属性
结构边属性{
EdgeProperties(){}
边属性(char-elabel){elabels.emplace_-back(elabel)}
边属性(std::vector&elabels):\u elabels(elabels){}
/*过载==*/
布尔运算符==(边属性常量和其他)常量{
用于(自动和我的电子标签){
用于(自动和操作:其他){
如果(my_l==o_l)返回true;
}
}
返回false;
}
std::vector_elabels;
};
typedef boost::属性<
boost::edge_name_t,
边缘属性
>边缘性质;
//定义图形类型
typedef boost::邻接列表<
boost::vecS,//outedgelist
boost::vecS,//顶点列表
boost::双向,//DirectedS
boost::no_属性,//VertexProperties
edge_属性,//EdgeProperties
boost::no_属性,//GraphProperties
boost::列表//边缘列表
>MyGraphType;
//构建图G1
mygraphtypeg1;
std::载体v1(3);
对于(自动itr=v1.begin();itr!=v1.end();++itr){
*itr=boost::添加顶点(g1);
}
boost::add_edge(v1[0],v1[1],edge_属性('a'),g1);
boost::add_edge(v1[0],v1[2],edge_属性('a'),g1);
boost::添加边(v1[1],v1[2],边属性('b'),g1);
//构建图G2
MygraphtypeG2;
std::载体v2(3);
对于(自动itr=v2.begin();itr!=v2.end();++itr){
*itr=boost::添加顶点(g2);
}
boost::add_edge(v2[0],v2[1],edge_属性('a'),g2);
boost::add_edge(v2[0],v2[2],edge_属性('a'),g2);
std::载体tmp;
tmp.安置后(“a”);
tmp.安置后(“b”);
boost::添加边(v2[1],v2[2],边属性(tmp),g2);
//创建边的谓词
typedef boost::property_map::type edge_name_map\t;
typedef boost::属性映射等效边组件;
edge\u comp\t edge\u comp=boost::使属性映射等效(
boost::get(boost::edge_name,g1),boost::get(boost::edge_name,g2);
//创建回调
boost::vf2_print_回调(g1、g2);
//执行
const bool result=boost::vf2\u子图\u iso(
g1,g2,回调,boost::顶点顺序(g1),
boost::边缘与等效物(边缘与复合物));
std::cout代码已审核,并创建点状图
subgraph isomorphic? false
#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;
}