搜索回溯算法①

假设有一座N*M的迷宫,每两点之间的距离为1米,如下所示(图仅供参考):

436a0b4491e4fe1606c047f0827f60f.png

此迷宫是一个二维网格,其中‘#’表示墙体,‘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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰灰老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值