zoukankan      html  css  js  c++  java
  • 第一篇:算法之使用递归求解迷宫问题

    算法之使用递归求解迷宫问题

     

    题目要求:

    现有一个迷宫,四周都被围起来了,只能从一个入口进入,计算出一条通道使得从入口可以安全到达出口。在迷宫中行走的方向可以是(北,东北,东,东南,南,西南,西,西北)八个方向,迷宫图案如下:

    复制代码
     1 [
     2     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
     3     [0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
     4     [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
     5     [1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
     6     [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1],
     7     [1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
     8     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
     9     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
    10     [1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    11     [1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
    12     [1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
    13     [1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
    14     [1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
    15     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    16 ]
    复制代码

    入口位置在第二行第一列的位置,出口位置在倒数第二行最后一列的位置。中间是0的位置表示可以到达,其他位置被堵死。

    解决思路:

    假设在该迷宫中的某一点,其有八个方向可供选择,那么,遍历这八个方向,探测这周边八个方向是否是可达的,如果可达,那再以可达的点为当前点,继续遍历八个方向检测其周边的方向是否可达。设置一个标记表,只要是走过的点,都将标记位设置为1,这样是为了不走之前走过的老路。这样递归下去,直到到达我们想要出去的迷宫的出口处位置时,到达递归的最大深度,之后一层一层反向打印出之前走过的位置。。。

    复制代码
     1 #!/usr/bin/env python
     2 # encoding:utf-8
     3 # __author__: huxianglin
     4 # date: 2016-09-04
     5 # blog: http://huxianglin.cnblogs.com/ http://xianglinhu.blog.51cto.com/
     6 
     7 MAZE = [
     8     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
     9     [0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1],
    10     [1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
    11     [1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1],
    12     [1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1],
    13     [1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    14     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
    15     [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
    16     [1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    17     [1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1],
    18     [1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1],
    19     [1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1],
    20     [1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0],
    21     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    22 ]
    23 
    24 MOVE = [[0, -1, "N"], [1, -1, "NE"], [1, 0, "E"], [1, 1, "SE"], [0, 1, "S"], [-1, 1, "SW"], [-1, 0, "W"],
    25         [-1, -1, "NW"]]
    26 
    27 
    28 def seek_path(x, y):  # x,y作为横纵坐标传递进来
    29     if x == LINE-1 and y == ROW-2:  # 出口地址
    30         return True
    31     for i in range(8):  # 循环找八个方向看哪个方向有路
    32         line, row, direction = x+MOVE[i][0], y+MOVE[i][1], MOVE[i][2]  # 将当前位置的移动后的坐标以及移动方向赋值给新变量用来递归
    33         if MAZE[row][line] == 0 and mark[row][line] == 0:  # 移动后的坐标是通的并且之前没走过
    34             mark[row][line] = 1  # 将该新位置坐标标记为已走过
    35             if seek_path(line, row):  # 将新坐标传递到递归函数中进行下一步递归
    36                 print("横向移动:%s,纵向移动:%s,方向:%s" % (MOVE[i][0], MOVE[i][1], direction))
    37                 path.append(["横向移动:%s" % MOVE[i][0], "纵向移动:%s" % MOVE[i][1], "方向:%s" % direction,
    38                              "坐标:(%s,%s)" % (line, row)])
    39                 return True
    40 
    41 if __name__ == "__main__":
    42     LINE, ROW = len(MAZE[0]), len(MAZE)
    43     mark = []
    44     # for i in range(14):
    45     #     mark.append([0 for j in range(17)])
    46     mark = [[0 for v in range(len(MAZE[0]))] for m in range(len(MAZE))]  # 列表推导试生成mark列表
    47     path = []
    48     mark[1][0] = 1
    49     if seek_path(0, 1):
    50         print("迷宫走完了...下面是每一步的详细情况:")
    51     path.reverse()
    52     for i in path:
    53         print(i)
    复制代码
     
    分类: 算法
  • 相关阅读:
    连接到 ASP.NET 数据库
    ASP.NET数据库操作代码小结:SQL Server篇
    无法远程连接 SQL Server 2008
    使用 ADO.NET 来创建、读取、更新和删除数据
    User表引发的"FROM子句语法错误"
    传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确
    ANSI,Unicode,UTF8网页编码的区别【转】
    ASP.NET 数据库原理【转】
    Eval()时间格式化
    Eclipse下无法自动编译,或者WEBINF/classes目录下没文件,编译失败的解决办法
  • 原文地址:https://www.cnblogs.com/weiman3389/p/6224847.html
Copyright © 2011-2022 走看看