【问题标题】:Understanding a python breadth-first-search algorithm了解python广度优先搜索算法
【发布时间】:2020-03-06 17:32:24
【问题描述】:

我正在尝试理解这个广度优先搜索 python 实现,我理解我的评论中显示的大部分内容,但我在这里没有得到这一行:

for dx, dy in [(-1, 0), (0, +1), (+1, 0), (0, -1)]:
           a, b = current[0] + dx, current[1] + dy #Start searching in a random direction

           if maze.in_maze(a, b) and not maze.is_wall(a, b) and (a, b) not in parent: #Check to see if the coordinates that are searching is inside the wall is not a wall and not inside of parent
               parent[(a, b)] = current #?
               dist[(a, b)] = dist[current] + 1; #?
               queue.append((a, b)) #Add the coordinates to the end of the queue

整个代码可以在这里找到,如果有任何评论错误,请随时给我打电话。我还是 python 的新手,所以我不知道每一行的确切作用,但我有一个粗略的想法。

from collections import deque #A double-ended queue, or deque, supports adding and removing elements from either end. Import this from collections

nodes = 0 #Initialise nodes with value 0


def solve(maze, start, end): #Solve function that takes in the maze, start and end points as arguments
   global nodes #Declare nodes as a global variable
   nodes = 0 #Set nodes value to 0

   queue = deque() #Set queue as a double ended queue
   parent, dist = dict(), dict() #Set parent and dist

   queue.append(start) #Add start point to the queue
   parent[start], dist[start] = start, 1

   while len(queue): #While there are items in the list
       current = queue.popleft() #Set current to the first thing in the queue from the left
       nodes += 1 #Increment nodes by 1

       if current == end: #If the current place is the end target then solution has been found and we can exit the loop
           break #Exit the loop

       for dx, dy in [(-1, 0), (0, +1), (+1, 0), (0, -1)]:
           a, b = current[0] + dx, current[1] + dy #Start searching in a random direction

           if maze.in_maze(a, b) and not maze.is_wall(a, b) and (a, b) not in parent: #Check to see if the coordinates that are searching is inside the wall is not a wall and not inside of parent
               parent[(a, b)] = current #Set later
               dist[(a, b)] = dist[current] + 1; #set later
               queue.append((a, b)) #Add the coordinates to the end of the queue

   if end not in parent: #If there is no solution
      return [] #Return an empty solution
   else: #Otherwise if there is a solution
      path = [] #Initialise path as an empty list
      while start != end: #While the starting point is not the end point, the solution has not be found so
          path.append(end) #Keep appending the end node to the path queue until they meet the condition
          end = parent[end] #Set end point to the position it is in the parent dictionary
      path.append(start) #Insert the starting point to the end of the queue
      path.reverse() #Reverse the path queue since the solution was found back to front
      return path #Return the final solution

【问题讨论】:

    标签: python algorithm breadth-first-search


    【解决方案1】:

    所以,在上面的代码中,阅读后,我假设开始和结束由坐标表示,如(x, y)。 此外,如果您在“迷宫”中选择任何坐标,则只能沿上、下、左、右方向遍历,即如果您在坐标 (x, y) 上,则只能转到以下坐标之一: (x+1, y), (x-1, y), (x, y+1), (x, y-1)

    所以基本上,for 循环用于一一选择您可以遍历的相邻坐标。 然后a, b = current[0] + dx, current[1] + dy这条线用于获取相邻坐标的绝对坐标。 然后我们检查新坐标是否存在于迷宫中,或者它是否是一堵墙。 如果它在迷宫中而不是墙中,而且我们还没有穿过它,我们更新parent dict 并更新dist dict(用于距离)。

    parent 字典存储坐标的父级。所以对于(x+1, y),父级将是(x, y),这是当前的。 parent[(x+1, y)] = (x, y) 表示(x+1, y) 的父级是(x, y)

    dist 字典存储到达新坐标所需的步数或非步数。 dist[(x+1, y)] = dist[(x,y)] + 1 表示新坐标距离等于父坐标距离+1新步长。

    然后我们将它添加到队列中。

    【讨论】:

    • 会有这样的输出场景吗? if end not in parent: #如果没有解决方案 return [] #返回一个空的解决方案 .我认为广度优先搜索是一种总能找到解决方案的完整算法。
    • 是的,如果坐标在迷宫之外或者坐标代表一堵墙。然后if 循环将失败,坐标不会添加到parents dict 或队列中
    • 哦,我明白了,谢谢!在调用solve之前,我会确保添加验证以检查坐标是否代表墙壁或迷宫之外。
    • 验证已经存在于上述代码中:if maze.in_maze(a, b) and not maze.is_wall(a, b) and (a, b) not in parent: 意思是,“如果 (a,b) 存在于迷宫中并且 (a,b) 不是墙并且如果我们没有已经访问过的(a,b)"如果满足这些条件,则将其加入队列,以便我们可以遍历并更新字典
    【解决方案2】:
    parent[(a, b)] = current
    

    用于存储位置的坐标 (current), 您来到坐标(a, b)。哦,顺便说一句,这里的评论是错误的:

       for dx, dy in [(-1, 0), (0, +1), (+1, 0), (0, -1)]:
           a, b = current[0] + dx, current[1] + dy #Start searching in a random direction
    

    应该是“在每个方向搜索,一次一个”。这里没有随机的东西。

    【讨论】:

    • 谢谢,是的,当我实施深度优先搜索时,我忘记更改该行,感谢您指出这一点。 dist[(a, b)] = dist[current] + 1 是什么意思? #set 稍后再做呢?我不完全理解 dist 在算法中的用途。
    • dist 用于测量距起点的距离(沿路径)。如果您对路径的长度感兴趣,可能会很有用。显然算法不需要它来工作。
    • 我以为是最短路径,感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多