簡體   English   中英

具有優先隊列的 BGL DFS 訪客

[英]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 中的廣度優先搜索算法更適合您的用例; 它比名稱所暗示的更籠統。 您可以使用pushtoppop方法插入您自己的隊列,這些方法可以執行您想要的任何排序。

您可以使用setS而不是vecS來指定對該特定屬性進行排序的容器。 例如,如果您想對邊進行排序,您將使用adjacency_list<setS, ...>並為TreeVertexType使用比較運算符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM