Algorithm 无法找出BFS中的错误
我已经写了两个版本的BFS,但是其中一个有一个bug,不能得到正确的结果。不过,我还是搞不清楚这个bug是什么 正确版本:Algorithm 无法找出BFS中的错误,algorithm,debugging,graph,breadth-first-search,Algorithm,Debugging,Graph,Breadth First Search,我已经写了两个版本的BFS,但是其中一个有一个bug,不能得到正确的结果。不过,我还是搞不清楚这个bug是什么 正确版本: def find_all_distances(self, start_node): distance = {} marked = {} marked[start_node] = True distance[start_node] = 0 queue = [start_node] while queue: nod
def find_all_distances(self, start_node):
distance = {}
marked = {}
marked[start_node] = True
distance[start_node] = 0
queue = [start_node]
while queue:
node = queue.pop(0)
for adj_node in self.adj[node]:
if adj_node not in marked:
marked[adj_node] = True
distance[adj_node] = distance[node] + 6
queue.append(adj_node)
错误版本:
def find_all_distances(self, start_node):
distance = {}
marked = {}
queue = [(start_node, 0)]
while queue:
node, dist = queue.pop(0)
marked[node] = True
distance[node] = dist
for adj_node in self.adj[node]:
if adj_node not in marked:
queue.append((adj_node, dist + 6))
对我来说,唯一明显的区别是当我们在添加到队列之前或从队列弹出之后标记一个已访问。为什么这会影响结果?因为错误版本会导致相似节点的访问两次或两次以上,示例: 假设您从以下位置开始: 迭代1: 队列Q=[A] 标记={} 迭代2: 节点弹出:A 队列Q=[B] 已标记={A:True} 迭代3: 节点弹出:B 队列Q=[C,D] 标记={A:True,B:True} 迭代4: 节点弹出:C 队列=[D,D] 标记={A:True,B:True,C:True}
看看迭代4中发生了什么,,节点D访问了两次。。。因为您在弹出后标记节点,因为错误版本会导致类似节点访问两次或两次以上,示例: 假设您从以下位置开始: 迭代1: 队列Q=[A] 标记={} 迭代2: 节点弹出:A 队列Q=[B] 已标记={A:True} 迭代3: 节点弹出:B 队列Q=[C,D] 标记={A:True,B:True} 迭代4: 节点弹出:C 队列=[D,D] 标记={A:True,B:True,C:True} 看看迭代4中发生了什么,,节点D访问了两次。。。因为在弹出作为旁注后要标记节点,
pop(0)
的复杂性为O(n)。不建议将Python列表用作队列。使用collections.deque
。作为旁注,pop(0)
具有O(n)复杂性。不建议将Python列表用作队列。改用collections.deque