我有一棵树(在图形意义上)表示树(在物理意义上)。树被表示为BGL邻接列表,其中每个顶点包含半径和位置属性,即,我的图形以
的形式定义struct TreeVertexType {
double radius;
double position[3];
}
typedef adjacency_list<vecS, vecS, undirectedS, TreeVertexType> Tree;
我想在树上执行DFS以创建分支列表。附加要求是,只要顶点具有多个未探测的相邻顶点,它就会选择具有最大半径的顶点。此规则确保图的遍历顺序代表物理树分支。
似乎DFS访问者不支持优先级队列,所以我想知道是否有另一种搜索方式可以通过A *获取此信息?
或者,我可以通过排序顶点来实现我自己的DFS算法,但如果可能的话,我宁愿利用BGL框架。
由于
-John
答案 0 :(得分:3)
在DFS boost :: graph期间,使用一个堆栈来推送相邻的顶点,这些顶点将按照它们被推送的顺序弹出。
std::vector<VertexInfo> stack;
//第94行deep_1_47_0 of depth_first_search.hpp
作为一种解决方法,你可以使用相同的push()和pop()接口重新定义这个stack
,你可以做的是当任何Vertex
被推入stack
只需对your stack
的元素进行排序,使得半径最大的顶点始终位于顶部。
换句话说,伪造一个具有您自己的优先级队列的堆栈接口。
这将减轻您编写自己的DFS的痛苦。
答案 1 :(得分:1)
我最终遵循http://www.boost.org/doc/libs/1_34_0/libs/graph/example/ordered_out_edges.cpp提供的逻辑,即
template <class StoredEdge>
struct weight : public std::binary_function<StoredEdge, StoredEdge, bool>
{
bool operator()(const StoredEdge &lhs, const StoredEdge &rhs) const {
return boost::get(boost::edge_weight, lhs) >
boost::get(boost::edge_weight, rhs);
}
};
struct weightS {};
namespace boost {
template <class ValueType>
struct container_gen<weightS, ValueType> {
typedef std::multiset<ValueType, weight<ValueType> > type;
};
template <>
struct parallel_edge_traits<weightS> {
typedef disallow_parallel_edge_tag type;
};
}
typedef adjacency_list<weightS, vecS, undirectedS, TreeVertexType> Tree;
为了确保out_edges根据半径排序,我只是将边权重定义为源顶点和目标顶点的平均半径。
然而问题是,在创建图形时,半径顶点属性是动态的和未知的,因此每当我更新边权重时,边排序都不会改变。
有人知道另一种方法吗?
由于
-John
答案 2 :(得分:1)
BGL中的广度优先搜索算法更适合您的用例;它比名称暗示的更为通用。您可以使用push
,top
和pop
方法插入自己的队列,这些方法可以执行您想要的任何顺序。
答案 3 :(得分:0)
您可以使用setS
代替vecS
来指定对该特定属性进行排序的容器。例如,如果您想订购边缘,则可以使用adjacency_list<setS, ...>
并为TreeVertexType
设置比较运算符。