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

发布于 2024-11-29 02:37:44 字数 475 浏览 2 评论 0原文

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

struct TreeVertexType {
  double radius;
  double position[3]; 
}

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

我希望在树上执行 DFS 的形式定义,以便创建分支列表。附加要求是,每当一个顶点有多个未探索的相邻顶点时,它就会选择半径最大的顶点。该规则确保图的遍历顺序代表物理树分支。

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

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

谢谢

-约翰

I have a tree (in the graph sense) representation of a tree (in the physical sense). The tree is represented as a BGL adjacency list where each vertex contains radius and position properties, i.e., my graph is defined in the form

struct TreeVertexType {
  double radius;
  double position[3]; 
}

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

I would like to perform a DFS on the tree in order to create a list of branches. The additional requirement is that whenever a vertex has more than one unexplored adjacent vertices that it chooses the vertex with the greatest radius. This rule ensure that the traversal order of the graph is representative of physical tree branches.

It seems that the DFS visitor does not support a priority queue and so I was wondering whether there's an alternative search formulation of obtaining this information maybe via A*?

Alternatively I can implement my own DFS algorithm by sorting vertices, but would rather leverage the BGL framework if possible.

Thanks

-John

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

信愁 2024-12-06 02:37:44

在DFS期间,boost::graph使用堆栈来压入相邻的顶点,这些顶点稍后将按照压入的顺序弹出。

std::vectorstack; //deep_first_search.hpp 的第 94 行 boost_1_47_0

作为解决方法,您可以使用相同的 push() 和 pop() 接口重新定义stack以及什么您可以做的是,当任何 Vertex 被推入 stack 时,只需对 stack 的元素进行排序,方法是半径最大的顶点总是出现在 顶部。

换句话说,用您自己的优先级队列伪造堆栈接口。

这将减轻您编写自己的 DFS 的痛苦。

During the DFS boost::graph uses a stack to push the adjacent vertices which will be popped later in the order that they are pushed.

std::vector<VertexInfo> stack; //line 94 boost_1_47_0 of depth_first_search.hpp

as a workaround you can redefine this stack with the same push() and pop() interface and what you can do is when any Vertex is pushed into the stack just sort the elements of your stack in a way that the vertex with the greatest radius always comes on the top.

In other words fake a stack interface with your own priority queue.

This will relieve you of the pain of writing your own DFS.

千と千尋 2024-12-06 02:37:44

我最终遵循了 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按照半径,我简单地将边权重定义为源顶点和目标顶点的平均半径。

然而问题是,半径顶点属性是动态的,并且在创建图时是未知的,因此每当我更新边权重时,边顺序都不会改变。

有人知道替代方法吗?

谢谢

-约翰

I ended up following the logic provided at http://www.boost.org/doc/libs/1_34_0/libs/graph/example/ordered_out_edges.cpp, i.e.,

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;

To ensure that the out_edges were ordered according to the radius, I simply defined the edge weight as the average radius of the source and target vertices.

The issue however is that the radius vertex property is dynamic and unknown at the time the graph is created, hence the edge ordering is unchanged whenever I update the edge weights.

Is anyone aware of an alternative approach?

Thanks

-John

信仰 2024-12-06 02:37:44

BGL 中的广度优先搜索算法将更适合您的用例;它比名字所暗示的更通用。您可以使用 pushtoppop 方法插入自己的队列,执行您想要的任何排序。

The breadth-first search algorithm in BGL would fit your use case better; it is more general than the name implies. You can plug in your own queue with push, top, and pop methods that do whatever ordering you want.

安静被遗忘 2024-12-06 02:37:44

您可以使用 setS 而不是 vecS 来指定按特定属性排序的容器。例如,如果您想对边进行排序,则可以使用 adjacency_list 并为 TreeVertexType 使用比较运算符。

You can use setS instead of vecS to specify a container with ordering on that particular attribute. E.g., if you wanted to order edges, you would use adjacency_list<setS, ...> and have a comparison operator for TreeVertexType.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文