[英]BGL DFS Visitor with Priority Queue
我有一棵樹(在圖形意義上)表示一棵樹(在物理意義上)。 樹表示為 BGL 鄰接表,其中每個頂點包含半徑和 position 屬性,即我的圖定義為
struct TreeVertexType {
double radius;
double position[3];
}
typedef adjacency_list<vecS, vecS, undirectedS, TreeVertexType> Tree;
我想在樹上執行 DFS 以創建分支列表。 附加要求是,當一個頂點有多個未探索的相鄰頂點時,它會選擇具有最大半徑的頂點。 該規則確保圖的遍歷順序代表物理樹枝。
似乎 DFS 訪問者不支持優先級隊列,所以我想知道是否存在通過 A* 獲取此信息的替代搜索公式?
或者,我可以通過對頂點進行排序來實現我自己的 DFS 算法,但如果可能的話,我寧願利用 BGL 框架。
謝謝
-約翰
在 DFS 期間 boost::graph 使用堆棧來推送相鄰的頂點,這些頂點將在稍后按它們被推送的順序彈出。
std::vector<VertexInfo> stack;
//depth_first_search.hpp的第94行boost_1_47_0
作為一種解決方法,您可以使用相同的 push() 和 pop() 接口重新定義此stack
,您可以做的是當任何Vertex
被推入stack
時,只需以具有最大半徑的頂點的方式對your stack
的元素進行排序總是排在首位。
換句話說,使用您自己的優先級隊列偽造一個堆棧接口。
這將減輕您編寫自己的 DFS 的痛苦。
我最終遵循了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 進行排序,我簡單地將邊權重定義為源頂點和目標頂點的平均半徑。
然而,問題是半徑頂點屬性是動態的,並且在創建圖形時是未知的,因此每當我更新邊權重時,邊的順序都不會改變。
有人知道替代方法嗎?
謝謝
-約翰
BGL 中的廣度優先搜索算法更適合您的用例; 它比名稱所暗示的更籠統。 您可以使用push
、 top
和pop
方法插入您自己的隊列,這些方法可以執行您想要的任何排序。
您可以使用setS
而不是vecS
來指定對該特定屬性進行排序的容器。 例如,如果您想對邊進行排序,您將使用adjacency_list<setS, ...>
並為TreeVertexType
使用比較運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.