python 二维迷宫路径探测 和可视化 递归回溯算法

python 自学,以一个常规的习题做自己这段时间的学习总结

问题描述:

给定迷宫,入口坐标和出口坐标,给出一条从入口到出口的坐标路径,并完成可视化。

例如:

迷宫

listMap=[
    ['1', '0', '1', '1', '1', '1', '1', '1', '1'],\
    ['1', '0', '0', '0', '1', '0', '1', '0', '1'],\
    ['1', '1', '1', '0', '1', '1', '1', '0', '1'],\
    ['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
    ['1', '0', '0', '1', '1', '1', '1', '0', '1'],\
    ['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
    ['1', '1', '1', '1', '1', '0', '1', '0', '1'],\
    ['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
    ['1', '1', '1', '1', '1', '1', '1', '0', '1'] ]

1为墙,0为路径

入口坐标:(0,1)0为y,行号;1为x,列号;

出口坐标:(8,7)8为y,行号;7为x,列好。

坐标系:x水平向右,y垂直向下

======================系统输出如下==============

(0, 1)
(1, 1)
(1, 2)
(1, 3)
(2, 3)
(3, 3)
(3, 2)
(4, 2)
(5, 2)
(5, 3)
(5, 4)
(5, 5)
(6, 5)
(7, 5)
(7, 6)
(7, 7)
(8, 7)
 1  *  1  1  1  1  1  1  1 
 1  *  *  *  1  0  1  0  1 
 1  1  1  *  1  1  1  0  1 
 1  0  *  *  0  0  0  0  1 
 1  0  *  1  1  1  1  0  1 
 1  0  *  *  *  *   0  0  1 
 1  1  1  1  1  *  1  0  1 
 1  0  0  0  0  *  *  *  1 
 1  1  1  1  1  1  1  *  1 
 

============================================

思路:自然路径探测。

函数:findChild。

从fthPoint 走到CurrentPoint,然后根据CurrentPoint向4个方向探测,如果这4个方向的坐标不是fthPoint,且该3个方向的坐标不是1,则将CurrentPoint存入字典的key里面,将它的3个方向中为0的坐标存入字典的value里面。然后从这三个方向的坐标中选一个,作为新的CurrentPoint,原先的CurrentPoint作为fthPoint,继续探测,直到某一个坐标为出口坐标。

回溯函数:back

在上面的CurrentPoint没有为0的子坐标,则说明这条路径不通,从字典中删除父节点,如果父节点的父节点已经没有可用路径,则继续向上删除,如果有,选一个新的坐标,做findChild探测。

为保存当前节点的可用路径,定义结构体如下:

class itemValue:
    def __init__(self):
        self.fPoint=(0,1)   #父节点坐标
        self.dirs=[]    # 不包含父节点的所有子节点,

地图和入口出口坐标定义如下:

listMap=[
    ['1', '0', '1', '1', '1', '1', '1', '1', '1'],\
    ['1', '0', '0', '0', '1', '0', '1', '0', '1'],\
    ['1', '1', '1', '0', '1', '1', '1', '0', '1'],\
    ['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
    ['1', '0', '0', '1', '1', '1', '1', '0', '1'],\
    ['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
    ['1', '1', '1', '1', '1', '0', '1', '0', '1'],\
    ['1', '0', '0', '0', '0', '0', '0', '0', '1'],\
    ['1', '1', '1', '1', '1', '1', '1', '0', '1'] ]

dictPath =dict()
endPoint = (8, 7)   #8为y 行,7为x  列

查找子节点的函数如下:

def find_child(fthPoint,currPoint): #没有可用子节点,则返回失败,否则将可用子节点添加到dict
    childItem=itemValue()
    childItem.fPoint=fthPoint

    point=(currPoint[0]+1,currPoint[1])
    if point == endPoint:
        childItem.dirs.append(point)
        dictPath[currPoint] = childItem
        return True
    if point not in dictPath.keys():
        if listMap[point[0]][point[1]] == '0':
            childItem.dirs.append(point)

    point = (currPoint[0] , currPoint[1]-1)
    if point == endPoint:
        childItem.dirs.append(point)
        dictPath[currPoint] = childItem
        return True
    if point not in dictPath.keys():
        if listMap[point[0]][point[1]] == '0':
            childItem.dirs.append(point)

    point = (currPoint[0]-1 , currPoint[1])
    if point == endPoint:
        childItem.dirs.append(point)
        dictPath[currPoint] = childItem
        return True
    if point not in dictPath.keys():
        if listMap[point[0]][point[1]] == '0':
            childItem.dirs.append(point)

    point = (currPoint[0], currPoint[1]+1)
    if point == endPoint:
        childItem.dirs.append(point)
        dictPath[currPoint] = childItem
        return True
    if point not in dictPath.keys():
        if listMap[point[0]][point[1]] == '0':
            childItem.dirs.append(point)

    if len(childItem.dirs)==0:
        back(fthPoint)
    else:
        dictPath[currPoint] = childItem
        point = childItem.dirs[0]
        if(currPoint !=endPoint):find_child(currPoint,point)
        else: return True

死胡同,回溯函数如下

def back(point):
    value1=dictPath[point]
    fthPoint =value1.fPoint;#找到当前点的父节点
    if(fthPoint==point):
        print("no path")
        exit(0)
    dictPath.pop(point)
    fthValue = dictPath[fthPoint]
    fthValue.dirs.remove(point)
    if len(fthValue.dirs)==0:
        back(fthPoint)
    else:
        value2 =dictPath[fthPoint]
        currPoint =value2.dirs[0]
        find_child(fthPoint,currPoint)

结果可视化和输出函数如下:

def main():
    beginPoint=(0,1)
    childPoint=(1,1)
    itemValue0 =itemValue()
    itemValue0.fPoint=beginPoint
    itemValue0.dirs.append(childPoint)
    dictPath[beginPoint]=itemValue0
    find_child(beginPoint,childPoint)
    childItem = itemValue()
    dictPath[endPoint] = childItem
    for key,value in dictPath.items():
        print(key)

    for y in range(len(listMap)):
        for x in range(len(listMap[0])):
            if (y,x) in dictPath.keys():
                print(' * ',end='')
            else:
                print(" %s "%listMap[y][x],end='')
        print()

    return 1
main()

 

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

健忘的松鼠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值