Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 无法找出BFS中的错误_Algorithm_Debugging_Graph_Breadth First Search - Fatal编程技术网

Algorithm 无法找出BFS中的错误

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

我已经写了两个版本的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:
        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