使用特定成本查找有向图中的所有路径

时间:2012-11-17 23:48:55

标签: graph graph-algorithm path-finding directed-graph weighted

假设我们有定向加权图。我们的任务是找到两个顶点(源和目标)之间的所有路径,其成本小于或等于=< N.我们只访问每个顶点一次。在以后的版本中,我想添加一个条件,源可以作为目的地(我们只是做一个循环)。

我认为可以用改进的Dijkstra算法来完成,但我不知道如何实现这样的事情。谢谢你的帮助。

3 个答案:

答案 0 :(得分:3)

您可以使用递归回溯来解决此问题。在以下情况下终止递归:

  • 你到达目的地
  • 您访问已访问过的节点
  • 您的路径长度超过N.

伪代码:

list curpath := {}
int dest, maxlen
def findPaths (curNode, dist):
    if curNode = dest:
        print curpath
        return
    if curNode is marked:
        return
    if dist > maxlen:
        return
    add curNode to curpath
    mark curNode
    for nextNode, edgeDist adjacent to curNode:
        findPaths(nextNode, dist + edgeDist)
    remove last element of curpath

答案 1 :(得分:1)

你想在有向图中找到全部从A点到B点的路径,例如从A到B的距离小于N,并允许A = B的可能性。

Dijkstra的算法是在图中找到从一个点到另一个点的最小路径,并且可以说是沿途丢弃了许多其他路径。因此,如果我们包含重叠的路径,则不能用于查找所有路径。

您可以通过在图表中进行广度优先搜索来实现您的目标,将覆盖树的每个分支保持在堆栈中(如果节点连接得很好,您将获得大量的分支),并停在深度为N.所有到达B的分支都被放在一边。一旦覆盖了深度N,就会丢弃所有未到达B的路径。其余的路径以及放在一起的路径将成为您的解决方案。

您可以选择在路径中添加没有循环的限制,在这种情况下,如果新到达的节点已经在目前所覆盖的路径中,您将检查搜索的每个步骤,并修剪该路径情况确实如此。

这是一些伪代码:

function find_paths(graph G, node A):
list<path> L, L';

L := empty list;
push path(A) in L;
for i = 2 to N begin
   L' := empty list;
   for each path P in L begin
       if last node of P = B then push P in L'
       else
       for each successor S of last node in P begin
           if S not in P then
              path P' := P;
              push S in P';
              push P' in L';
           endif
       end
       endif
   end
   L := L';
end

for each path P in L begin
  if last node of P != B
  then remove P from L
  endif
end
return L;

答案 2 :(得分:0)

我认为jma127建议的递归回溯算法的可能改进(取决于问题的大小和最大成本N)将预先计算每个节点距目的地的最小距离(最短路径树) ,然后将以下内容附加到测试条件以终止递归:

  • 您到达的目的地的最小距离大于最大费用N减去到达当前节点的距离。

如果需要针对不同的源和目的地多次运行算法,则可以运行例如Johnson的算法,以创建所有节点对之间的最短路径的矩阵。