所以我发布这个是因为我正在研究算法项目,并且可能会使用boost库从输入文本文件构建图形。所以我注意到图中有一个顶点的描述符,但由于我要构建一个非常大的图,我是否需要为该图中的每个顶点分配一个描述符?如果我不这样做,我可以在构建之后遍历整个图形吗?
我是升级库的新手,这有点紧急,所以如果有人能解释一下,我将非常感激!
答案 0 :(得分:1)
顶点描述符描述一个顶点(以便宜的,图形模型独立的方式)。
图表模型描述了一个图表。
如果要遍历图形,可以使用迭代器遍历图形:
typedef boost::adjacency_list<> Graph;
typedef Graph::vertex_iterator Vit;
Vit begin, end;
boost::tie(begin, end) = vertices(g);
取消引用有效迭代器会为您提供描述符(对于边缘迭代器也是如此)。
简单演示:
<强> Live On Coliru 强>
#include <boost/graph/adjacency_list.hpp>
#include <iostream>
int main () {
typedef boost::adjacency_list<> Graph;
typedef Graph::vertex_iterator Vit;
Graph g(10);
add_edge(2,5,g);
add_edge(5,3,g);
add_edge(3,8,g);
Vit begin, end;
boost::tie(begin, end) = vertices(g);
for (Vit it = begin; it != end; ++it) {
unsigned edges = out_degree(*it, g);
if (edges)
std::cout << "vertex #" << *it << " has " << edges << " outgoing edge(s)\n";
}
}
打印:
vertex #2 has 1 outgoing edge(s)
vertex #3 has 1 outgoing edge(s)
vertex #5 has 1 outgoing edge(s)
并非所有图形都具有整数顶点描述符,因此添加边缘变得更加复杂,打印它们看起来并不那么“友好”
<强> Live On Coliru 强>
#include <boost/graph/adjacency_list.hpp>
#include <iostream>
int main () {
typedef boost::adjacency_list<boost::setS, boost::listS/*, boost::undirectedS*/> Graph;
typedef Graph::vertex_iterator Vit;
Graph g(10);
Vit begin, end;
boost::tie(begin, end) = vertices(g);
{
std::vector<Graph::vertex_descriptor> vindex(begin, end);
add_edge(vindex[2], vindex[5], g);
add_edge(vindex[5], vindex[3], g);
add_edge(vindex[3], vindex[8], g);
}
for (Vit it = begin; it != end; ++it) {
unsigned edges = out_degree(*it, g);
if (edges)
std::cout << "vertex #" << *it << " has " << edges << " outgoing edge(s)\n";
}
}
打印
vertex #0x994d00 has 1 outgoing edge(s)
vertex #0x994d70 has 1 outgoing edge(s)
vertex #0x994e50 has 1 outgoing edge(s)
在这种情况下,请考虑添加property bundle。
这样,任意特定于应用程序的信息都可以附加到模型顶点(或边或图形)。
在我看来,主要缺点是没有对属性进行自然索引,因此通过其(捆绑)属性查找图形实体可能会导致性能不佳(线性搜索),除非您在外部保留额外的索引手动图。
<强> Live On Coliru 强>
#include <boost/graph/adjacency_list.hpp>
#include <iostream>
struct VertexProperties {
std::string name;
VertexProperties(std::string name) : name(name) {}
};
int main () {
typedef boost::adjacency_list<boost::setS, boost::listS, boost::directedS, VertexProperties> Graph;
typedef Graph::vertex_iterator Vit;
Graph g;
add_vertex(VertexProperties ("zero"), g);
add_vertex(VertexProperties ("one"), g);
add_vertex(VertexProperties ("two"), g);
add_vertex(VertexProperties ("three"), g);
add_vertex(VertexProperties ("four"), g);
add_vertex(VertexProperties ("five"), g);
add_vertex(VertexProperties ("six"), g);
add_vertex(VertexProperties ("seven"), g);
add_vertex(VertexProperties ("eight"), g);
add_vertex(VertexProperties ("nine"), g);
Vit begin, end;
boost::tie(begin, end) = vertices(g);
{
std::vector<Graph::vertex_descriptor> vindex(begin, end);
add_edge(vindex[2], vindex[5], g);
add_edge(vindex[5], vindex[3], g);
add_edge(vindex[3], vindex[8], g);
}
for (Vit it = begin; it != end; ++it) {
unsigned edges = out_degree(*it, g);
if (edges)
std::cout << "vertex '" << g[*it].name << "' has " << edges << " outgoing edge(s)\n";
}
}
打印
vertex 'two' has 1 outgoing edge(s)
vertex 'three' has 1 outgoing edge(s)
vertex 'five' has 1 outgoing edge(s)