具有优先级队列的BGL DFS访问者

时间:2011-08-12 17:55:56

标签: c++ boost graph depth-first-search boost-graph

我有一棵树(在图形意义上)表示树(在物理意义上)。树被表示为BGL邻接列表,其中每个顶点包含半径和位置属性,即,我的图形以

的形式定义
struct TreeVertexType {
  double radius;
  double position[3]; 
}

typedef adjacency_list<vecS, vecS, undirectedS, TreeVertexType> Tree;

我想在树上执行DFS以创建分支列表。附加要求是,只要顶点具有多个未探测的相邻顶点,它就会选择具有最大半径的顶点。此规则确保图的遍历顺序代表物理树分支。

似乎DFS访问者不支持优先级队列,所以我想知道是否有另一种搜索方式可以通过A *获取此信息?

或者,我可以通过排序顶点来实现我自己的DFS算法,但如果可能的话,我宁愿利用BGL框架。

由于

-John

4 个答案:

答案 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中的广度优先搜索算法更适合您的用例;它比名称暗示的更为通用。您可以使用pushtoppop方法插入自己的队列,这些方法可以执行您想要的任何顺序。

答案 3 :(得分:0)

您可以使用setS代替vecS来指定对该特定属性进行排序的容器。例如,如果您想订购边缘,则可以使用adjacency_list<setS, ...>并为TreeVertexType设置比较运算符。