Algorithm学习笔记 --- 迷宫问题

      版权声明:学习交流为主,未经博主同意禁止转载,禁止用于商用。          https://blog.csdn.net/u012965373/article/details/26376987        </div><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css"><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css"><div class="htmledit_views" id="content_views">

关于搜索我做了一个整理这里用到的是深度搜索还有回溯算法。

意思是按着一个方向找如果没有依次返回。

http://www.cnblogs.com/hustcat/archive/2008/04/09/1144645.html

这里有位大师的讲解不错!

计算机解迷宫时,通常用的是"试探和回溯"的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止,如果所有可能的通路都试探过,还是不能走到终点,那就说明该迷宫不存在从起点到终点的通道。

  1.从入口进入迷宫之后,不管在迷宫的哪一个位置上,都是先往东走,如果走得通就继续往东走,如果在某个位置上往东走不通的话,就依次试探往南、往西和往北方向,从一个走得通的方向继续往前直到出口为止;

  2.如果在某个位置上四个方向都走不通的话,就退回到前一个位置,换一个方向再试,如果这个位置已经没有方向可试了就再退一步,如果所有已经走过的位置的四个方向都试探过了,一直退到起始点都没有走通,那就说明这个迷宫根本不通;
   
   3.所谓"走不通"不单是指遇到"墙挡路",还有"已经走过的路不能重复走第二次",它包括"曾经走过而没有走通的路"。显然为了保证在任何位置上都能沿原路退回,需要用一个"后进先出"的结构即栈来保存从入口到当前位置的路径。并且在走出出口之后,栈中保存的正是一条从入口到出口的路径。

由此,求迷宫中一条路径的算法的基本思想是:
若当前位置"可通",则纳入"当前路径",并继续朝"下一位置"探索;若当前位置"不可通",则应顺着"来的方向"退回到"前一通道块",然后朝着除"来向"之外的其他方向继续探索;若该通道块的四周四个方块均"不可通",则应从"当前路径"上删除该通道块。

设定当前位置的初值为入口位置; 
  do{
    若当前位置可通, 
    则{
     将当前位置插入栈顶;       // 纳入路径 
     若该位置是出口位置,则算法结束; 
      // 此时栈中存放的是一条从入口位置到出口位置的路径
     否则切换当前位置的东邻方块为新的当前位置; 
     }
    否则
    {
    若栈不空且栈顶位置尚有其他方向未被探索, 
    则设定新的当前位置为: 沿顺时针方向旋转找到的栈顶位置的下一相邻块;
    若栈不空但栈顶位置的四周均不可通, 
    则{ 删去栈顶位置;         // 从路径中删去该通道块
      若栈不空,则重新测试新的栈顶位置, 
      直至找到一个可通的相邻块或出栈至栈空; 
     } 
   } 
} while (栈不空);


#include <cstdio>
#include <iostream>
#define WALL   0  //墙
#define CORRIDOR 1 //通道
#define PATH  9 //为路径上的一块
#define TRIED 2 //

#define ROW_NUM    7 //迷宫数组行数
#define COL_NUM   13 //列数

#define TRUE 1
#define FALSE 0
#define MAXSIZE 50
typedef struct 
{
    int row;
    int col;
}
PosType;

typedef struct 
{
    int ord;      //通道块在路径上的"序号"
    PosType seat; //通道块在迷宫中的坐标
    int di;       //当前通道块的方向
}
SElemType;
typedef struct 
{
    SElemType S[MAXSIZE];
    int top;
}
MazeType;
//迷宫
int grid[ROW_NUM][COL_NUM]={{1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1},
                            {1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1},
                            {1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1},
                            {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1},
                            {1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0},
                            {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}}
;
//当前位置是否可以通过
bool Valid(PosType pos)
{
    if(pos.row>=0&&pos.row<=ROW_NUM&&pos.col>=0&&pos.col<=COL_NUM&&grid[pos.row][pos.col]==CORRIDOR)
        return TRUE;
    else
        return FALSE;
}

void FootPrint(PosType pos)//留下足迹
{
    grid[pos.row][pos.col]=PATH;
}

void Undo(PosType pos) //留下不能通过的标识
{
    grid[pos.row][pos.col]=TRIED;
}

//当前位置的下一个位置
PosType NextPos(PosType cur,int di)
{
    PosType next;
    switch(di)
    {
    case 0: //东
        next.row=cur.row;
        next.col=cur.col+1;
        break;
    case 1: //南
        next.row=cur.row+1;
        next.col=cur.col;
        break;
    case 2:  //西
        next.row=cur.row;
        next.col=cur.col-1;
        break;
    case 3:  //北
        next.row=cur.row-1;
        next.col=cur.col;
        break;
    }

    return next;
}

