zoukankan      html  css  js  c++  java
  • 迷宫问题python实现(靠右手摸墙)

    大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang

    这是大二时候的数学模型毕业课程设计,我选择了自己研究盲人穿越迷宫的问题。当然后来再在网上查了这个问题研究比较成熟了,但是自己研究出来了也是小有成果的。

    当时是用C++实现的,而且用了不必要的递归来进行。

    现简化为简单的循环,并使用python实现了。

    以下进行我自己设计算法的思路设计,最后附上现在的python源码

    @”表示墙,“·”表示迷宫中可行路线上的空格,走过的路线用“X”表示。本问题只研究12×12规模且只有一个入口和一个出口(迷宫也许会不通)的迷宫。如何从入口走到出口?

    算法分析

    问题一, 迷宫构造   

    首先,我用二维字符型数组来表示迷宫的墙和可行路

    其次,可由系统产生01的随机数来控制每一个位置产生墙的概率,当然,如果要使概率可变动,那也无非是传递一个值而已。为使问题简单化,我将产生墙的概率设置为30%

    第三,将第一行和最后一行全部设置为墙,第一列和最后一列均只有一个可行路。

    问题二, 穿越方式

    分析 

    这类问题解决的方法应该很多,但就我现在掌握的以及现在的灵感,我只能想到蛮力的办法。

    解决

    一直沿着穿越者的右手边的墙壁走,如若此迷宫是通的,那一定能找到出口!

    用递归的办法,我只需要研究当前的位置到下一步的过程就可以了。

    问题三, 方向控制

    分析

    1、我设置的是二维数组,其动态必须通过数组的下标来控制

    2、对于穿越者来说,他的方向只有前后左右,人在其中必定是不知道自己的坐标的

    3、有了方向才不能迷失,这对于我们的穿越者也同样如此,每一次作的决策就是选择方向,即向左转90°还是不转还是向右转90°,这里规定穿越者一次只能选择其中一种,向左转和向右转的次数从最开始就累计,且一次向左转和一次向右转可抵消为不转

    4、由于迷宫是随机构造的,所以也有可能出现类似漩涡一样的路径,所以累计的向左转或者向右转的次数也有可能超过3次,即在空间存在转的角度超过360°,那么就需要研究同一方向上的转动次数的规律。

    解决

    根据以上分析,需要将做决策时穿越者的状态,具体的说就是穿越者面向的方向,用坐标绝对位置来表示出来。

    规定初始位置人的朝向是坐标方位向右用sum=0表示;

    每一次穿越者向自己的左边转一次,sum就减1

    每一次穿越者向自己的右边转一次,sum就加1

    将同一方向上的数字进行研究,可以发现其内在的规律:

    绝对向右的数字有…-12,-8,-4,0,4,8,12=4n

    绝对向上的数字有…-13,-9,-5,-1,3,7,11=4n-1

    绝对向左的数字有…-14,-10,-6,-2,2,6,10=4n-2

    据对向下的数字有…-11,-7,-3,1,5,9,13=4n+1

    由上观察,我发现余数sum%4与方向是对应的,就是说余数可以作为方向的判断标志,根据C++%的定义和用法,发现余数与被除数的符号一致,所以这样每个方向上有两个余数(绝对向右的除外,因为其余数为0),且它们都区别于其他方向上的余数。

    这样容易得出——

    设人的当前坐标为a[i][j]

    sum%4=0时,人绝对向右,此时若向前走一步,则为a[i][j+1]

    sum%4= 3 or -1 时,人绝对向上,此时若向前走一步,则为a[i-1][j]

    sum%4= -3 or 1 时,人绝对向下,此时若向前走一步,则为a[i+1][j]

    sum%4= -2 or 2 时,人绝对向左,此时若向前走一步,则为a[i][j-1]

    问题四,决策分析

    过程决策

    分析1

    假设前面的路都没有走过

    这是核心问题。

    这里分析时假定此时人的当前绝对方位是面向右的。

    1、 当前穿越者位置特征分析

          可以肯定,当前位置特征必定是穿越者的右边是一堵墙

    2、 

    穿越者前

    1、 前面环境分析

           根据排列组合知识可知,有4种情况,即

          1                  2                   3                      4

          X·               X@                 X @                    X·

      @@               @@                 @·                   @·

    人前有路,路右有墙 人前有墙,墙右有墙 人前有墙,墙右有路 人前有路,路右有路

    解决1

    根据分析,决策可分为三类,即将23合并

     1                     2                              3

          X·               X @        X @                   X·

       @@               @@        @·                   @·

    针对以上3种情况,可有与之相对应的3种决策

    对于1,前进一步

    对于2,向左转

    对于3,前进一步,向右转,前进一步

    这样,可以看到经过这样的决策,可使得人的右面是墙,便可重复进行上面的决策,递归便有作用了。整个穿越过程,便是以上过程的循环。

    分析2与解决2

        如果前面的路走过,即前方有“X”,将其与“.”一同看待处理。

     

    问题五,决策分析

    边界决策

    分析

    根据问题四,可对过程进行决策,但对于递归问题,还有关键的一点就是边界分析决策。可以注意到,此问题由于是随机产生的迷宫,所以存在不通路的情况,也就是可能会走回出发点。虽然结果也许我们认为是不同的,但是对于数组来说,都是越界。

    解决

    每一次都对其进行越界判断。如果下一步的坐标经判断是越界的,就不再需要进行问题四的操作了,就可以直接输出二维数组了,我们的问题也就解决了!

    python实现如下:

     1 #!usr/bin/python
     2 #Filename: maze.py
     3 import random
     4 a = [['#']*12 for i in range(12)]
     5 turn = [[0,1],[1,0],[0,-1],[-1,0]]#right,down,left,up; turn[i+1] means you turn right
     6 for i in range(1,11):
     7     for j in range(1,11):
     8         if random.random() > 0.3:#the wall is generated with the prosibility of 0.3
     9             a[i][j] = ' '
    10 a[1][1] = a[10][11] = a[10][10] = ' '#the maze is generated completely
    11 raw = 1#current raw number
    12 column = 0#current column number
    13 face = 0#0 means right, 1 means down, 2 means left, 3 means up 
    14 a[raw][column] = 'X'
    15 while column < 11:
    16     if face == 3:
    17         r_face = 0
    18     else:
    19         r_face = face + 1
    20     if face == 0:
    21         l_face = 3
    22     else:
    23         l_face = face - 1
    24     ft_r = raw + turn[face][0]
    25     ft_c = column + turn[face][1]
    26     ftrt_r = ft_r + turn[r_face][0]
    27     ftrt_c = ft_c + turn[r_face][1]
    28     if a[ft_r][ft_c] == '#':
    29         face = l_face
    30     elif a[ftrt_r][ftrt_c] == '#':
    31         raw = ft_r
    32         column = ft_c
    33         a[raw][column] = 'X'
    34     else:
    35         raw = ftrt_r
    36         column = ftrt_c
    37         a[ft_r][ft_c] = a[raw][column] = 'X'
    38         face = r_face
    39     if column == 0:
    40         print "The maze is death!
    "
    41         break
    42 for i in range(0,12):
    43     for j in range(0,12):
    44         print a[i][j],' ',
    45     print '
    '
  • 相关阅读:
    被放弃的概率权,机器下围棋不理会沉没成本
    百位性感女明星三围大曝光,体型测试设计
    斯坦福大学机器学习,EM算法求解高斯混合模型
    Javascript图片预加载详解
    使用马尔可夫模型自动生成文章
    18种女粉引流方法、效果、评估
    既然认准了这条路,就不必打听要走多久!
    新媒体运营10个大坑,思维导图版
    谷歌发布"自动机器学习"技术 AI可自我创造
    Centos7下PHP的卸载与安装nginx
  • 原文地址:https://www.cnblogs.com/xiaoyajiang/p/5950348.html
Copyright © 2011-2022 走看看