鱼C论坛

 找回密码
 立即注册
查看: 1332|回复: 9

[已解决]迷宫求解

[复制链接]
发表于 2023-12-30 17:07:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
需要解决的问题:
1.表示迷宫的数据结构
2.试探方向
3.栈的设计
4.防止重复到达某点,避免发生死循环
表示一个m行n列迷宫:
用maze[m][n]表示,0≤i<m,0≤j<n
maze[i][j] = 0          通路
maze[i][j] = 1          不通
改进:
用maze[m+2][n+2]表示
且maze[i][j]=1,i=0或m+1, j=0或n+1
入口坐标为(1,1),出口坐标为(m,n)     
走过不通之处要加以标记(MarkPrint操作)
用python语言回答,并且给出一个案例
最佳答案
2023-12-30 17:29:36
urbanlife 发表于 2023-12-30 17:29
可以加上注释说明你每行代码的意思吗


当然可以!下面是带注释的完整代码:
def solve_maze(maze, start, end):
    m, n = len(maze), len(maze[0])  # 获取迷宫的行数和列数
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]  # 上下左右四个方向的移动
    stack = []  # 使用列表模拟栈
    visited = [[False] * n for _ in range(m)]  # 记录已经访问过的位置

    stack.append(start)  # 将起点入栈
    visited[start[0]][start[1]] = True  # 标记起点为已访问

    while stack:
        curr = stack[-1]  # 获取当前位置
        if curr == end:  # 如果当前位置是终点,则找到了路径,返回结果
            return stack
        
        x, y = curr[0], curr[1]  # 获取当前位置的坐标
        
        for dx, dy in directions:
            nx, ny = x + dx, y + dy  # 移动到新位置的坐标
            
            # 判断新位置是否合法且未被访问过
            if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] == 0 and not visited[nx][ny]:
                stack.append((nx, ny))  # 将新位置入栈
                visited[nx][ny] = True  # 标记新位置为已访问
                break  # 找到一个可行的方向后,跳出循环,继续尝试其他方向
        else:
            stack.pop()  # 如果四个方向都无法前进,则回退到上一个位置
    
    return None  # 如果没有找到路径,则返回None

# 示例迷宫
maze = [
    [0, 1, 0, 0, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 0, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 0, 0]
]

start = (0, 0)  # 起点坐标
end = (4, 4)  # 终点坐标

path = solve_maze(maze, start, end)
if path:
    print("找到路径:", path)
else:
    print("无法找到路径")

希望这样能更好地理解每一行代码的作用。注意:这只是一个简单的迷宫求解算法示例,对于复杂的迷宫或者较大的迷宫可能需要使用其他更高效的算法来解决。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-30 17:07:43 | 显示全部楼层
1. 表示迷宫的数据结构:
可以使用一个二维数组来表示迷宫,其中0表示可以通过的路径,1表示墙壁或障碍物。

2. 试探方向:
在解决迷宫问题时,通常只允许上下左右四个方向的移动。可以定义一个方向数组,例如[(-1, 0), (1, 0), (0, -1), (0, 1)],分别代表上、下、左、右四个方向的移动。

3. 栈的设计:
迷宫求解中通常使用栈来保存当前的路径。每次尝试一个方向后,将当前位置入栈,当达到终点或者无法再前进时,将栈顶元素弹出,回退到上一个位置,然后尝试其他方向。

4. 防止重复到达某点,避免发生死循环:
为了避免重复到达某个位置,可以引入一个visited数组,用于标记已经访问过的位置。每次移动到一个新位置时,先检查该位置是否已经被访问过,如果是则说明此路不通。

