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

        近来学习数据结构,书中给出练习题,走出迷宫,很有意思,便摸索了两天,终于,实现了部分功能。

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

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

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


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

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

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


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

        下面贴代码了

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

        运行结果如下


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


        程序运行结果如下


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


  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值