【问题标题】:How does Boost's graph library link vertex and out-edge list containers?Boost 的图形库如何链接顶点和出边列表容器?
【发布时间】:2014-09-21 11:01:54
【问题描述】:
根据Boost's documentation,顶点及其对应的出边有两种主要的容器类型,两者的默认值都是向量。
两者之间是否存在任何联系,就像地图一样,键是顶点,值是传出边的向量?或者你知道每个顶点指向什么,因为顶点作为一个唯一的 int 存储在顶点列表中,其中每个顶点就像某种向量向量的索引,其中每个向量都包含该向量的传出边顶点?
基本上,一个顶点如何链接到 Boost 邻接列表中其对应的出边列表?
【问题讨论】:
标签:
boost
graph
containers
【解决方案1】:
邻接列表中的每个顶点项,称为stored_vertex,都有一个包含出边的容器,如果是双向的,则包含入边。以下是stored_vertex 的各种风格的定义方式:
// stored_vertex and StoredVertexList
typedef typename container_gen<VertexListS, vertex_ptr>::type
SeqStoredVertexList;
struct seq_stored_vertex {
seq_stored_vertex() { }
seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
OutEdgeList m_out_edges;
VertexProperty m_property;
typename SeqStoredVertexList::iterator m_position;
};
struct bidir_seq_stored_vertex {
bidir_seq_stored_vertex() { }
bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
OutEdgeList m_out_edges;
InEdgeList m_in_edges;
VertexProperty m_property;
typename SeqStoredVertexList::iterator m_position;
};
struct rand_stored_vertex {
rand_stored_vertex() { }
rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
OutEdgeList m_out_edges;
VertexProperty m_property;
};
struct bidir_rand_stored_vertex {
bidir_rand_stored_vertex() { }
bidir_rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
OutEdgeList m_out_edges;
InEdgeList m_in_edges;
VertexProperty m_property;
};
//! This generates the actual stored_vertex type based on
//! the container type.
typedef typename mpl::if_<is_rand_access,
typename mpl::if_<BidirectionalT,
bidir_rand_stored_vertex, rand_stored_vertex>::type,
typename mpl::if_<BidirectionalT,
bidir_seq_stored_vertex, seq_stored_vertex>::type
>::type StoredVertex;
struct stored_vertex : public StoredVertex {
stored_vertex() { }
stored_vertex(const VertexProperty& p) : StoredVertex(p) { }
};
如果顶点的列表类型是随机访问,则 vertex_descriptor 类型为 std::size_t 并表示顶点在stored_vertex 实例的向量中的索引。如果列表类型是基于节点的序列(如列表),则 vertex_descriptor 是 stored_vertex 的内存地址(强制转换为 void*)。这两种情况都提供了从 vertex_descriptor 到底层 stored_vertex 进而到相关边列表的 O(n) 映射。