【问题标题】:BGL DFS Visitor with Priority Queue具有优先队列的 BGL DFS 访客
【发布时间】:2011-08-12 17:55:56
【问题描述】:

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

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

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

我想在树上执行 DFS 以创建分支列表。附加要求是,每当一个顶点有多个未探索的相邻顶点时,它都会选择具有最大半径的顶点。该规则保证了图的遍历顺序代表了物理树枝。

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

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

谢谢

-约翰

【问题讨论】:

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


    【解决方案1】:

    在 DFS 期间 boost::graph 使用堆栈来推送相邻的顶点,这些顶点将在稍后按它们被推送的顺序弹出。

    std::vector&lt;VertexInfo&gt; stack; //depth_first_search.hpp 的第 94 行 boost_1_47_0

    作为一种解决方法,您可以重新定义这个 stack 使用相同的 push() 和 pop() 接口,您可以做的是当任何 Vertex 被推入 stack 时对your stack 的元素进行排序,使半径最大的顶点始终位于顶部。

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

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

    【讨论】:

      【解决方案2】:

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

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

      有人知道另一种方法吗?

      谢谢

      -约翰

      【讨论】:

      • 请单独提出后续问题。谢谢!
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2023-04-02
          • 1970-01-01
          • 2013-08-08
          • 2011-01-18
          • 1970-01-01
          • 2011-05-26
          • 2011-03-19
          相关资源
          最近更新 更多