Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph 递归遍历一个图,计算到一个点的路径_Graph_Traversal_Depth First Search - Fatal编程技术网

Graph 递归遍历一个图,计算到一个点的路径

Graph 递归遍历一个图,计算到一个点的路径,graph,traversal,depth-first-search,Graph,Traversal,Depth First Search,有一张图,看起来像这样: 我想计算从图中的p(0,0)到特定点p(I,j)的所有可能的方法。我想我可以用深度优先搜索来完成。我应该如何扩展深度优先搜索,这样它就不会对某些方法进行两次计数了?最好的方法是在不实际遵循所有路径的情况下计算方法的数量。让F(x,y)成为到达目的地的方法数。然后,您可以在图形中看到,F(x,y)=F(x+1,y)+F(x,y+1)+F(x+1,y+1)。您需要F(0,0)。您的基本情况将是F(i,j)=1(如果您已经到达目的地,那么只有一种方法:不要去任何地方)和F(任

有一张图,看起来像这样:


我想计算从图中的p(0,0)到特定点p(I,j)的所有可能的方法。我想我可以用深度优先搜索来完成。我应该如何扩展深度优先搜索,这样它就不会对某些方法进行两次计数了?

最好的方法是在不实际遵循所有路径的情况下计算方法的数量。让
F(x,y)
成为到达目的地的方法数。然后,您可以在图形中看到,
F(x,y)=F(x+1,y)+F(x,y+1)+F(x+1,y+1)
。您需要
F(0,0)
。您的基本情况将是
F(i,j)=1
(如果您已经到达目的地,那么只有一种方法:不要去任何地方)和
F(任意数字>i,任意j)以及F(i,任意数字>j)=0
,因为一旦您通过了目的地,就无法到达目的地

更新更详细的信息:现在如何评估此公式?您可以递归地执行,但是一个简单的实现将非常低效。在伪代码中,一个朴素的实现就是这样的,它看起来很像python:

i = ...
j = ...
def paths (x, y):
    if (x > i) or (y > j):
        return 0         
    if (x == i) and (y == j):
        return 1
    else:
        return paths (x+1, y) + paths (x, y+1) + paths (x+1, y+1)
print F(0, 0)
问题是,如果从(0,0)开始,第一级递归调用将是(0,1)、(1,0)和(1,1)。当这些调用依次求值时,(0,1)将计算(0,2)(1,1)和(1,2);然后(1,0)将计算(1,1)、(2,0)和(2,1),然后(1,1)将计算(1,2)、(2,1)和(2,2)。注意这些调用中有多少是冗余的,因为它们计算的值相同。解决这个问题的方法是保留一个矩阵,该矩阵存储
F
的值。因此,代码可能如下所示:

i = ...
j = ...
memorizedValues = ... #make an i by j grid filled with -1
memorizedValues[i][j] = 1 #initial condition

def paths (x, y):
    if (x > i) or (y > j):
        return 0
    if (memorizedValues[x][y] != -1): #check for a memorized value before
        return memorizedValues[x][y] # starting more recursion!
    else:
        memorizedValues[x][y] = paths (x+1, y) + paths (x, y+1) + paths (x+1, y+1)
        return memorizedValues[x][y]

print F(0, 0)

这仍然不是最有效的实现,但我认为它能说明问题。这比通过跟踪和回溯来计算每条路径要快得多

您可以使用BFS标记节点或使用地图跟踪节点。然而,如果图形很大,BFS需要将其全部保存在内存中。DFS在这方面做得更好。但是,DFS可能会在大型图形中丢失,除非对其设置深度限制

无论如何,为了加速你的程序,你可以考虑提前停止:
  • 图形已断开连接
  • 你到了一座桥
其他启发法:

  • 在继续之前,先拜访1级的邻居
我写了一个类似的程序,看看我能优化到什么程度:

谢谢。我考虑过这个解决方案,但需要遵循所有方法,因为我必须从边缘读取指向特定点的其他信息。因此,如果我只读取一次文件,而不必存储我不需要的信息,那就更好了。嗯……那么我解释算法的更新可能没有实际用处。我真的不明白你想解决什么问题。为什么深度优先搜索会为您生成重复的路径?