【问题标题】:c++ remove vertex from a graphc ++从图中删除顶点
【发布时间】:2011-11-04 20:33:40
【问题描述】:

3he 以下使用 boost.1.46.1 编译

#include <boost/graph/adjacency_list.hpp>

struct Node {
  int id;
};

struct Edge {
  int source;
  int target;
  int weight;
};

int main() {
  /* an adjacency_list like we need it */
  typedef boost::adjacency_list<
    boost::setS, // edge container
    boost::listS, // vertex container
    boost::bidirectionalS, // directed graph
    Node, Edge> Graph;

  typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;

  Graph gp1;

  std::cout << "Number of vertices 1: " << boost::num_vertices(gp1) << std::endl;
  Vertex v1 = boost::add_vertex(gp1);
  Vertex v2 = boost::add_vertex(gp1);

  std::cout << "Number of vertices 2: " << boost::num_vertices(gp1) << std::endl;

  gp1[v1].id = 3;
  gp1[v2].id = 4;

  Graph gp2(gp1);

  std::cout << "Number of vertices 3: " << boost::num_vertices(gp2) << std::endl;

  boost::remove_vertex(v2, gp2);

  std::cout << "Number of vertices 4: " << boost::num_vertices(gp1) << std::endl;
  std::cout << "Number of vertices 5: " << boost::num_vertices(gp2) << std::endl;

  boost::graph_traits<Graph>::vertex_iterator it, end;
  for (boost::tie( it, end ) = vertices(gp2); it != end; ++it) {
    if ( gp2[*it].id == 3 ) {
      boost::remove_vertex(*it, gp2);
    }
  }

  std::cout << "Number of vertices 6: " << boost::num_vertices(gp1) << std::endl;
  std::cout << "Number of vertices 7: " << boost::num_vertices(gp2) << std::endl;

  return 0;
}

gp2 在删除 v2 时如何知道 v2:“boost::remove_vertex(v2, gp2)” 为什么gp1的顶点数减少了1?

为什么它会在:“boost::remove_vertex(*it, gp2)”处出现分段错误 我该如何解决?

【问题讨论】:

    标签: c++ boost graph


    【解决方案1】:

    请注意,sehe 的解决方案仅适用于 VertexList=listS 的图,尤其不适用于 VertexList=vecS 的图。另请注意,通常您不能存储顶点描述符或迭代器并在以后删除它们,因为from the Boost Graph Library webiste

    void remove_vertex(vertex_descriptor u, adjacency_list& g)

    ... 如果 adjacency_list的VertexList模板参数为vecS,则全部 图的顶点描述符、边描述符和迭代器是 被此操作无效。内置的 vertex_index_t 属性 每个顶点都被重新编号,以便在操作后顶点 索引仍然形成一个连续的范围 [0, num_vertices(g))。 ...

    【讨论】:

      【解决方案2】:

      您在迭代时正在修改顶点集合。

      先收集要移除的顶点,然后再移除。或者使用以下模式:

      // Remove all the vertices. This is OK.
      graph_traits<Graph>::vertex_iterator vi, vi_end, next;
      tie(vi, vi_end) = vertices(G);
      for (next = vi; vi != vi_end; vi = next) {
        ++next;
        remove_vertex(*vi, G);
      }
      

      来自此页面的示例:http://www.boost.org/doc/libs/1_47_0/libs/graph/doc/adjacency_list.html(当您查找 remove vertices boost graph 时,Google 会返回该示例)

      编辑

      快速将其翻译成您的示例:

      boost::graph_traits<Graph>::vertex_iterator vi, vi_end, next;
      boost::tie(vi, vi_end) = vertices(gp2);
      for (next = vi; vi != vi_end; vi = next) {
          ++next;
          if (gp2[*vi].id == 3)
              remove_vertex(*vi, gp2);
      }
      

      输出:

      Number of vertices 1: 0
      Number of vertices 2: 2
      Number of vertices 3: 2
      Number of vertices 4: 1
      Number of vertices 5: 2
      Number of vertices 6: 1
      Number of vertices 7: 1
      

      没有更多的崩溃:)

      【讨论】:

      • 好的,阅读文档我了解 remove_vertex() 失效/稳定性,但是我的第一个问题呢。当我将 gp1 复制到 gp2 中时。 “boost::remove_vertex(v2, gp2)”是如何工作的?为什么它将 gp1 减少 1 个顶点?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-23
      • 1970-01-01
      • 2015-10-09
      相关资源
      最近更新 更多