得到一张如下图所示的图表:
我想从该图中的p(0,0)计算到特定点p(i,j)的所有可能方法。我想我可以用深度优先搜索来做到这一点。我应该如何扩展深度优先搜索,所以它不计算两次?
答案 0 :(得分:1)
最好的方法是在不实际跟踪所有路径的情况下计算路数。让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(any number > i, any j) and F(i, any number > 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)
这仍然不是最有效的实现方式,但我认为它可以解决问题。它比通过跟踪和回溯计算每条路径要快得多!
答案 1 :(得分:1)
您可以使用BFS并标记节点或使用地图来跟踪它们。但是,如果您的图表很大,BFS需要将其全部保存在内存中。 DFS更擅长。但是,除非您对其进行深度限制,否则DFS可能会丢失在大图中。
无论如何,为了加快您的计划,您可以考虑提前停止:
其他启发式:
我写了一个类似的程序,看看我能在多大程度上优化它: https://github.com/eamocanu/allPathsFinder