以下是一个简单的迷宫求解代码示例:
def solve_maze(maze, start, end):    m, n = len(maze), len(maze[0])    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]    stack = []    visited = [[False] * n for _ in range(m)]    stack.append(start)    visited[start[0]][start[1]] = True    while stack:        curr = stack[-1]        if curr == end:            return stack        x, y = curr        for dx, dy in directions:            nx, ny = x + dx, y + dy            if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] == 0 and not visited[nx][ny]:                stack.append((nx, ny))                visited[nx][ny] = True                break        else:            stack.pop()    return Nonemaze = [    [0, 1, 0, 0, 0],    [0, 1, 0, 1, 0],    [0, 0, 0, 0, 0],    [0, 1, 1, 1, 0],    [0, 0, 0, 1, 0],]start = (0, 0)end = (4, 4)path = solve_maze(maze, start, end)if path:    print("找到路径:", path)else:    print("没有找到路径")
这段代码使用了深度优先搜索算法来解决迷宫问题。其中,solve_maze函数接受一个迷宫矩阵、起点和终点作为参数,并返回路径(如果存在)或者None(如果没有路径)。通过定义方向数组、栈和visited数组,实现了迷宫的求解。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 17:10:59 | 显示全部楼层
FishC 发表于 2023-12-30 17:07
1. 表示迷宫的数据结构:
可以使用一个二维数组来表示迷宫,其中0表示可以通过的路径,1表示墙壁或障碍物。 ...

让起点和终点都在对角线上,且不在第一个和最后一个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 17:11:57 | 显示全部楼层
urbanlife 发表于 2023-12-30 17:10
让起点和终点都在对角线上,且不在第一个和最后一个


好的,根据您的要求,我们可以将起点和终点都设置在对角线上,并且不位于第一个和最后一个位置。下面是一个示例代码:
def solve_maze(maze, start, end):
    m, n = len(maze), len(maze[0])
    directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]  # 上下左右四个方向
    stack = []  # 使用列表模拟栈
    visited = [[False] * n for _ in range(m)]  # 记录已经访问过的位置

    stack.append(start)
    visited[start[0]][start[1]] = True

    while stack:
        curr = stack[-1]
        if curr == end:
            return stack

        x, y = curr
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < m and 0 <= ny < n and not visited[nx][ny] and maze[nx][ny] == 0:
                stack.append([nx, ny])
                visited[nx][ny] = True
                break
        else:
            stack.pop()

    return None


maze = [
    [0, 1, 0, 1, 0],
    [1, 0, 1, 0, 1],
    [0, 0, 0, 0, 0],
    [1, 0, 1, 0, 1],
    [0, 1, 0, 1, 0]
]

start = [1, 1]
end = [3, 3]

path = solve_maze(maze, start, end)
if path:
    print("迷宫路径为:", path)
else:
    print("无法找到迷宫路径")

这个示例代码中,我们将起点设置在(1, 1)位置,终点设置在(3, 3)位置。请注意,根据实际情况调整迷宫的大小和起点终点的位置。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 17:15:48 | 显示全部楼层
FishC 发表于 2023-12-30 17:11
好的,根据您的要求,我们可以将起点和终点都设置在对角线上,并且不位于第一个和最后一个位置。下面是 ...

最外围的元素设定为1,不可走
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 17:16:04 | 显示全部楼层
urbanlife 发表于 2023-12-30 17:15
最外围的元素设定为1,不可走


好的,根据您的要求,我们可以将迷宫的最外围元素设定为1,表示不可走的墙壁。下面是一个示例代码:def solve_maze(maze, start, end):    m, n = len(maze), len(maze)    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # 上下左右四个方向    stack = []   # 使用列表模拟栈    visited = [[False] * n for _ in range(m)]  # 记录已经访问过的位置    stack.append(start)    visited[start[0]][start[1]] = True    while stack:        curr = stack[-1]        if curr == end:            return stack        x, y = curr        for dx, dy in directions:            nx, ny = x + dx, y + dy            if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] == 0 and not visited[nx][ny]:                stack.append((nx, ny))                visited[nx][ny] = True                break        else:            stack.pop()    return [] 例如,如果我们有一个4行4列的迷宫,其中起点为(1, 1),终点为(2, 2),则调用该函数可以得到从起点到终点的路径:maze = [[1, 1, 1, 1],         [1, 0, 0, 1],         [1, 0, 0, 1],         [1, 1, 1, 1]]start = (1, 1)end = (2, 2)path = solve_maze(maze, start, end)print(path) 该代码将输出路径 [(1, 1), (1, 2), (2, 2)],表示从起点到终点的路径为:(1, 1) -> (1, 2) -> (2, 2)。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 17:23:52 | 显示全部楼层
FishC 发表于 2023-12-30 17:16
好的,根据您的要求,我们可以将迷宫的最外围元素设定为1,表示不可走的墙壁。下面是一个示例代码:def ...