//是否到达终点
bool Done(PosType cur,PosType end)
{
    if(cur.row==end.row&&cur.col==end.col)
        return TRUE;
    else
        return FALSE;
}

//寻找迷宫路径
bool MazePath(MazeType &path,PosType start,PosType end)
{
    SElemType e;
    path.top=-1;
    int step=1;
    PosType curpos=start;
    do
    {
        if(Valid(curpos))
        {
            FootPrint(curpos);
            e.ord=step;
            e.di=0;
            e.seat=curpos;
            path.S[++path.top]=e;
            if(Done(curpos,end))
                return TRUE;
            curpos=NextPos(curpos,0);
            step++;
        }

        else
        {
            if(path.top>-1)//棧不空
            {
                e=path.S[path.top--];
                while(e.di==3&&path.top>-1)
                {
                    Undo(e.seat);
                    e=path.S[path.top--];
                }

                if(e.di<3)
                {
                    e.di++;
                    path.S[++path.top]=e;
                    curpos=NextPos(e.seat,e.di);
                }

            }
//if
        }
//else
    }
while(path.top>-1);
    return FALSE;
}

//输出路径
void PrintPath(MazeType path)
{
    int i=0;
    while(i<=path.top)
    {
        printf("第%d步:(%d,%d)\n",path.S[i].ord,path.S[i].seat.row,path.S[i].seat.col);
        i++;
    }

}

//输出路径
void PrintPath2()
{
    for(int i=0;i<ROW_NUM;i++)
        for(int j=0;j<COL_NUM;j++)
        if(grid[i][j]==PATH)
            printf("(%d,%d)\n",i,j);
}

