- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试创建一个回溯函数,它将返回从根到 GOAL
我的路径持有人:
path_holder = {
'node1':['node2','node3','node5'],
'node2':['node1','node8','node10'],
'node3':['node4','node6']},
'node4':['node2','node1','node3'],
'node5':['DEADEND'],
'node6':['GOAL']
....
}
在我的 path_holder
输入中,它是 BFS 的输出,因此第一个节点是根节点,最后一个节点是目标节点。因为 path_holder
输入是 BFS 的输出,它会在找到 GOAL
时停止,因此所有作为先前节点分支的节点都需要搜索 GOAL
也被添加到 path_holder
中。
目前我陷入了发生无限循环的 while 循环。我的一般策略是从 GOAL
节点开始,使用该节点的键查找该键在另一个键(节点)列表中的位置。一旦找到该节点(它的列表中包含 key ),我就将该节点的 key 设置为新目标。 (混淆句抱歉)
这张图可能包含循环,这可能就是我得到无限循环的原因。
我的回溯函数:
def backtrace(path_holder, root, goal):
dct = {}
for d in path_holder:
dct.update(d)
rootnode = root.keys()[0]
goal = goal.keys()[0]
#x = len(path_holder)
path = []
path.append(goal)
#for i in reversed(xrange(x):
# path_holder[i].keys()
while goal != rootnode:
# find key that contains goal in list
for i in dct:
#print i
for j in dct[i] :
if j not in path:
if j == goal:
path.append(i)
goal = i
# append key that has goal in the list
# set goal to be the key that was appended
# repeat
return path
例如:输出
path = ['node1','node3','node6']
最佳答案
当我运行您的代码时出现以下错误:
>>> backtrace(path_holder, 'node1', 'GOAL')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "q20349609.py", line 13, in backtrace
dct.update(d)
ValueError: dictionary update sequence element #0 has length 1; 2 is required
那是因为当你像这样遍历字典时:
for d in path_holder:
您得到的是字典的键。所以 d
取值 'node1'
、'node2'
等等,你不能将这些传递给 dict。更新
方法。
但是你到底想在这里做什么?如果你试图将 path_holder
复制到 dct
中,你可以这样写:
dct = dict(path_holder)
但为什么要复制呢?为什么不直接使用 path_holder
?
修复错误 #1 后,程序运行但陷入无限循环。那是因为这些行:
if j not in path:
if j == goal:
path.append(i)
这些行意味着你只添加一个节点到路径,如果它有一个邻居 j
还没有在路径中,但等于目标。但是请稍等,此时 goal
已经在路径中。所以这两个条件不能同时满足。因此,没有任何东西被添加到路径中!
清楚的是:
if j not in path:
应该是:
if i not in path:
因为 i
是我们考虑添加到路径中的节点。
修复错误 #1 和 #2 后,程序取得了一些进展,但仍然陷入无限循环。如果我们在 path.append(i)
之后添加 print(path)
行,那么我们会得到以下输出,直到它卡住为止:
>>> backtrace(path_holder, 'node1', 'GOAL')
['GOAL', 'node6']
['GOAL', 'node6', 'node3']
['GOAL', 'node6', 'node3', 'node4']
可以看到搜索出错了:从node3
到了node4
,但是没有从node4
的路由到 GOAL
除了通过 node3
的那个。并且搜索永远不会考虑将 node3
添加到路径中,因为它已经存在。
当你找到一个像node4
这样的节点的路径时,你无法知道该节点是否在从GOAL
到的最短路径上节点 1
。此时你所能知道的是如果 node4
位于从GOAL
到node1
的最短路径上,< em>然后您将通过 node3
到达那里。这就是您必须记录的全部内容。
我是这样实现的,使用字典 visited
为每个节点记录从 start
到该节点的最短路径上的前一个节点,以及 collections.deque
维护一个节点队列,我们可能还没有访问过其邻居。
from collections import deque
class NotFound(Exception): pass
def search(graph, start, goal):
"""Find the shortest path from start to goal in graph (which must be a
map from a node to an iterable of adjacent nodes), using
breadth-first search.
>>> graph = {
... 1: [2, 4, 5],
... 2: [1],
... 3: [4, 6],
... 4: [2, 1, 3],
... 5: [],
... 6: [7],
... 7: [],
... }
>>> search(graph, 1, 7)
[1, 4, 3, 6, 7]
>>> search(graph, 1, 1)
[1]
>>> search(graph, 5, 1) # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
NotFound: No path from 5 to 1
"""
visited = {start: None}
queue = deque([start])
while queue:
node = queue.popleft()
if node == goal:
path = []
while node is not None:
path.append(node)
node = visited[node]
return path[::-1]
for neighbour in graph[node]:
if neighbour not in visited:
visited[neighbour] = node
queue.append(neighbour)
raise NotFound('No path from {} to {}'.format(start, goal))
注意事项:
您的变量 path_holder
包含一个称为 graph in adjacency list representation 的数据结构。所以我将此变量称为 graph
。
我已经编写了一个文档字符串来解释该函数的作用以及如何调用它。文档字符串还包含可以使用 doctest
模块运行的嵌入式代码示例。
您的函数从目标向后搜索到起点。但这与从开始到目标的所有边都反转的向前搜索是一样的。所以我通过向前搜索让事情变得简单。
关于python - BFS 输出图的最短路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20349609/
我有一个无向图,我从中重新绘制了相同的图,但采用树状结构(具有层次)。我知道广度优先搜索 (BFS) 算法的工作原理,但我不确定如何从图 --> 树进行转换。 在这里,在 this Wikipedia
只要我没记错,UCS 和 BFS 是一样的,唯一的区别是它不是扩展最浅的节点,而是扩展路径成本最低的节点。 (也为此使用 PriorityQueue 而不是 Queue)所以我复制了我的 BFS 代码
我知道 Dijkstra 的算法、Floyd-Warshall 算法和 Bellman-Ford 算法,用于查找图中 2 个顶点之间的最便宜路径。 但是当所有边的成本都相同时,最便宜的路径是边数最少的
我正在寻找一个代码来找到有向图中的最短路径 a 。 有什么地方可以找到吗? (可以基于BFS) 最佳答案 使用Erlang Digraph Library和函数 get_short_path/3,它采
这个问题已经有答案了: What is the point of the diamond operator (<>) in Java? (7 个回答) 已关闭 6 年前。 我是java初学者,我有BF
我想修改下面的代码以动态从文件中获取数据并运行 BFS。我尝试过循环,但我坚持如何使用匿名对象动态连接节点。 Node nA=new Node("101"); Node nB=new
我正在尝试实现 BFS 来查找学习某门类(class)之前所需的所有先决条件。我的public List computeAllPrereqs(String courseName)方法是我的代码困惑的地
我正在尝试编写一个程序来查找节点 B 是否属于从节点 A 开始的子树。我用 C 编写了代码,并自行实现了队列机制,因为我使用 BFS 来遍历树。问题是我的代码遇到无限循环,说我的队列已满,甚至没有。
我已经制作了 BFS 算法的并行版本,现在我正在尝试序列化相同的算法以了解加速情况。我的代码是这样的: #include #include #include struct Node {
我尝试根据我的研究在 JAVA 中实现 BFS 算法,但我有点困惑,我不确定我是在检查节点是否是目标,还是在将节点添加到探索列表中适当的地方。代码如下: frontier.add(nodes.getF
请帮助我理解我的代码做错了什么。我试图使用 BFS 获得最短路径来解决问题,但它要么给我 -1 要么 2。它应该给我 6 作为答案。我究竟做错了什么?这就是问题所在: 给定一个棋盘,找到马从给定来源到
我最近在解决一个 bfs 问题,其中每个节点都是数组元素的不同排列。但是我无法想出一个合适的数据结构来跟踪扩展树中的访问节点。通常,节点是不同的字符串,因此我们可以只使用映射将节点标记为已访问,但在上
我有一个文件夹结构中的元素列表: /文件夹/myfile.pdf /folder/subfolder1/myfile.pdf /文件夹/子文件夹2/myfile.pdf /folder/subfold
我已经实现了一个 BFS 算法来检测图中的循环,这是以下代码: void hasCycle(node *root,string start){ if(
真的很难弄清楚如何修复我的代码。我知道显然存在错误,因为它没有运行,但我不确定错误到底是什么,也不确定如何修复它们。任何帮助/见解将不胜感激。谢谢!! struct vertices { in
我在图中有代表城镇的顶点。我试图找到从 A 点到 B 点的最短路径。 我创建了一个图形类。 struct Edge{ string name; vector v; Edge(
所以我正在构建这棵树,它有 1..* 个节点,其中每个节点都有一个列表,该列表本身可以有 1..* 个节点。 树的前三层我可以构建得很好,但如果我不编写所有愚蠢的级别,它就不会发挥更多作用。解决方案当
我正在研究 Perfect Squares - LeetCode Perfect Squares Given a positive integer n, find the least number o
我是图论新手,目前只学过图论中的BFS和Disjoint sets。如果在给定的无向连通图中存在一个循环,我可以使用 BFS 找到它吗?我的意图是打印循环中的所有顶点。提前致谢。 最佳答案 是的,如果
我在矩阵上实现 bfs 时遇到问题。似乎我的代码只检查起始节点的子节点。 我的目标是找到从“B”到“H”的最短路径。我还认为我的代码需要大量修改。先感谢您! #include #include #
我是一名优秀的程序员,十分优秀!