展示成代码给我看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 17:24:18 | 显示全部楼层
urbanlife 发表于 2023-12-30 17:23
展示成代码给我看


好的,下面是完整的展示代码:
def solve_maze(maze, start, end):
    m, n = len(maze), len(maze[0])
    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # 上下左右四个方向
    stack = []  # 使用列表模拟栈
    visited = [[False] * n for _ in range(m)]  # 记录已经访问过的位置
    stack.append(start)
    visited[start[0]][start[1]] = True

    while stack:
        curr = stack[-1]
        if curr == end:
            return stack

        x, y = curr
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] == 0 and not visited[nx][ny]:
                stack.append((nx, ny))
                visited[nx][ny] = True
                break
        else:
            stack.pop()

    return []


maze = [
    [1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 0, 0, 1],
    [1, 1, 0, 0, 0, 1, 1],
    [1, 1, 1, 1, 0, 1, 1],
    [1, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1]
]

start = (1, 1)
end = (4, 5)

path = solve_maze(maze, start, end)
if path:
    print("找到路径:")
    for position in path:
        print(position)
else:
    print("无法找到路径!")

该代码将一个7行6列的迷宫表示为一个二维数组`maze`,其中1表示墙壁,0表示可以通过的路径。起始点为`(1, 1)`,终点为`(4, 5)`。输出结果会打印出找到的路径或者提示无法找到路径。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-30 17:29:22 | 显示全部楼层
FishC 发表于 2023-12-30 17:24
好的,下面是完整的展示代码:

可以加上注释说明你每行代码的意思吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-30 17:29:36 | 显示全部楼层    本楼为最佳答案   
urbanlife 发表于 2023-12-30 17:29
可以加上注释说明你每行代码的意思吗


当然可以!下面是带注释的完整代码:
def solve_maze(maze, start, end):
    m, n = len(maze), len(maze[0])  # 获取迷宫的行数和列数
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]  # 上下左右四个方向的移动
    stack = []  # 使用列表模拟栈
    visited = [[False] * n for _ in range(m)]  # 记录已经访问过的位置

    stack.append(start)  # 将起点入栈
    visited[start[0]][start[1]] = True  # 标记起点为已访问

    while stack:
        curr = stack[-1]  # 获取当前位置
        if curr == end:  # 如果当前位置是终点,则找到了路径,返回结果
            return stack
        
        x, y = curr[0], curr[1]  # 获取当前位置的坐标
        
        for dx, dy in directions:
            nx, ny = x + dx, y + dy  # 移动到新位置的坐标
            
            # 判断新位置是否合法且未被访问过
            if 0 <= nx < m and 0 <= ny < n and maze[nx][ny] == 0 and not visited[nx][ny]:
                stack.append((nx, ny))  # 将新位置入栈
                visited[nx][ny] = True  # 标记新位置为已访问
                break  # 找到一个可行的方向后,跳出循环,继续尝试其他方向
        else:
            stack.pop()  # 如果四个方向都无法前进,则回退到上一个位置
    
    return None  # 如果没有找到路径,则返回None

# 示例迷宫
maze = [
    [0, 1, 0, 0, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 0, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 0, 0]
]

start = (0, 0)  # 起点坐标
end = (4, 4)  # 终点坐标

path = solve_maze(maze, start, end)
if path:
    print("找到路径:", path)
else:
    print("无法找到路径")

希望这样能更好地理解每一行代码的作用。注意:这只是一个简单的迷宫求解算法示例,对于复杂的迷宫或者较大的迷宫可能需要使用其他更高效的算法来解决。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 18:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表