停留在最小骑士的移动以到达终点位置
Stuck at minimum knight's move to reach the end position
我正在解决这个问题:
Find the minimum number of steps required by the knight to move from the starting position to the end position in a nXn chess board. If the path does not exists, then return -1
我写了下面的代码:
def is_position_safe(n, cur_row, cur_col):
if 0 <= cur_row < n and 0 <= cur_col < n:
return True
else:
return False
def min_moves(n, cur_row, cur_col, end_row, end_col, visited):
if cur_row == end_row and cur_col == end_col:
return 0
key = tuple([cur_row, cur_col])
visited_temp = visited.copy()
if is_position_safe(n, cur_row, cur_col) and key not in visited:
visited_temp.append(key)
d1 = min_moves(n, cur_row - 2, cur_col - 1, end_row, end_col, visited_temp)
d2 = min_moves(n, cur_row - 2, cur_col + 1, end_row, end_col, visited_temp)
d3 = min_moves(n, cur_row - 1, cur_col - 2, end_row, end_col, visited_temp)
d4 = min_moves(n, cur_row - 1, cur_col + 2, end_row, end_col, visited_temp)
d5 = min_moves(n, cur_row + 1, cur_col - 2, end_row, end_col, visited_temp)
d6 = min_moves(n, cur_row + 1, cur_col + 2, end_row, end_col, visited_temp)
d7 = min_moves(n, cur_row + 2, cur_col - 1, end_row, end_col, visited_temp)
d8 = min_moves(n, cur_row + 2, cur_col + 1, end_row, end_col, visited_temp)
return min(d1, d2, d3, d4, d5, d6, d6, d7, d8) + 1
else:
return float('inf')
def min_knight_moves(n, cur_row, cur_col, end_row, end_col):
result = min_moves(n, cur_row, cur_col, end_row, end_col, [])
if result != float('inf'):
return result
else:
return -1
print(min_knight_moves(10, 9, 9, 6, 3))
在某些情况下它不起作用。例如,对于上面的那个,它返回我 5
,但实际答案是 3
.
我不明白我哪里做错了。谁能帮帮我。
P.S.: 我知道有现有的解决方案,通过使用 BFS,但我正在尝试递归解决这个问题。我不太确定,我哪里错了。感谢你的帮助。谢谢!
记忆可能不是最好的情况,因为骑士可以从不同的路径到达某个地点,并且对于每条路径都有不同的访问集。因此我建议创建一个 visited_temp = visited.copy()
并将其转发到递归中而不使用记忆。
visited_temp = visited.copy()
if is_position_safe(n, cur_row, cur_col) and key not in visited:
visited_temp.append(key)
d1 = min_moves(n, cur_row - 2, cur_col - 1, end_row, end_col, visited_temp)
d2 = min_moves(n, cur_row - 2, cur_col + 1, end_row, end_col, visited_temp)
d3 = min_moves(n, cur_row - 1, cur_col - 2, end_row, end_col, visited_temp)
d4 = min_moves(n, cur_row - 1, cur_col + 2, end_row, end_col, visited_temp)
d5 = min_moves(n, cur_row + 1, cur_col - 2, end_row, end_col, visited_temp)
d6 = min_moves(n, cur_row + 1, cur_col + 2, end_row, end_col, visited_temp)
d7 = min_moves(n, cur_row + 2, cur_col - 1, end_row, end_col, visited_temp)
d8 = min_moves(n, cur_row + 2, cur_col + 1, end_row, end_col, visited_temp)
return min(d1, d2, d3, d4, d5, d6, d6, d7, d8) + 1
else:
return float('inf')
这个问题也被称为 self avoiding walk problem. I have posted a DFS solution without memoization to the self avoiding walk 但我选择 DFS 只是因为所有可能的路径都是 objective。自我回避行走不能有记忆,因为正如我所说,每条路径都有自己的访问集。
请注意,由于您希望通过递归而不是 BFS 使用 DFS,因此您的 运行时间将呈指数增长,因为您必须在决定之前计算所有路径。我选择了 BFS 方法,由于 BFS 的性质,您可以停止到达目的地。
运行 建议的解决方案
在 10X10 网格上需要很长时间,因为 运行 时间呈指数级增长,因此对于较低网格上的以下类似示例,我们得到:
print(min_knight_moves(5, 4, 4, 2, 0)) # 2
对于 6 或更大的网格大小,我在它结束之前杀死了 运行,因为它需要很长时间,递归在这个问题上不是一个好的方法
我正在解决这个问题:
Find the minimum number of steps required by the knight to move from the starting position to the end position in a nXn chess board. If the path does not exists, then return -1
我写了下面的代码:
def is_position_safe(n, cur_row, cur_col):
if 0 <= cur_row < n and 0 <= cur_col < n:
return True
else:
return False
def min_moves(n, cur_row, cur_col, end_row, end_col, visited):
if cur_row == end_row and cur_col == end_col:
return 0
key = tuple([cur_row, cur_col])
visited_temp = visited.copy()
if is_position_safe(n, cur_row, cur_col) and key not in visited:
visited_temp.append(key)
d1 = min_moves(n, cur_row - 2, cur_col - 1, end_row, end_col, visited_temp)
d2 = min_moves(n, cur_row - 2, cur_col + 1, end_row, end_col, visited_temp)
d3 = min_moves(n, cur_row - 1, cur_col - 2, end_row, end_col, visited_temp)
d4 = min_moves(n, cur_row - 1, cur_col + 2, end_row, end_col, visited_temp)
d5 = min_moves(n, cur_row + 1, cur_col - 2, end_row, end_col, visited_temp)
d6 = min_moves(n, cur_row + 1, cur_col + 2, end_row, end_col, visited_temp)
d7 = min_moves(n, cur_row + 2, cur_col - 1, end_row, end_col, visited_temp)
d8 = min_moves(n, cur_row + 2, cur_col + 1, end_row, end_col, visited_temp)
return min(d1, d2, d3, d4, d5, d6, d6, d7, d8) + 1
else:
return float('inf')
def min_knight_moves(n, cur_row, cur_col, end_row, end_col):
result = min_moves(n, cur_row, cur_col, end_row, end_col, [])
if result != float('inf'):
return result
else:
return -1
print(min_knight_moves(10, 9, 9, 6, 3))
在某些情况下它不起作用。例如,对于上面的那个,它返回我 5
,但实际答案是 3
.
我不明白我哪里做错了。谁能帮帮我。
P.S.: 我知道有现有的解决方案,通过使用 BFS,但我正在尝试递归解决这个问题。我不太确定,我哪里错了。感谢你的帮助。谢谢!
记忆可能不是最好的情况,因为骑士可以从不同的路径到达某个地点,并且对于每条路径都有不同的访问集。因此我建议创建一个 visited_temp = visited.copy()
并将其转发到递归中而不使用记忆。
visited_temp = visited.copy()
if is_position_safe(n, cur_row, cur_col) and key not in visited:
visited_temp.append(key)
d1 = min_moves(n, cur_row - 2, cur_col - 1, end_row, end_col, visited_temp)
d2 = min_moves(n, cur_row - 2, cur_col + 1, end_row, end_col, visited_temp)
d3 = min_moves(n, cur_row - 1, cur_col - 2, end_row, end_col, visited_temp)
d4 = min_moves(n, cur_row - 1, cur_col + 2, end_row, end_col, visited_temp)
d5 = min_moves(n, cur_row + 1, cur_col - 2, end_row, end_col, visited_temp)
d6 = min_moves(n, cur_row + 1, cur_col + 2, end_row, end_col, visited_temp)
d7 = min_moves(n, cur_row + 2, cur_col - 1, end_row, end_col, visited_temp)
d8 = min_moves(n, cur_row + 2, cur_col + 1, end_row, end_col, visited_temp)
return min(d1, d2, d3, d4, d5, d6, d6, d7, d8) + 1
else:
return float('inf')
这个问题也被称为 self avoiding walk problem. I have posted a DFS solution without memoization to the self avoiding walk
请注意,由于您希望通过递归而不是 BFS 使用 DFS,因此您的 运行时间将呈指数增长,因为您必须在决定之前计算所有路径。我选择了 BFS 方法,由于 BFS 的性质,您可以停止到达目的地。
运行 建议的解决方案
在 10X10 网格上需要很长时间,因为 运行 时间呈指数级增长,因此对于较低网格上的以下类似示例,我们得到:
print(min_knight_moves(5, 4, 4, 2, 0)) # 2
对于 6 或更大的网格大小,我在它结束之前杀死了 运行,因为它需要很长时间,递归在这个问题上不是一个好的方法