int main()
{
    MazeType path;
    PosType start={0,0},end={6,12};
    if(MazePath(path,start,end))
        PrintPath(path);
    else
        printf("not reachable!\n");

    PrintPath2();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css资源网站收集推荐

非原创&#xff0c;来源网络。感谢原作者奉献如此精彩文章。原文地址&#xff1a;http://www.jianbitou.com/post/20_websites-learn-master-css.html1. A List Apart CSS Topics A List Apart是一个CSS优秀文章的收集网站&#xff0c;从1999年开始收集文章&#xff0c;关注最佳…

IP地址、子网掩码、网络号、主机号、网络地址、主机地址以及ip段/数字-如192.168.0.1/24是什么意思?

背景知识 IP地址 IP地址被用来给Internet上的电脑一个编号。大家日常见到的情况是每台联网的PC上都需要有IP地址&#xff0c;才能正常通信。我们可以把“个人电脑”比作“一台电话”&#xff0c;那么“IP地址”就相当于“电话号码”&#xff0c;而Internet中的路由器&#xff0…

思科CCNA第一学期期末考试答案

1 第 3 层头部包含的哪一项信息可帮助数据传输&#xff1f; 端口号 设备物理地址 目的主机逻辑地址 虚拟连接标识符 2 IP 依靠 OSI 哪一层的协议来确定数据包是否已丢失并请求重传&#xff1f; 应用层 表示层 会话层 传输层 3 请参见图示…

思科CCNA第二学期期末考试答案

1.关于数据包通过路由器传输时的封装和解封的叙述&#xff0c;下列哪三项是正确的&#xff1f;&#xff08;选择三项。&#xff09; 路由器修改 TTL 字段&#xff0c;将其值减 1。 路由器将源 IP 更改为送出接口的 IP。 路由器保持相同的源 IP 和目的 IP。 路…

关于xrdp的安装设置

参考链接http://linuxfan-linuxtips.blogspot.com/2010/03/get-xrdp-to-work-in-ubuntu.htmlhttp://chip.twbbs.org/blog/?p658http://www.mexlinux.com/how-to-install-xrdp-in-ubuntu/首先&#xff0c;你必须remove vnc4server&#xff0c;这个东西和这个软件有冲突sudo apt…

35-46集 中心极限定理、置信区间

第三十五集 中心极限定律   该定律是说随着样本n越来越大&#xff0c;这n个样本的m个均值会趋于正态分布。与大数定律的区别在于&#xff1a;大数定律描述的样本均值趋于总体均值&#xff0c;而中心极限定律描述的是样本均值的分布。 第三十六、七集 样本均值的抽样分布   …

AS3自制按钮通用代码

系统提供按钮不大适合现在的很多实用&#xff0c;很多都是MC做的&#xff0c;很多情况要些很多代码…… 代码 stop();addEventListener(MouseEvent.MOUSE_OVER,MouseOver);addEventListener(MouseEvent.MOUSE_UP,MouseOver);addEventListener(MouseEvent.MOUSE_DOWN,MouseDown)…

统计学(可汗学院视频62-81集笔记)

资料链接 本次统计学学习以网易云可汗学院公开课为主&#xff1a; 视频链接&#xff1a;http://open.163.com/special/Khan/khstatistics.html 并以《深入浅出统计学》为辅&#xff1a; 书籍链接&#xff1a;https://pan.baidu.com/s/1dCV6rrOWZU-deKxAoectGA </div…

可汗学院统计学笔记 42-81集

假设检验 假设检验是推论统计中用于检验统计假设的一种方法。而“统计假设”是可通过观察一组随机变量的模型进行检验的科学假说。一旦能估计未知参数&#xff0c;就会希望根据结果对未知的真正参数值做出适当的推论。统计上对参数的假设&#xff0c;就是对一个或多个参数的论述…

再谈js拖拽(一)

关于js拖拽早已是老生常谈&#xff0c;网上一搜一大坨&#xff0c;但是有很多并不是很完善&#xff0c;或者兼容性不够&#xff0c;或者功能不全&#xff0c;并且这样的东西还是自己写的好用。我打算在&#xff08;一&#xff09;中主要对js拖拽功能的注意点进行罗列&#xff0…

操作系统进程调度算法图解(FCFS、轮转、SPN、SRT、HRRN、反馈)

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/woshiwanghao_hi/article/details/13004507 FCFS: 先来先服务&#xff0c;也可以称为先进先出 轮转…

安装Ubuntu之后一定要安装Docky

2019独角兽企业重金招聘Python工程师标准>>> 安装Ubuntu之后一定要安装Docky&#xff0c;然后把面板隐藏&#xff0c;真是太漂亮了&#xff01; 图片太大&#xff0c;传不上来&#xff0c;传到百度上&#xff0c;又不让引用&#xff0c;还是百度看吧&#xff1a; 我…

操作系统中调度算法(FCFS、RR、SPN、SRT、HRRN)

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/xieminyao123/article/details/79116985 决策模式 决策模式说明选择函数在执行的瞬间的处理方式&a…

操作系统学习总结(超赞!!!)

我是技术搬运工,好东西当然要和大家分享啦.原文地址 操作系统基本特征 1. 并发 并发性是指宏观上在一段时间内能同时运行多个程序&#xff0c;而并行性则指同一时刻能运行多个指令。 并行需要硬件支持&#xff0c;如多流水线或者多处理器。 操作系统通过引入进程和线程&#xf…

操作系统的SPOOLING技术

SPOOLING技术&#xff08;Simultaneous Peripheral Operating On Line) 同时联机外围操作技术&#xff0c;它是关于慢速字符设备如何与计算机主机进行数据交换的一种技术&#xff0c;通常又称假脱机技术。 在多道程序环境下&#xff0c;利用多道程序中的一道或者两道程序来模拟…

独立磁盘冗余阵列:RAID

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/fsx2550553488/article/details/79819164 RAID RAID&#xff1a;独立磁盘冗余阵列&#xff08;Redun…

task2 EDA数据分析

目标 了解&#xff0c;验证数据集 了解变量关系&#xff0c;与预测值之间关系 数据处理、特征工程 数据探索性分析 EDA探索性数据分析 通过EDA可实现: 1. 得到数据的直观表现 2. 发现潜在的结构 3. 提取重要的变量 4. 处理异常值 5. 检验统计假设 6. 建立初步…

task2 EDA探索性数据分析

1、赛题数据赛题以预测二手车的交易价格为任务&#xff0c;数据集报名后可见并可下载&#xff0c;该数据来自某交易平台的二手车交易记录&#xff0c;总数据量超过40w&#xff0c;包含31列变量信息&#xff0c;其中15列为匿名变量。为了保证比赛的公平性&#xff0c;将会从中抽…

2021-06-10

局部搜索算法是一种简单的贪心搜索算法&#xff0c;是解决最优化问题的一种启发式算法&#xff0c;该算法每次从当前解的临近解空间中根据启发函数选择一个最优解&#xff08;也不一定是最优解&#xff09;作为当前解&#xff0c;直到达到一个局部最优解。本文以求解八皇后问题…

.NET(C#) Internals: 以一个数组填充的例子初步了解.NET 4.0中的并行(二)

引言 随着CPU多核的普及&#xff0c;编程时充分利用这个特性越显重要。上篇首先用传统的嵌套循环进行数组填充&#xff0c;然后用.NET 4.0中的System.Threading.Tasks提供的Parallel Class来并行地进行填充&#xff0c;最后对比他们的性能。本文将深入分析Parallel Class并借机…