深度优先:走出迷宫,Python模拟实现

《深度优先:走出迷宫,Python模拟实现》         近来学习数据结构,书中给出练习题,走出迷宫,很有意思,便摸索了两天,终于,实现了部分功能。

这个图是很直观的,入口在左上角,出口在右下角,只有白色的位置可以走,但一次只能走一格,好了,怎么实现的呢,下面谈谈我的想法吧!

        由于之前弄过数独,因此对深度优先颇为喜欢,故而思考在这里能否照搬。

        1 为了易于处理,我将上图的迷宫表示成了数字矩阵的格式,就像下面这样

《深度优先:走出迷宫,Python模拟实现》

其中的数字0代表该位置不可走,1代表能走的位置,8代表入口,888代表出口。

        2 当位于入口的位置时,这时需要判断下一步可以走哪里,这可以定义函数来实现;而为了不出现来回两步走的情况,这里采用的思想为前进一步的同时,删除来向的位置,比如说如果走到8的右边,那么,我就同时把原来位置的数换为-8,表示已走过。

        3 2中的方法虽然可以避免来回死循环,但同时又产生了一个严重的问题,当自断来路而导致无路可走时怎么办,就像下面这样

《深度优先:走出迷宫,Python模拟实现》

当我自断来路后,却发现当走到如图红点的位置时,就没法走了,但当走进死胡同时,我要需要能够原路返回,因此,套路和数独中一样,我用列表把走的位置的信息记录下来,这样就能实现原路返回。

        下面贴代码了

import numpy as np
#迷宫中0的位置代表墙,不能走
#8代表入口,1代表可走位置
#88代表出口
migong = '''
0	0	0	0	0	0	0	0	0	0
0	8	1	0	1	1	1	0	0	0
0	1	1	0	1	1	1	0	1	0
0	1	1	1	1	0	0	1	1	0
0	1	0	0	0	1	1	1	1	0
0	1	1	1	0	1	0	1	1	0
0	1	0	1	1	1	0	1	1	0
0	1	0	0	0	1	0	1	1	0
0	0	1	1	1	1	1	1	888	0
0	0	0	0	0	0	0	0	0	0'''
data = np.array(migong.split(), dtype = int).reshape((10,10))


def direction_set(data):
    """
        函数功能,找到data中未被走过的地方,并同时记录该地方能够走的地方
    """
    dir_set = {}
    v, h = np.where(data > 0)
    for i,j in zip(v, h):
        key = str(i) + str(j)
        if data[i, j+1] > 0:            #该地方东邻块是否能走
            dir_set[key] = [(i, j+1)]
        if data[i+1, j] > 0:            #该地方南邻块是否能走
            if key in dir_set:
                dir_set[key] += [(i+1, j)]
            else:
                dir_set[key] = [(i+1, j)]
        #data[i, j-1]
        if data[i, j-1] > 0:            #该地方西邻块是否能走
            if key in dir_set:
                dir_set[key] += [(i, j-1)]
            else:
                dir_set[key] = [(i, j-1)]
        #data[i-1, j]
        if data[i-1, j] > 0:            #该地方北邻块是否能走
            if key in dir_set:
                dir_set[key] += [(i-1, j)]
            else:
                dir_set[key] = [(i-1, j)]
    return dir_set

step = []       #记录走的状态
key_old = '11'  #起始位置
print(data, '\n')

while True:
    #print(data)
    direct_set = direction_set(data)
    if key_old == '88':  #当到达出口的位置,就不用继续往别处走
        print(data)      #打印出路线,其中走过的位置都用-8标示出来了
        print([i for i,j in step])
        break
    if key_old in direct_set:
        step += [(key_old, direct_set[key_old])]
        data[int(key_old[0]), int(key_old[1])] = -8
        coors = direct_set[key_old][0]
        key_old = str(coors[0]) + str(coors[1])
    else:
        for i in range(len(step)):
            huish = step.pop()
            key = huish[0]
            values = huish[1]
            if len(values) == 1:
                data[int(key[0]), int(key[1])] = 1
                #print(data)
            else:
                key_old = str(values[1][0]) + str(values[1][1])
                step += [(key, values[1:])]
                #print(data)
                break

        运行结果如下

《深度优先:走出迷宫,Python模拟实现》

        可以看到程序运行后确实找到了一条路径能够出去,下面把888的位置换一下,看是否能重新找到一条路径,注意如果换了出口的话,程序里面的判断什么时候退出就要更换一下,这点很重要。如888的位置换成如下

《深度优先:走出迷宫,Python模拟实现》

        程序运行结果如下

《深度优先:走出迷宫,Python模拟实现》

        发现,结果也还不错,差强人意,至于为什么会出现这样的蛇形走位,其实是跟算法有关的,这个地方使用的是深度优先,它并没有考虑最短的问题,广度优先似乎更适合来解决这个问题,还在学习当中,等会了,再来更新对比一下。

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/weixin_42147487/article/details/80268390
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