简体   繁体   English

boost::graph:如何删除先前删除的顶点的入边?

[英]boost::graph: How to remove in-edges of a previously removed vertex?

I created the simplest directed graph possible using boost::graph, and added 2 vertices that are mutually connected via 2 edges.我使用 boost::graph 创建了最简单的有向图,并添加了 2 个通过 2 条边相互连接的顶点。

After removing the first vertex, the second vertex still has an out-edge that points to the previously removed vertex.删除第一个顶点后,第二个顶点仍然有一个指向先前删除的顶点的出边。

boost::adjacency_list<
    boost::vecS,
    boost::vecS,
    boost::directedS,
    boost::no_property,
    boost::no_property
>  graph;

// add 2 vertices and connect them
auto v0 = boost::add_vertex(graph);
auto v1 = boost::add_vertex(graph);

boost::add_edge(v0, v1, graph);
boost::add_edge(v1, v0, graph);

// remove the first vertex
boost::remove_vertex(v0, graph); 

// iterate over vertices and print their out_degree. 
auto [begin, end] = boost::vertices(graph);

for (auto vertex_itr = begin; vertex_itr != end; ++vertex_itr)
{
    auto vertex_descriptor = *vertex_itr;

    auto out_degree = boost::out_degree(vertex_descriptor, graph);

    std::cout << out_degree << '\n'; // this prints 1
}

To my understanding, my graph is in a sort of "invalid state" where an edge points to a non exiting vertex.据我了解,我的图处于一种“无效状态”,其中一条边指向一个不存在的顶点。 From further examining, it seems as if the "dangling edge" has become an edge with source == target .通过进一步检查,似乎“悬挂边缘”已成为source == target的边缘。 This makes me even more confused as to why boost::graph decided to leave this edge and even go to the trouble of making it cyclic.这让我更加困惑为什么 boost::graph 决定留下这条边,甚至 go 来让它循环。

Questions:问题:

  • How do I fix this?我该如何解决?
  • How do I remove the in edges of a vertex?如何删除顶点的内边?
  • Does it make more sense to use a bidirectional graph in this situation?在这种情况下使用双向图是否更有意义?

Also, I couldn't find anything on the docs regarding this behavior, so I would appreciate if someone could point me to the right place.此外,我在文档中找不到任何关于此行为的信息,所以如果有人能指出我正确的位置,我将不胜感激。

The implementation isn't "going through the trouble" - it's just doing anything, because you didn't satisfy the pre-conditions :实现不是“经历麻烦”——它只是在做任何事情,因为你不满足先决条件

void remove_vertex(vertex_descriptor u, adjacency_list& g)

Remove vertex u from the vertex set of the graph.从图的顶点集中删除顶点 u。 It is assumed that there are no edges to or from vertex u when it is removed.假设当顶点 u 被移除时,没有边到达或来自顶点 u。 One way to make sure of this is to invoke clear_vertex() beforehand.确保这一点的一种方法是事先调用clear_vertex()

I repro-ed your issue slightly more briefly: Live On Coliru我稍微简单地重述了你的问题: Live On Coliru

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

int main() {
    boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> g(2);

    add_edge(0, 1, g);
    add_edge(1, 0, g);

    print_graph(g, std::cout << "--- Before: ");
        
    remove_vertex(0, g); // remove the first vertex

    print_graph(g, std::cout << "--- After: ");

    // iterate over vertices and print their out_degree. 
    for (auto [it, end] = boost::vertices(g); it != end; ++it)
        std::cout << out_degree(*it, g) << "\n"; // this prints 1
}

Prints印刷

--- Before: 0 --> 1 
1 --> 0 
--- After: 0 --> 0 
1

Fixing It修复它

Let's simply do as the docs say:让我们简单地按照文档所说的那样做:

clear_vertex(0, g);  // clear edges
remove_vertex(0, g); // remove the first vertex

Now it works: Live On Coliru , printing:现在可以使用了: Live On Coliru ,打印:

--- Before: 0 --> 1 
1 --> 0 
--- After: 0 --> 
0

BONUS奖金

For more elegance :为了更优雅

// iterate over vertices and print their out_degree. 
for (auto v : boost::make_iterator_range(vertices(g)))
    std::cout << v << " out_degree: " << out_degree(v, g) << "\n";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM