广度优先搜索比预期结果差一个索引
Breadth First Search falling one index short of desired outcome
我正在尝试在 Python 中实现面包优先搜索算法,以找到从矩阵(二维列表)左上角到数字 9 的最短路径,无论它可能落在哪个位置矩阵。出于某种原因,当我 运行 下面的代码和包含的打印语句时,我的 x 坐标将正确输出(达到索引 5 而不是期望的 5)。然而,我的 y 坐标仍然是一个索引短(例如需要 7,它停在 6)。此外,当我打印队列时,它不是空的,但由于某种原因该功能仍然结束。所以,我不明白为什么如果两个条件都不满足(即队列为空或我们想要的坐标已找到),代码会退出。
import numpy as np
from collections import deque
def shortest_path(maze):
num_rows = len(maze)
num_cols = len(maze[0])
row_moves = [1, -1, 0, 0]
col_moves = [0, 0, 1, -1]
# Convert maze to an array and use numpy to find coordinates of our goal, which is the 9.
maze_to_matrix = np.array(maze)
destination = np.where(maze_to_matrix == 9)
destination_x, destination_y = destination[1][0], destination[0][0]
def is_valid_move(matrix, visited, y, x):
return (y >= 0) and (y < num_rows) and (x >= 0) and (x < num_cols) \
and matrix[y][x] == 1 and not visited[y][x]
def bfs(matrix, dest_y, dest_x):
# Construct matrix to keep track of visited cells.
visited = [[False for x in range(num_cols)] for y in range(num_rows)]
# Mark our origin as visited.
# Our origin is always the top left node.
visited[0][0] = True
# Create an empty queue to keep track of our nodes to visit.
queue = deque()
# Append our starting coordinates and its minimum distance from the source to our queue.
# First number is y coordinate, or outer list index.
# Second number is x coordinate, or inner list index.
queue.append((0, 0, 0))
# Store the length of the longest path from source to destination
min_dist = float('inf')
# Pull most recently visited node off queue and determine if neighbouring
# nodes are accessible. Continue until no valid unvisited nodes remain.
while queue:
(y, x, dist) = queue.popleft()
print(f'y: {y} and dest_y: {dest_y}')
print(f'x: {x} and dest_x: {dest_x}')
# If our destination is found then break the loop and return value.
if y == dest_y and x == dest_x:
min_dist = dist
break
# Check for all possible movement directions from current (x, y)
# and add valid movements to our queue.
for i in range(4):
if is_valid_move(matrix, visited, y + row_moves[i], x + col_moves[i]):
visited[y + row_moves[i]][x + col_moves[i]] = True
queue.append((y + row_moves[i], x + col_moves[i], dist + 1))
print(queue)
if min_dist != float('inf'):
return min_dist
else:
return "Desired destination can't be reached from given origin points."
return bfs(maze, destination_y, destination_x)
maze = [
[1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0],
[1, 1, 0, 1, 1, 1, 0],
[1, 0, 0, 0, 0, 1, 0],
[1, 1, 1, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 1, 9, 0]
]
print(shortest_path(maze))
# Outputting y: 6 and dest_y: 7 x: 5 and dest_x: 5 and the queue is full.
没关系,我是个白痴...在我的 is_valid_move 函数中,我只计算矩阵中值为 1 的空格,这意味着我们的目标 9 永远不会有效。
所以 is_valid_function 应该是这样的:
return (y >= 0) and (y < num_rows) and (x >= 0) and (x < num_cols) \
and (matrix[y][x] == 1 or matrix[y][x] == 9) and not visited[y][x]
我正在尝试在 Python 中实现面包优先搜索算法,以找到从矩阵(二维列表)左上角到数字 9 的最短路径,无论它可能落在哪个位置矩阵。出于某种原因,当我 运行 下面的代码和包含的打印语句时,我的 x 坐标将正确输出(达到索引 5 而不是期望的 5)。然而,我的 y 坐标仍然是一个索引短(例如需要 7,它停在 6)。此外,当我打印队列时,它不是空的,但由于某种原因该功能仍然结束。所以,我不明白为什么如果两个条件都不满足(即队列为空或我们想要的坐标已找到),代码会退出。
import numpy as np
from collections import deque
def shortest_path(maze):
num_rows = len(maze)
num_cols = len(maze[0])
row_moves = [1, -1, 0, 0]
col_moves = [0, 0, 1, -1]
# Convert maze to an array and use numpy to find coordinates of our goal, which is the 9.
maze_to_matrix = np.array(maze)
destination = np.where(maze_to_matrix == 9)
destination_x, destination_y = destination[1][0], destination[0][0]
def is_valid_move(matrix, visited, y, x):
return (y >= 0) and (y < num_rows) and (x >= 0) and (x < num_cols) \
and matrix[y][x] == 1 and not visited[y][x]
def bfs(matrix, dest_y, dest_x):
# Construct matrix to keep track of visited cells.
visited = [[False for x in range(num_cols)] for y in range(num_rows)]
# Mark our origin as visited.
# Our origin is always the top left node.
visited[0][0] = True
# Create an empty queue to keep track of our nodes to visit.
queue = deque()
# Append our starting coordinates and its minimum distance from the source to our queue.
# First number is y coordinate, or outer list index.
# Second number is x coordinate, or inner list index.
queue.append((0, 0, 0))
# Store the length of the longest path from source to destination
min_dist = float('inf')
# Pull most recently visited node off queue and determine if neighbouring
# nodes are accessible. Continue until no valid unvisited nodes remain.
while queue:
(y, x, dist) = queue.popleft()
print(f'y: {y} and dest_y: {dest_y}')
print(f'x: {x} and dest_x: {dest_x}')
# If our destination is found then break the loop and return value.
if y == dest_y and x == dest_x:
min_dist = dist
break
# Check for all possible movement directions from current (x, y)
# and add valid movements to our queue.
for i in range(4):
if is_valid_move(matrix, visited, y + row_moves[i], x + col_moves[i]):
visited[y + row_moves[i]][x + col_moves[i]] = True
queue.append((y + row_moves[i], x + col_moves[i], dist + 1))
print(queue)
if min_dist != float('inf'):
return min_dist
else:
return "Desired destination can't be reached from given origin points."
return bfs(maze, destination_y, destination_x)
maze = [
[1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0],
[1, 1, 0, 1, 1, 1, 0],
[1, 0, 0, 0, 0, 1, 0],
[1, 1, 1, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 1, 9, 0]
]
print(shortest_path(maze))
# Outputting y: 6 and dest_y: 7 x: 5 and dest_x: 5 and the queue is full.
没关系,我是个白痴...在我的 is_valid_move 函数中,我只计算矩阵中值为 1 的空格,这意味着我们的目标 9 永远不会有效。
所以 is_valid_function 应该是这样的:
return (y >= 0) and (y < num_rows) and (x >= 0) and (x < num_cols) \
and (matrix[y][x] == 1 or matrix[y][x] == 9) and not visited[y][x]