【问题标题】:Negative edge weight check in boost's dijkstra_shortest_pathsboost的dijkstra_shortest_paths中的负边权重检查
【发布时间】:2011-10-06 01:09:31
【问题描述】:

我正在使用 boost 图形库来调用 dijkstra_shortest_paths。但是,我有一些特殊设置,因为 weight_map 实际上是一个函子。因此,每次 boost 库需要边的权重时,都会调用我的函子,进行复杂的计算并将结果返回给 boost。

不幸的是,在dijkstra_shortest_paths.hpp 结构dijkstra_bfs_visitor 的方法examine_edge 中有一个get 调用权重映射,只是为了检查返回值是否为负。我完全清楚我不能使用带负值的 Dijkstra 算法,并且我确信我的函子只返回正值。但是,此检查会导致我的仿函数为每条边调用两次。由于它执行复杂的计算,我想避免执行两次(调用之间的结果不会改变..在dijkstra_shortest_paths 运行期间,每个边缘都得到相同的等待)。

到目前为止,我正在手动检查传递给仿函数的边,如果出现重复调用,我将返回之前记住的结果。这显然是一种解决方法,而不是解决方案。

我试图传递我自己的访问者,它覆盖了examine_edge,但是,boost 的dijkstra_bfs_visitor 定义的原始方法仍然适用。

有谁知道是否有更好的方法来处理这种情况并以某种方式避免负边权重检查?

【问题讨论】:

  • 如果它很昂贵,无论如何缓存这个边缘权重计算似乎是个好主意。除此之外...也许您可以提供一个始终返回 false 的组合函子?
  • 我当然已经缓存了它。我只是不喜欢函数被无缘无故地调用两次。 combine 函子应该返回一个距离值,那么返回 false 是什么意思?
  • 您能否从struct DijkstraVisitorConcept 派生并重载您自己的void constraints() 函数,您可以在其中完全删除examine_edge() 检查。
  • @Aditya Kumar:听起来像是对我的回答——你应该把它贴在回答部分

标签: c++ boost dijkstra


【解决方案1】:

你是对的,即使向你自己的访客提供负面测试也会被执行。

  void examine_edge(Edge e, Graph& g) {
    if (m_compare(get(m_weight, e), m_zero))
        boost::throw_exception(negative_edge());
    m_vis.examine_edge(e, g);
  } 

但无论如何应该多次调用 weight_map(参见 boost doc):

 for each vertex v in Adj[u]
  if (w(u,v) + d[u] < d[v])
    d[v] := w(u,v) + d[u]

只需使用预先计算的权重图调用 djikstra,无论如何都必须计算每个边缘权重。

【讨论】:

  • 不幸的是,我的情况并非如此。首先:文档没有说它调用 w(u,v) 两次。这只是伪代码,boost 也可以重用结果。其次,我不能预先计算,因为我的访问者在到达目标顶点时会抛出异常,所以我不知道要预先计算什么(显然,不想全部计算)。
  • 嗯,它被记录的方式表明你不应该依赖它只被调用一次的事实。那么memoization是一个可能的选择。或者按照 Aditya Kumar 的建议从 DijkstraVisitorConcept 继承。
【解决方案2】:

我建议您使用惰性计算来确保每个昂贵的计算最多执行一次。实现这一点的最直接方法是给你的 Edge 类一个 getWeight() 惰性吸气剂,我不熟悉你正在使用的库,所以我不确定你如何将它与仿函数集成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    相关资源
    最近更新 更多