【发布时间】:2015-10-15 19:24:06
【问题描述】:
不久前,我问了一个问题 (depth first search algorithm in python),@6502 给出了精彩的回答。这让我可以更准确地思考这个问题,并引出这个后续问题。
在上一个问题中,您有一个来自如下函数的隐含定向树:
def neighbors1(node):
"Returns neighboring nodes in directed tree"
#some code
yield node_1
#some more code
yield node_2
#...
yield node_n
和这样的成功标准函数:
def goal(node):
"Returns true if node is the end goal and false otherwise"
if node #meets some goal#:
return True
else:
return False
第一个函数意味着某种图,根据细节的不同,它可能是一棵树或一个有环的图,它可能是有向的或无向的。但是假设上面暗示了一个有向树(如图所示)。
这意味着对于任何节点,您都可以找到子节点,并递归地继续向下搜索这棵树。现在如果你想从节点 A 到节点 H(比方说),你可以使用上一个问题中的代码,将 neighbors1 函数传递给 search 函数(转载如下):
def search(start_state, neighbors, goal):
path = [start_state]
class PathFound(RuntimeError):
pass
def rsearch(x):
if goal(x):
raise PathFound
for y in neighbors(x):
path.append(y)
rsearch(y)
path.pop()
try:
rsearch(start_state)
except PathFound:
return path
return None # No path exists
所以你只需调用它
search(A,neighbors1,goal)
现在(经过冗长的介绍),问题是,如果邻域函数隐含不同的图怎么办?
我认为如果邻居函数意味着这样的无向树:
那么上面的方法可能行不通,因为你最终可能会出现一个无限循环,在这些循环之间来回跳转,例如B 和 F。但是,我认为这可以通过添加一个简单的检查来解决,看看你是否加倍返回:
def search(start_state, neighbors, goal):
path = [start_state]
class PathFound(RuntimeError):
pass
def rsearch(x):
if goal(x):
raise PathFound
for y in neighbors(x):
if y in path: continue #New line for undirected graphs
path.append(y)
rsearch(y)
path.pop()
try:
rsearch(start_state)
except PathFound:
return path
return None # No path exists
关于上述欢迎的效率/效果的想法或cmets。
但是,问题的关键在于,如果您有一个由邻居函数隐含的通用图(如下所示),该怎么办:
是否有类似的搜索功能可以让您探索通过它的最短路径(再次仅使用邻居功能,而不是整个图的先验知识)。一种选择是实现 dijkstra 的算法,但我认为(尽管有利于找到最佳解决方案),这对于为非常大的图找到好的解决方案可能效率低下。有没有像这样的图的深度优先搜索?或者dijkstra可以以类似的方式实现吗?或者你会考虑什么方法?
我希望这个问题有意义,并且对更多人有用,而不仅仅是我!
【问题讨论】:
-
您已经发现了基本深度优先搜索算法的一个缺点——它会陷入循环。避免这种情况的一种方法是维护您已经访问过的节点列表,并将它们排除在任何进一步的探索之外。如果你不喜欢这个想法,你可以尝试广度优先搜索,或者不同的图遍历算法
标签: python algorithm dijkstra depth-first-search