python - 使用迭代方法从 Python 中的起始节点到达图中的目标节点
问题描述
我有以下无向图,其中我试图通过所有可用路径5
从节点开始到达节点目标节点0
,而不仅仅是单个或最短的路径。
该图是这样的字典:
graph = { "0" : ["2", "1"],
"2" : ["0", "3", "4"],
"3" : ["2"],
"1" : ["0", "5"],
"4" : ["2", "5"],
"5" : ["1", "4"]
}
我的方法是从起始节点开始,然后遍历每个邻居,然后遍历他们的邻居,直到到达目的地。
但是,我面临的问题是,我无法将 for 循环中的主要迭代实时更改为新的迭代(不可能,强烈不推荐)。
例如,如果我开始在 和 的邻居中循环0
,我最初会循环,然后我会在和 之间循环,因为它们是 的邻居,但是,我不能在 for 循环中将其更改为iterative 仍将保留而不是成为。此外,需要以在遍历节点和节点及其邻居之后的方式保持引用,第一个迭代器中的第二个节点应该与它的邻居一起遍历,在这种情况下。2
1
[2, 1]
3
4
2
[2, 1]
[3, 4]
[2, 1]
3
4
[5]
1
[1]
解决方案
您可以使用包含要探索的下一个节点列表和到达它们的路径的堆栈结构来迭代地执行此操作。
例如:
def findPath(graph, origin,target):
stack = [(origin,[origin])] # Start from origin
seen = {origin} # Track where you've been so far
while stack:
node, path = stack.pop(0) # BFS (use pop(-1) for DFS)
for nextNode in graph[node]: # Go through neighbours
if nextNode in seen: continue # not seen yet
nextPath = path + [nextNode] # Record path to get there
if nextNode == target: return nextPath # Arrived!
seen.add(nextNode) # Avoid returning here
stack.append( (nextNode,nextPath) ) # Stack for more exploration
return [] # no path to target
输出:
graph = { "0" : ["2", "1"],
"2" : ["0", "3", "4"],
"3" : ["2"],
"1" : ["0", "5"],
"4" : ["2", "5"],
"5" : ["1", "4"]
}
print(findPath(graph,"0","5"))
['0', '1', '5']
print(findPath(graph,"3","5"))
['3', '2', '4', '5']
print(findPath(graph,"1","3"))
['1', '0', '2', '3']
BFS(广度优先搜索)将找到最短路径。DFS(深度优先搜索)会消耗更少的内存,但可能找不到最佳路径。
要获得所有可能的路径,您可以将此函数转换为生成器,但是您不能使用“seen”优化,因为它会使到达同一节点的多个部分路径短路。在这种情况下,您应该使用 DFS,因为无论如何您都将探索所有路径,并且 DFS 的内存效率会更高。
def findPaths(graph, origin,target):
stack = [(origin,[origin])] # Start from origin
while stack:
node, path = stack.pop(-1) # DFS (use pop(0) for BFS)
for nextNode in graph[node]: # Go through neighbours
if nextNode in path: continue # don't loop inside paths
nextPath = path + [nextNode] # Record path to get there
if nextNode == target:
yield nextPath # Return this path,
continue # continue with others
stack.append( (nextNode,nextPath) ) # Stack for more exploration
输出:
graph = { "0" : ["2", "1"],
"2" : ["0", "3", "4"],
"3" : ["2"],
"1" : ["0", "5"],
"4" : ["2", "5"],
"5" : ["1", "4"]
}
for path in findPaths(graph,"0","5"): print(path)
['0', '1', '5']
['0', '2', '4', '5']
for path in findPaths(graph,"3","5"): print(path)
['3', '2', '4', '5']
['3', '2', '0', '1', '5']
for path in findPaths(graph,"1","3"): print(path)
['1', '0', '2', '3']
['1', '5', '4', '2', '3']
推荐阅读
- python - 解析数据的 HTML 存储格式
- python - 未触发扩展上下文菜单中的 Qaction 快捷方式
- javascript - 基于表单字段验证添加类
- reactjs - React Hooks (Functional) Lifecycle: 在 useEffect() 代码之前渲染的组件
- amazon-web-services - 是否可以知道 S3 存储桶中的平均请求量?
- rust - 如何在极地加载数据框时定义列类型?
- r - 尝试使用线性模型函数 lm() 时出错
- django - 如何处理组之间的数据流?(姜戈)
- python - Python 在另一个 Python .py 文件中定义一个类方法
- html - 使用 Leaflet Search 插件搜索 Shapefile