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

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

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

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

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

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

算法分析

问题一, 迷宫构造   

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

其次,可由系统产生0到1的随机数来控制每一个位置产生墙的概率,当然,如果要使概率可变动,那也无非是传递一个值而已。为使问题简单化,我将产生墙的概率设置为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

根据分析,决策可分为三类,即将2和3合并

1                     2                              3

X·               X @        X @                   X·

@@               @@        @·                   @·

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

对于1,前进一步

对于2,向左转

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

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

分析2与解决2

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

 

问题五,决策分析

边界决策

分析

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

解决

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

python实现如下:

#!usr/bin/python
#Filename: maze.py
import random
a = [['#']*12 for i in range(12)]
turn = [[0,1],[1,0],[0,-1],[-1,0]]#right,down,left,up; turn[i+1] means you turn right
for i in range(1,11):
    for j in range(1,11):
        if random.random() > 0.3:#the wall is generated with the prosibility of 0.3
            a[i][j] = ' '
a[1][1] = a[10][11] = a[10][10] = ' '#the maze is generated completely
raw = 1#current raw number
column = 0#current column number
face = 0#0 means right, 1 means down, 2 means left, 3 means up 
a[raw][column] = 'X'
while column < 11:
    if face == 3:
        r_face = 0
    else:
        r_face = face + 1
    if face == 0:
        l_face = 3
    else:
        l_face = face - 1
    ft_r = raw + turn[face][0]
    ft_c = column + turn[face][1]
    ftrt_r = ft_r + turn[r_face][0]
    ftrt_c = ft_c + turn[r_face][1]
    if a[ft_r][ft_c] == '#':
        face = l_face
    elif a[ftrt_r][ftrt_c] == '#':
        raw = ft_r
        column = ft_c
        a[raw][column] = 'X'
    else:
        raw = ftrt_r
        column = ftrt_c
        a[ft_r][ft_c] = a[raw][column] = 'X'
        face = r_face
    if column == 0:
        print "The maze is death!\n"
        break
for i in range(0,12):
    for j in range(0,12):
        print a[i][j],' ',
    print '\n'

迷宫问题python实现(靠右手摸墙)的更多相关文章

  1. 教你用Python制作微信好友背景墙

    目录: 0 引言 1 环境 2 代码实现 3 后记 0 引言 前段时间,微信朋友圈开始出现了一种晒照片新形式,微信好友墙,即在一张大图片中展示出自己的所有微信好友的头像. 效果如下图,出于隐私考虑,这 ...

  2. XIX Open Cup named after E.V. Pankratiev. GP of Poland(AMPPZ-2018)

    A. Drone With a Camera 三分套三分. #include<cstdio> #include<cmath> #include<algorithm> ...

  3. Python迷宫生成器

    作为一项古老的智力游戏,千百年来迷宫都散发着迷人的魅力.但是,手工设计迷宫费时又耗(脑)力,于是,我们有必要制作一个程序:迷宫生成器-- 好吧,我编不下去了.但是,从上面的文字中,我们可以看出,我们此 ...

  4. [LeetCode] Walls and Gates 墙和门

    You are given a m x n 2D grid initialized with these three possible values. -1 - A wall or an obstac ...

  5. 剑指Offer——回溯算法解迷宫问题(java版)

    剑指Offer--回溯算法解迷宫问题(java版)   以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍.设计程序,对任意设定的迷宫,求出从入口到出口的所有通路.   下面我们来详细讲一 ...

  6. 搜索入门之dfs--经典的迷宫问题解析

    今天来谈一下dfs的入门,以前看到的dfs入门,那真的是入门吗,都是把dfs的实现步骤往那一贴,看完是知道dfs的步骤了,但是对于代码实现还是没有概念.今天准备写点自己的心得,真的是字面意思--入门. ...

  7. 《C++游戏开发》十六 游戏中的寻路算法(二):迷宫&A*算法基础

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/10289253 作者:七十一雾央 新浪微博:http: ...

  8. Python之微信-微信好友头像合成

    仔细看下图,你的头像就藏在里面哦!!! 有没有犯密集恐惧症?这并不震撼,如果你有 5000 位好友的话,做出来的图看着会更刺激些. 看完了图,你可能想知道这个图咋做出来的,不会是我闲着无聊把把好友头像 ...

  9. [LeetCode] 286. Walls and Gates 墙和门

    You are given a m x n 2D grid initialized with these three possible values. -1 - A wall or an obstac ...

随机推荐

  1. ubuntu安装openssh-server

    openssh-server是依赖于openssh-clienr的,那ubuntu不是自带了openssh-client吗? 原因是自带的openssh-clien与所要安装的openssh-serv ...

  2. 带KEY的SCP命令,老是要查,这次写在这里吧,

    有些东东记不住,急要用时老是想不起,放在这里吧, scp -r -i /xxx/rsa.key -P port user@ip:/source/ /target/

  3. QQ截图时窗口自动识别的原理(WindowFromPoint, ChildWindowFromPoint, ChildWindowFromPointEx,RealChildWindowFromPoint)

    新版的QQ在截图时加入了窗口自动识别的功能,能根据鼠标的位置自动画出下面窗口的轮廓.今天有人在论坛上问起这个问题,下面我们来探讨这个功能的实现原理. 首先我们要明白截图软件的基本原理,截图时实际上是新 ...

  4. 使用面向 iOS 的本机插件扩展

    本文细致探讨了 Xcode(以 iOS 设备为目标)中的 PhoneGap(也称为 Apache Cordova)应用程序本机插件.如果您刚开始接触 PhoneGap 或者需要回顾 PhoneGap ...

  5. 标准I/O介绍

    标准I/O库 1. 标准I/O介绍 不仅是在UNIX系统中,很多操作系统上都实现了标准I/O库. 标准I/O库由ANSI C 标准说明 标准 I/O 库处理很多细节,例如带有缓冲分配.以优化长度执行的 ...

  6. Hacker(22)----解除系统中的密码

    Win7系统中,用户可以设置BIOS密码以及系统登录密码,这些密码都有各自的用途.但对黑客而言,完全可以采用不同的方式绕过这些密码.下面介绍黑客如如何接触这些密码. 一.解除BIOS密码 BIOS密码 ...

  7. Fantageek翻译系列之《使用Autolayout显示变化高度的UITableViewCell》

    这篇博客主要在于,解释如何通过仅仅使用Autolayout很很少的代码,显示高度不同的Cell.虽然标题说的是TableView,但是CollectionView同样适合.但是,这种方法只使用iOS7 ...

  8. 除去内容中的HTML代码方法

    显示内容时,需要截取部分,而不要全部显示.在截取时,会出现这样的情况: 截取一定量的字符串后,可能会把未关闭的表格HTML代码留下来,最終导致界面受影响, 下面的是C#解决办法: public str ...

  9. 《第一行代码》学习笔记3-活动Activity(1)

    1.活动-一种可以包含用户界面的组件,用于和用户进行交互. <Button android:id="@+id/button_1" android:layout_width=& ...

  10. js处理数学经典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一 对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...