C++ boost中的负边缘重量检查';s dijkstra_最短路径

C++ boost中的负边缘重量检查';s dijkstra_最短路径,c++,boost,dijkstra,C++,Boost,Dijkstra,我正在使用boost图形库调用dijkstra\u最短路径。然而,我有一个特殊的设置,weight\u map实际上是一个函子。因此,每次boost库需要边的权重时,我的函子就会被调用,进行复杂的计算并将结果返回给boost 不幸的是,在dijkstra\u shortest\u path.hpp中,structdijkstra\u bfs\u visitor的方法inspect\u edge对weightmap进行了get调用,只是为了检查返回值是否为负值。我完全知道我不能用Dijkstra算

我正在使用boost图形库调用
dijkstra\u最短路径
。然而,我有一个特殊的设置,
weight\u map
实际上是一个函子。因此,每次boost库需要边的权重时,我的函子就会被调用,进行复杂的计算并将结果返回给boost

不幸的是,在
dijkstra\u shortest\u path.hpp
中,struct
dijkstra\u bfs\u visitor
的方法
inspect\u edge
对weightmap进行了
get
调用,只是为了检查返回值是否为负值。我完全知道我不能用Dijkstra算法来处理负值,我确信我的函子只返回正值。但是,此检查会导致对每条边调用我的函子两次。由于它执行复杂的计算,我希望避免执行两次(调用之间的结果不会改变..在
dijkstra\u最短路径
运行期间,每个边缘都会得到相同的等待)

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

我试图传递我自己的访问者,该访问者覆盖了
examine\u edge
,但是,boost的
dijkstra\u bfs\u访问者定义的原始方法仍然适用


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

你是对的,即使向你自己的访客提供否定性测试也会执行

  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);
  } 
但无论如何,权重图应该被称为多次(见boost):

调整[u]中每个顶点v的

if(w(u,v)+d[u]

只要使用预先计算的权重映射调用djikstra,就必须计算每个边的权重。

我建议您使用延迟计算,以确保每次昂贵的计算最多执行一次。实现这一点最直接的方法是给你的
Edge
class a
getWeight()
lazy getter,我不熟悉你正在使用的库,所以我不确定你会如何将它与functor集成。

如果它很昂贵,缓存这个边权重计算似乎是个好主意。除此之外…也许你可以提供一个总是返回false的组合函子?当然,我已经缓存了它。我只是不喜欢这个函子被无缘无故地调用两次。combine functor应该返回一个距离值,那么返回false意味着什么呢?您可以从
结构DijkstraVisitorConcept
派生并重载自己的
void constraints()
函数,在该函数中可以删除
检查边()
全部检查。@Aditya Kumar:听起来像是我的答案——你应该在答案部分发布这一点。不幸的是,我的情况并非如此。第一:文件没有说,它调用w(u,v)两次。这只是伪代码,boost也可以重用结果。第二,我不能预计算,因为我的访问者在到达目标顶点时抛出一个异常,所以我不知道要预计算什么(显然,我不想全部计算)。它的记录方式表明,您不应该依赖于它只被调用一次的事实。那么,回忆录是一种可能的选择。或者继承自Aditya Kumar建议的DijkstraVisitorConcept。
 for each vertex v in Adj[u]
  if (w(u,v) + d[u] < d[v])
    d[v] := w(u,v) + d[u]