简体   繁体   English

对于通过实加权无向图的单对最短路径,最简单的算法/解决方案是什么?

[英]What's the simplest algorithm/solution for a single pair shortest path through a real-weighted undirected graph?

I need to find a shortest path through an undirected graph whose nodes are real (positive and negative) weighted. 我需要通过无向图找到最短路径,其节点是实数(正和负)加权。 These weights are like resources which you can gain or loose by entering the node. 这些权重就像您可以通过输入节点获得或松散的资源。

The total cost (resource sum) of the path isn't very important, but it must be more than 0, and length has to be the shortest possible. 路径的总成本(资源总和)不是很重要,但必须大于0,并且长度必须尽可能短。

For example consider a graph like so: 例如,考虑如下图:

A-start node; D-end node

A(+10)--B( 0 )--C(-5 )
     \     |    /
       \   |  /
D(-5 )--E(-5 )--F(+10)

The shortest path would be AEFED 最短的路径是AEFED

Dijkstra's algorithm alone doesn't do the trick, because it can't handle negative values. Dijkstra的算法本身并不起作用,因为它无法处理负值。 So, I thought about a few solutions: 所以,我想了几个解决方案:

First one uses Dijkstra's algorithm to calculate the length of a shortest path from each node to the exit node, not considering the weights. 首先使用Dijkstra算法计算从每个节点到出口节点的最短路径的长度,而不考虑权重。 This can be used like some sort of heuristics value like in A*. 这可以像A *中的某种启发式值一样使用。 I'm not sure if this solution could work, and also it's very costly. 我不确定这个解决方案是否可行,而且成本也很高。 I also thought about implement Floyd–Warshall's algorithm, but I'm not sure how. 我也想过实现Floyd-Warshall的算法,但我不确定如何。

Another solution was to calculate the shortest path with Dijkstra's algorithm not considering the weights, and if after calculating the path's resource sum it's less than zero, go through each node to find a neighbouring node which could quickly increase the resource sum, and add it to the path(several times if needed). 另一个解决方案是使用Dijkstra算法计算最短路径而不考虑权重,如果在计算路径的资源总和后它小于零,则通过每个节点找到可以快速增加资源总和的相邻节点,并将其添加到路径(如果需要,可以多次)。 This solution won't work if there is a node that could be enough to increase the resource sum, but farther away from the calculated shortest path. 如果有一个节点足以增加资源总和,但距计算的最短路径更远,则此解决方案将不起作用。

For example: 例如:

A- start node; E- end node
A(+10)--B(-5 )--C(+40)
      \
        D(-5 )--E(-5 )

Could You help me solve this problem? 你能帮我解决这个问题吗?

EDIT: If when calculating the shortest path, you reach a point where the sum of the resources is equal to zero, that path is not valid, since you can't go on if there's no more petrol. 编辑:如果在计算最短路径时,您到达资源总和等于零的点,该路径无效,因为如果没有更多的汽油则无法继续。

Edit: I didn't read the question well enough; 编辑:我没有读好这个问题; the problem is more advanced than a regular single-source shortest path problem. 问题比常规的单源最短路径问题更先进。 I'm leaving this post up for now just to give you another algorithm that you might find useful. 我现在要离开这篇文章,只是为了给你另一个你可能觉得有用的算法。

The Bellman-Ford algorithm solves the single-source shortest-path problem, even in the presence of edges with negative weight. 即使在存在具有负权重的边缘的情况下, Bellman-Ford算法也解决了单源最短路径问题。 However, it does not handle negative cycles (a circular path in the graph whose weight sum is negative). 但是,它不处理负循环 (图中的圆形路径,其权重和为负)。 If your graph contains negative cycles, you are probably in trouble, because I believe that that makes the problem NP-complete (because it corresponds to the longest simple path problem ). 如果你的图形包含负周期,那么你可能遇到了麻烦,因为我相信这会使问题NP完全(因为它对应于最长的简单路径问题 )。

This doesn't seem like an elegant solution, but given the ability to create cyclic paths I don't see a way around it. 这似乎不是一个优雅的解决方案,但考虑到创建循环路径的能力,我没有看到它的方法。 But I would just solve it iteratively. 但我会迭代地解决它。 Using the second example - Start with a point at A, give it A's value. 使用第二个示例 - 从A处的点开始,给它A的值。 Move one 'turn' - now I have two points, one at B with a value of 5, and one at D also with a value of 5. Move again - now I have 4 points to track. 移动一个'转弯' - 现在我有两个点,一个在B,值为5,另一个在D也值为5.再次移动 - 现在我有4个要跟踪的点。 C: 45, A: 15, A: 15, and E: 0. It might be that the one at E can oscillate and become valid so we can't toss it out yet. C:45,A:15,A:15,E:0。可能E上的那个可以振荡并变得有效,所以我们不能把它扔掉。 Move and accumulate, etc. The first time you reach the end node with a positive value you are done (though there may be additional equivalent paths that come in on the same turn) 移动和累积等。第一次到达具有正值的结束节点时,您已完成(尽管在同一回合可能有其他等效路径)

Obviously problematic in that the number of points to track will rise pretty quickly, and I assume your actual graph is much more complex than the example. 显然有问题的是跟踪点的数量会很快上升,我认为你的实际图形比例子复杂得多。

I would do it similarly to what Mikeb suggested: do a breadth-first search over the graph of possible states, ie (position, fuel-left)-pairs. 我会像Mikeb建议的那样做:在可能状态的图表上进行广度优先搜索,即(位置,燃料左) - 对。

Using your example graph: 使用示例图表:

由示例图生成的状态图

  • Octagons: Ran out of fuel 八角形:燃料耗尽
  • Boxes: Child nodes omitted for space reasons 框:由于空间原因省略了子节点

Searching this graph breadth-first is guaranteed to give you the shortest route that actually reaches the goal if such a route exists . 搜索此图表, 如果存在此类路径,则保证广度优先为您提供实际到达目标的最短路径。 If it does not, you will have to give up after a while (after x nodes searched, or maybe when you reach a node with a score greater than the absolute value of all negative scores combined), as the graph can contain infinite loops. 如果没有,您将不得不放弃一段时间(搜索x个节点之后,或者当您到达的分数大于所有负分数的绝对值的节点时),因为图形可以包含无限循环。

You have to make sure not to abort immediately on finding the goal if you want to find the cheapest path (fuel wise) too, because you might find more than one path of the same length, but with different costs. 如果你想找到最便宜的路径(燃料方式),你必须确保在找到目标时不立即中止,因为你可能会发现多条相同长度的路径,但费用不同。

Try adding the absolute value of the minimun weight (in this case 5) to all weights. 尝试将最小权重的绝对值(在本例中为5)添加到所有权重。 That will avoid negative ciclic paths 这将避免负面的ciclic路径

Current shortest path algorithms requires calculate shortest path to every node because it goes combinating solutions on some nodes that will help adjusting shortest path in other nodes. 当前的最短路径算法需要计算到每个节点的最短路径,因为它在一些节点上组合解决方案,这将有助于调整其他节点中的最短路径。 No way to make it only for one node. 无法仅为一个节点制作它。

Good luck 祝好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM