繁体   English   中英

如何从增强图列表容器查看顶点/边

[英]How to view vertices/edges from boost graph list containers

我试图将listS用作顶点/边容器,以便可以安全地删除边。 但是,我遇到了一个问题-我不知道如何查看我的顶点或边缘! 当我尝试遍历它们并将其打印出来时,它仅出于某种原因才打印出它们的地址。

#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_iterator.hpp>
#include <utility>

using namespace std;

typedef boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS> Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef boost::graph_traits <Graph>::edge_iterator edgeIt;
typedef boost::graph_traits<Graph>::vertex_iterator vertexIt;
typedef map<vertex_t,size_t> IndexMap;

int main(int argc, const char * argv[]) {

    Graph g;

    IndexMap mapIndex;

    vertex_t v0 = boost::add_vertex(g);
    vertex_t v1 = boost::add_vertex(g);
    vertex_t v2 = boost::add_vertex(g);
    vertex_t v3 = boost::add_vertex(g);
    mapIndex[v0] = 0;
    mapIndex[v1] = 1;
    mapIndex[v2] = 2;
    mapIndex[v3] = 3;
    boost::add_edge(v0,v2,g);
    boost::add_edge(v1,v3,g);
    boost::add_edge(v1,v0,g);


    for(pair<vertexIt,vertexIt> vi = boost::vertices(g); vi.first != vi.second; ++vi.first) {
        cout << *vi.first << endl;
    }

    for(pair<edgeIt,edgeIt> ei = boost::edges(g); ei.first != ei.second; ++ei.first) {
        cout << source(*ei.first, g) << " -> " << target(*ei.first, g) << endl;
        cout << *ei.first << endl;
    }
}

输出为:

0x7f9409404b10
0x7f9409404b70
0x7f9409404c00
0x7f9409404c40
0x7f9409404b10 -> 0x7f9409404c00
(0x7f9409404b10,0x7f9409404c00)
0x7f9409404b70 -> 0x7f9409404c40
(0x7f9409404b70,0x7f9409404c40)
0x7f9409404b70 -> 0x7f9409404b10
(0x7f9409404b70,0x7f9409404b10)

如果我使用vecS而不是listS ,它可以正常工作,但是在删除顶点时会遇到麻烦。 那么如何使用listS查看边/顶点呢?

编辑:解决方案

解决方案1:

使用结构来存储属性:

struct vertex {
    int id;
}

typedef boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS, vertex> Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef boost::graph_traits <Graph>::edge_iterator edgeIt;
typedef boost::graph_traits<Graph>::vertex_iterator vertexIt;
typedef map<vertex_t,size_t> IndexMap;

//MAKE YOUR GRAPH
...
//

//Assign vertex IDs
int currentID = 0;
for(pair<vertexIt,vertexIt> it = boost::vertices(g); it.first != it.second; ++it.first) {
    g[*it.first].id = currentID++;
}

//Access them when displaying edges:
for(pair<vertexIt,vertexIt> it = boost::vertices(g); it.first != it.second; ++it.first) {
    cout << g[*it.first].id << endl;
}

//Access them when displaying vertices:
for(pair<edgeIt,edgeIt> it = boost::edges(g); it.first != it.second; ++it.first) {
    cout << g[source(*it.first,g)].id << " " << g[target(*it.first,g)].id << endl;
}

解决方案2:

使用属性映射(从我的第一个代码继续)

for(pair<vertexIt,vertexIt> vi = boost::vertices(g); vi.first != vi.second; ++vi.first) {
    cout << mapIndex[*vi.first] << endl;
}

for(IndexMap::iterator it = mapIndex.begin(); it != mapIndex.end(); ++it) {
    cout << it->first << ": " << it->second << endl;
}

(推测)一种可能性是您正在返回指针的值,即地址。

尝试并两次使用dereference运算符**以测试这些地址上的内容,并查看返回的值是否合理。

Boost中的顶点和边缘数据类型被抽象为descriptors 它们或多或少是指针。

使用vecS ,描述符为size_t索引,并且默认情况下它们对应的顶点和边缘索引图可用。 如果要为listS边和顶点使用整数索引,则必须自己创建它。

我认为,以类似Boost的方式执行此操作的一种好方法是这样。

typedef std::map<vertex_descriptor,size_t> StdVertexIndexMap;
StdVertexIndexMap viMap;
typedef boost::associative_property_map<StdVertexIndexMap> VertexIndexMap;
VertexIndexMap v_index(viMap);
vertex_iterator vi,ve;
size_t i = 0;
for(boost::tie(vi,ve) = boost::vertices(g); vi != ve; ++vi){
    boost::put(v_index,*vi,i);
    ++i;
}

对于Edge同样如此。 有关上下文,请参见我的旧问题 将其包装在boost::associative_property_map或类似的方法中,是Boost方法,以便使用boost::getboost::put的算法可以正常工作。

如果您不打算在boost算法中使用它,则可以使用简单的std::map

暂无
暂无

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

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