java递归老鼠走迷宫_6、老鼠走迷宫(简单,非最短路径)_python版本

最近看到一个新问题,老鼠走迷宫,原题是c版本的,想写成python版本。一个简单迷宫的实现,当中还有很多问题,一步一步来吧,人笨慢慢学习。

说明:

老鼠走迷宫是递归求解的基本题型,我们在二维阵列中使用2表示迷宫墙壁,使用1表示老鼠行走的路径,试以程

式求出由入口至出口的路径。

解法:

老鼠的走法有上,下,左,右四个方向,在每前进一格之后就选一个方向前进,无法前进时退回上一步选择下一个可前

进方向,如此在阵列中依序测试四个方向,知道走到出口为至。这是返回的基本题,请直接看程式应就可以理解

*/

从网上搜了一下,网上很多版本,大多都是反复递归,出栈和调用,比较复杂,慢慢学习吧,上一个简单版本,思路来自sinly100,看原版请移步。

看代码切记一行行读下去,看代码每一行的作用对象,理解含义,平时一目十行的阅读方式不是初学者的方法。

这是一个5 * 5数组排列:

03989f36ab2ee6f69bcc410dd655f9d3.png

我们设计一个迷宫:

0056cb660969f23d4a2573ce1a329fc9.png

注意此迷宫就一条通路,我们先来检验一下自己的设计思路。

1、用一个列表source存储迷宫图,一个列表route_stack存储路线图,一个列表route_history存储走过的点,起点(0,0),终点(4,4);

2、老鼠在每个点都有上下左右四种方案可选,因此我们需要设计4种上下左右四种方法;

3、最后做一个循环,如果当前点不是(4,4)的话就依次执行上下左右四种方法,但是也是一些必要的限制条件:

(1)、比如尝试走过的点不会再尝试走;

(2)、在四周的围墙,无法再执行越过围墙的操作。

上代码(代码里面有注释):

#!/user/bin/env.python

# _*_ coding:utf-8 _*_

# _author:poiuyds

"""

此方法不一定是最优化的解,在仅存在一种解法时正确,当存在多种解法时明显不是

"""

# 路线图

route_stack = [[0, 0]]

# 走过的点

route_history = [[0, 0]]

# 迷宫图

source = [[0, 0, 1, 0, 1],

[1, 0, 0, 0, 1],

[0, 0, 1, 1, 0],

[0, 1, 0, 0, 0],

[0, 0, 0, 1, 0] ]

# for i in source:

# print(i)

# for j in i:

# print(j)

# 上行函数

def up(location):

# 横坐标为0,无法再向上走

if location[0] == 0:

return False

else:

# 纵坐标不变,横坐标减1(向上)

new_location = [location[0]-1, location[1]]

# 已经尝试过的点不会尝试第二次

if new_location in route_history:

return False

# 碰到墙不走

elif source[new_location[0]][new_location[1]] == 1:

return False

else:

route_stack.append(new_location)

route_history.append(new_location)

return True

# 下行函数

def down(location):

# 横坐标为4,将不会下行

if location[0] == 4:

return False

else:

new_location = [location[0]+1, location[1]]

if new_location in route_history:

return False

elif source[new_location[0]][new_location[1]] == 1:

return False

else:

route_stack.append(new_location)

route_history.append(new_location)

return True

# 左行函数

def left(location):

# 纵坐标为0,不会左行

if location[1] == 0:

return False

else:

new_location = [location[0], location[1]-1]

if new_location in route_history:

return False

elif source[new_location[0]][new_location[1]] == 1:

return False

else:

route_stack.append(new_location)

route_history.append(new_location)

return True

# 右行函数

def right(location):

# 纵坐标为0,不会右行

if location[1] == 4:

return False

else:

new_location = [location[0], location[1]+1]

if new_location in route_history:

return False

elif source[new_location[0]][new_location[1]] == 1:

return False

else:

route_stack.append(new_location)

route_history.append(new_location)

return True

# 出发点

lo = [0, 0]

# 主函数

while route_stack[-1] != [4, 4]:

if up(lo):

lo = route_stack[-1]

# continue语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环

continue

if down(lo):

lo = route_stack[-1]

continue

if left(lo):

lo = route_stack[-1]

continue

if right(lo):

lo = route_stack[-1]

continue

# 将正确的路线点依次弹出

route_stack.pop()

# 将弹出点赋给lo继续下一次尝试

lo = route_stack[-1]

print(route_stack)

运行结果:

[[0, 0], [0, 1], [1, 1], [2, 1], [2, 0], [3, 0], [4, 0], [4, 1], [4, 2], [3, 2], [3, 3], [3, 4], [4, 4]]

我们再换一个迷宫尝试一下(存在多种方案),验证一下此解法是否最优解

b30517139fa437a133143467e3120cb3.png

运行结果:

[

[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [4, 1], [4, 2],

[5, 2], [5, 3], [5, 4], [4, 4], [3, 4], [3, 5], [3, 6],

[2, 6], [2, 7], [3, 7], [4, 7], [5, 7], [6, 7], [7, 7]

]

换成直观的路径图:

33f60ad8394b6330b89339fbdc71f908.png

可以明显看出来,此方案明显不是最短路径。

然后,我们分析一下代码的运行顺序,可以看出,我们这种方法明显的缺陷就是这一部分:

if up(lo):

lo = route_stack[-1]

# continue语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环

continue

if down(lo):

lo = route_stack[-1]

continue

if left(lo):

lo = route_stack[-1]

continue

if right(lo):

lo = route_stack[-1]

continue

该代码是按照up、down、left、right的顺序依次尝试,当有一条通路ok时,就不会尝试别的顺序了。如果按照此种方法想要尝试出最短路径,那么我们需要尝试4*4共16种方案。

才疏学浅,最短路径的算法暂时还不会写,日后学习到了有思路的时候一定补上,如果有思路的大佬请指点一下萌新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值