顶点描述符描述了一个顶点(以廉价、独立于图模型的方式)。
图模型描述图。
迭代器
当你想遍历一个图时,你可以使用迭代器来遍历这个图:
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)