如何创建带有顶点集列表​​升压子?(How to create boost subgraph wit

2019-10-23 07:09发布

下面的代码有错误:

 AAA.cpp:23:15: required from here .../boost/include/boost/graph/subgraph.hpp:333:5: error: static assertion failed: (!is_same<edge_index_type, boost::detail::error_property_not_found>::value) AAA.cpp:27:21: error: no matching function for call to 'add_vertex(foo(int, char**)::<anonymous enum>, Graph&)' AAA.cpp:27:21: note: candidates are: .../boost/include/boost/graph/subgraph.hpp: In instantiation of 'boost::subgraph<Graph>::subgraph(boost::subgraph<Graph>::vertices_size_type, const graph_property_type&) [with Graph = boost::adjacency_list<boost::setS, boost::setS, boost::directedS, boost::no_property, boost::no_property, boost::no_property, boost::setS>; boost::subgraph<Graph>::vertices_size_type = long unsigned int; boost::subgraph<Graph>::graph_property_type = boost::no_property]': 
#include <boost/config.hpp>
#include <iostream>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>

int foo(int,char*[])
{
    using namespace boost;
    typedef subgraph< 
        adjacency_list<
            setS, 
            setS, 
            directedS,
            no_property,
            no_property,
            no_property, // graph prop
            setS // edgelist
            > 
        > Graph;

    const int N = 6;
    Graph G0(N);
    enum { A, B, C, D, E, F}; 

    Graph& G1 = G0.create_subgraph();
    add_vertex(C, G1); // global vertex C becomes local A1 for G1

    return 0;
}

如果我改变设置为血管内皮细胞的顶点列表,它可以编译。 如何创建带有顶点集列表​​升压子?

谢谢,

Answer 1:

首先,它不编译vecS的VertexContainer:

要创建一个图和子图,首先创建根图对象。 这里我们使用的adjacency_list作为底层的图实现。 底层的图型需要具有的vertex_index和edge_index内部属性,所以我们添加的边缘索引属性,以邻接表。 ( 文档

因此,让我们添加一些东西。 现在,它编译:

住在Coliru

#include <boost/config.hpp>
#include <iostream>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>

int main()
{
    using namespace boost;
    using containerS = vecS;
    typedef subgraph< adjacency_list<containerS, containerS, directedS,
            property<vertex_index_t, size_t>,
            property<edge_index_t, size_t>
        >
    > Graph;

    const int N = 6;
    Graph G0(N);
    enum { A, B, C, D, E, F}; 

    Graph& G1 = G0.create_subgraph();
    Graph::vertex_descriptor CG1 = add_vertex(G1);
    Graph::vertex_descriptor EG1 = add_vertex(G1);

    add_edge(CG1, EG1, G1);

    print_graph(G0);
    std::cout << "SUBGRAPH:\n";
    print_graph(G1);
}

打印

0 --> 
1 --> 
2 --> 
3 --> 
4 --> 
5 --> 
6 --> 7 
7 --> 
SUBGRAPH:
0 --> 1 
1 --> 

使用setS

坦率地说,尽管文件表明这间接类似listSsetS可以选择老实说,我不认为这是可行的。

这个问题似乎是如何local_to_globalm_global_vertex已付诸实施。

这可能是一个人造的限制/未实现的功能。 你可能想在开发者邮件列表/ Trac的问题,提出这个问题。



Answer 2:

我发现1)组可以作为outedges和边缘列表2)的vertex_index和edge_index必须定义3),我们也可以在同时使用捆绑属性

后续的代码工作。

#include <boost/config.hpp>
#include <iostream>
#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>

int foo(int,char*[])
{
    using namespace boost;
  typedef adjacency_list_traits<vecS, vecS, directedS> Traits;

  struct EEE {
      int p;
  };

  struct VVV {
      int p;
  };

  typedef subgraph< 
    adjacency_list<
        setS, 
        vecS, 
        directedS,
        property<vertex_color_t, int, VVV>,
        property<edge_index_t, int, EEE>,
        no_property, // graph prop
        setS // edgelist
        > 
    > Graph;

 const int N = 6;
 Graph G0(N);
 enum { A, B, C, D, E, F};     // for conveniently refering to vertices in G0

 Graph& G1 = G0.create_subgraph();
 Graph& G2 = G0.create_subgraph();
 enum { A1, B1, C1 };          // for conveniently refering to vertices in G1
  enum { A2, B2 };              // for conveniently refering to vertices in G2

  add_vertex(C, G1); // global vertex C becomes local A1 for G1
  add_vertex(E, G1); // global vertex E becomes local B1 for G1
  add_vertex(F, G1); // global vertex F becomes local C1 for G1

  add_vertex(A, G2); // global vertex A becomes local A1 for G2
  add_vertex(B, G2); // global vertex B becomes local B1 for G2

  add_edge(A, B, G0);
  add_edge(B, C, G0);
  add_edge(B, D, G0);
  add_edge(E, B, G0);
  add_edge(E, F, G0);
  add_edge(F, D, G0);

  add_edge(A1, C1, G1); // (A1,C1) is subgraph G1 local indices for (C,F).

  Graph::vertex_iterator vi, vi_end;
  VVV vvv;
  EEE eee;
  for (tie(vi, vi_end) = vertices(G0); vi != vi_end; ++vi) {
     G0[*vi].p = 42;
     auto e = add_edge(*vi, *vi, G0);
     G0[e.first] = eee;
  }
  return 0;
}


Answer 3:

作为sehe指出,我们可以很容易地实现local_to_global这样的:

vertex_descriptor local_to_global(vertex_descriptor u_local) const
    { return is_root() ? u_local : m_global_vertex[get(get(vertex_index, m_graph), u_local)]; }

在我的情况,我有添加和删除顶点,同时保持顶点迭代器/描述符的稳定,所以我需要使用listS我的顶点描述符。 这很奇怪的是提升似乎并没有固定在此。



文章来源: How to create boost subgraph with setS vertices list?
标签: c++ boost graph