假设有一座N*M的迷宫,每两点之间的距离为1米,如下所示(图仅供参考):
此迷宫是一个二维网格,其中‘#’表示墙体,‘o’表示可以可以行走的路径,迷宫的四周一定的由‘#’构成的墙体,除迷宫四周以外,其他部分的墙体可随机生成。
假如发生突发情况,你的任务是找到一条最短路线将人群从S点安全撤离至E点,并统计出撤离路线的路径总长及走过的路径具体是什么。
若有相同的路线则输出一条路线的长度与路径即可;若无路可走,提示:“未找到逃生路线”;
输入格式:
输入描述:输入有N*M行,每行由‘#’和‘o’构成,可直接复制测试样例中的迷宫图案做测试。
建议:输入后的图案建议构成一个二维矩阵,便于计算。
输出格式:
输出有3行:
第一行输出路径长度,中文提示信息与冒号后面的值之间有一个空格,使用的是print(x,y)的方式进行输出的。
第二行输出具体路径,中文提示信息与冒号后面的值之间有一个空格,使用的是print(x,y)的方式进行输出的。
第三行为一个空行。
输入样例:
['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
['#', 'S', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#'],
['#', '#', '#', '#', '#', 'o', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
['#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#'],
['#', 'o', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 'o', '#'],
['#', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#'],
['#', 'o', '#', 'o', '#', '#', '#', '#', '#', '#', '#', '#', 'o', '#', 'o', '#'],
['#', 'o', '#', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#', 'o', '#'],
['#', 'o', '#', 'o', '#', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', '#', 'o', '#'],
['#', 'o', '#', 'o', '#', 'o', 'o', 'o', 'o', '#', 'o', '#', 'o', '#', 'o', '#'],
['#', 'o', '#', 'o', '#', '#', '#', '#', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#'],
['#', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', '#', 'o', '#'],
['#', 'o', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 'o', '#'],
['#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#'],
['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', 'o', 'o', '#'],
['#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'E', '#'],
['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
输出样例:
路径长度: 36
路径: [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 5), (3, 5), (3, 4), (3, 3), (3, 2), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (13, 2), (13, 3), (13, 4), (13, 5), (13, 6), (13, 7), (13, 8), (13, 9), (13, 10), (13, 11), (13, 12), (13, 13), (14, 13), (15, 13), (15, 14)]
提供一种随机生成迷宫地图及其路径求解的算法:
# 将回溯算法用于搜索的过程中
import random
def generate_maze(rows, cols, wall_prob):
'''
随机生成迷宫地图,四周为墙'#',中间可行的通道用'o'表示,起点为'S',终点为'E'
:param rows: 需要生成的迷宫地图行数,不要太大避免溢出
:param cols: 需要生成的迷宫地图列数,不要太大避免溢出
:param wall_prob: 生成概率
:return: 返回迷宫地图
'''
maze = [['#' for _ in range(cols)] for _ in range(rows)] # 初始化迷宫,边界由 "#" 构成
for i in range(1, rows - 1):
for j in range(1, cols - 1):
if random.random() > wall_prob:
maze[i][j] = 'o' # 随机生成空地
start = (random.randint(1, rows - 2), random.randint(1, cols - 2))
end = (random.randint(1, rows - 2), random.randint(1, cols - 2))
maze[start[0]][start[1]] = 'S'
maze[end[0]][end[1]] = 'E'
return maze
maze_rows = int(input('请输入迷宫的行N(0<N<=100):'))
maze_cols = int(input('请输入迷宫的列M(0<M<=100):'))
wall_probability = 0.3
maze_r = generate_maze(maze_rows, maze_cols, wall_probability)
print(maze_r) # 打印迷宫地图
maze_result = []
# 打印迷宫
for row in maze_r:
maze_result.append('[' + ','.join(row) + '],')
def find_shortest_path(maze):
'''
搜索与回溯算法过程
:param maze: 地图
:return: 返回是否能够找到路径或'未找到逃生路线'
'''
# 获取迷宫的行数和列数
rows = len(maze)
cols = len(maze[0])
# 定义四个方向的移动向量:上、下、左、右
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
# 定义起点和终点的坐标
start = None
end = None
# 找到起点和终点的坐标
for i in range(rows):
for j in range(cols):
if maze[i][j] == 'S':
start = (i, j)
elif maze[i][j] == 'E':
end = (i, j)
# 如果起点或终点不存在,返回无法找到逃生路线
if start is None or end is None:
return "未找到逃生路线"
path = [] # 保存路径
def dfs(current, path):
# 如果当前位置是终点,返回True表示找到了逃生路径
if current == end:
return True
x, y = current
# 向四个方向进行搜索
for dx, dy in directions:
nx, ny = x + dx, y + dy
# 判断新位置是否在迷宫范围内,且可以行走,并且没有在路径中出现过
if 0 <= nx < rows and 0 <= ny < cols and maze[nx][ny] != '#' and (nx, ny) not in path:
path.append((nx, ny)) # 将新位置添加到路径中
if dfs((nx, ny), path): # 递归搜索新位置
return True
path.pop() # 如果新位置不在逃生路径中,将其从路径中移除
return False
path.append(start) # 将起点添加到路径中
if dfs(start, path): # 开始深度优先搜索
path_length = len(path) # 计算路径长度
return path_length, path # 返回路径长度和具体路径
else:
return "未找到逃生路线" # 如果无法找到逃生路径,返回相应的提示信息
maze = maze_result
# maze为测试样例
# maze = [
# ['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
# ['#', 'S', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#'],
# ['#', '#', '#', '#', '#', 'o', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
# ['#', 'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#'],
# ['#', 'o', '#', '#', '#', '#', '#', '#', '#', '#', '#', 'o', '#', '#', 'o', '#'],
# ['#', 'o', '#', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#'],
# ['#', 'o', 'o', 'o', '#', '#', '#', '#', '#', '#', '#', '#', 'o', '#', 'o', '#'],
# ['#', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#', 'o', '#'],
# ['#', 'o', '#', 'o', 'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', '#', '#', '#'],
# ['#', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#', 'o', '#', 'o', '#'],
# ['#', 'o', '#', 'o', 'o', '#', '#', '#', 'o', 'o', 'o', 'o', 'o', '#', 'o', '#'],
# ['#', 'o', '#', '#', 'o', 'o', '#', 'o', 'o', '#', 'o', 'o', 'o', '#', 'o', '#'],
# ['#', 'o', '#', '#', 'o', 'o', '#', '#', '#', '#', '#', 'o', 'o', 'o', 'o', '#'],
# ['#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', 'o', '#'],
# ['#', '#', '#', '#', '#', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', '#'],
# ['#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'E', '#'],
# ['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
# ]
result = find_shortest_path(maze)
if isinstance(result, str):
print(result)
else:
path_length, path = result
print("路径长度:", path_length)
print("路径:", path)