作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

前言

本文介绍一种经典算法——回溯法,可作为迷宫问题的一种解法,以下是本篇文章正文内容,包括算法简介、算法应用(迷宫问题)、算法流程和C++代码实现。

一、回溯法简介

回溯法(Backtracking)是枚举法的一种,可以找出所有或者一部分的一般性算法,且有效避免枚举不对的解。当发现某个解的方向不准确时,就不再继续往下进行,而是回溯到上一层,减少算法运行时间,俗称“走不通就回头换路走”。特点是在搜索过程中寻找问题的解,一旦发现不满足条件便回溯,继续搜索其他路径,提高效率。

二、算法应用(迷宫问题)

1.问题描述

迷宫问题是回溯法的一种应用。迷宫问题的描述为:假设主体(人、动物或者飞行器)放在一个迷宫地图入口处,迷宫中有许多墙,使得大多数的路径都被挡住而无法行进。主体可以通过遍历所有可能到出口的路径来到达出口。当主体走错路时需要将走错的路径记录下来,避免下次走重复的路径,直到找到出口。主体需遵从如下三个原则:

  1. 一次步进只能走一格;
  2. 遇到路径堵塞后,退后直到找到另一条路径可行;
  3. 走过的路径记录下来,不会再走第二次。

2.解题思路

首先创建一个迷宫图,比如用二维数组人为定义MAZE[row][col],MAZE[i][j]=1时表示有墙无法通过,MAZE[i][j]=0时表示可行,假设MAZE[1][1]为入口,MAZE[8][10]为出口,创建如下初始迷宫图:

图1 初始迷宫图

当主体在迷宫中前行时,有东南西北(即右下左上)四个方向可以选择,如下图所示:

图2 方向示意图

视情况而定,并不是所有位置都可以上下左右前进,只能走MAZE[i][j]=0的地方。通过链表来记录走过的位置,并将其标记为2,把这个位置的信息放入堆栈,再进行下个方向的选择。若走到死胡同且未到达终点,则退回到上一个岔路口选择另一个方向继续走。由于每次新加入的位置处于堆栈的顶端,因此堆栈顶端指针所指向的方格编号便是当前主体所在的位置。如此重复直到走到迷宫出口为止。

本文提到的迷宫只是一个简易版的迷宫,对更复杂的迷宫问题,可基于该思路进行拓展或采取其他的算法。

三、算法流程

基于第二部分所讲的迷宫问题解题思路,其算法逻辑为:开始,输入初始入口位置;当前位置x和y均小于出口的x和y时,继续前进;判断东南西北可行的方向,并将步进的位置信息放入移动路径的堆栈中;检查是否到达出口;若路径堵塞,退后一步(即从堆栈中弹出一个位置)再检查是否有其他路径可走;当前位置x或y大于出口的x和y时,遍历结束,输出结果。

算法流程图如下:

图3 回溯法解迷宫问题-算法流程图

四、C++代码实现

#include < iostream >
// 二维数组中[x][y],x表示行,y表示列
#define EAST MAZE[x][y+1]   // 东方向
#define WEST MAZE[x][y-1]   // 西方向
#define SOUTH MAZE[x+1][y]  // 南方向
#define NORTH MAZE[x-1][y]  // 北方向
using namespace std;
const int ExitX = 8;        // 出口x坐标
const int ExitY = 10;       // 出口y坐标
struct list
{int x, y;struct list *next;
};
typedef struct list node;
typedef node* link;
int MAZE[10][12] = { 1,1,1,1,1,1,1,1,1,1,1,1,     // 定义迷宫1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1
};
link push(link path, int x, int y);
link pop(link path, int *x, int *y);
int chkExit(int x, int y, int ex, int ey);
link push(link path, int x, int y)
{link newnode;newnode = new node;if (!newnode){cout << "Error:内存分配失败!" << endl;return NULL;}newnode->x = x;newnode->y = y;newnode->next = path;path = newnode;return path;
}
link pop(link path, int *x, int *y)
{link top;if (path != NULL){top = path;path = path->next;*x = top->x;*y = top->y;delete top;return path;}else*x -= 1;return path;
}
int chkExit(int x, int y, int ex, int ey)
{if ((x == ex) && (y = ey)){if (NORTH == 1 || SOUTH == 1 || WEST == 1 || EAST == 2)return 1;if (NORTH == 1 || SOUTH == 1 || WEST == 2 || EAST == 1)return 1;if (NORTH == 1 || SOUTH == 2 || WEST == 1 || EAST == 1)return 1;if (NORTH == 2 || SOUTH == 1 || WEST == 1 || EAST == 1)return 1;}return 0;
}
int main(void)
{cout << endl << endl;int i, j;link path = NULL;int x = 1;        // 入口x坐标int y = 1;        // 入口y坐标cout << "   "<<"迷宫图(0的位置可走,1的位置为墙):\n" << endl;    // 显示地图for (i = 0; i < 10; i++){for (j = 0; j < 12; j++)cout << "   " << MAZE[i][j] << " ";cout << endl;}cout << endl << endl;// 开始走迷宫while (x <= ExitX && y <= ExitY){MAZE[x][y] = 2;if (NORTH == 0){x -= 1;path = push(path, x, y);}else if (SOUTH == 0){x += 1;path = push(path, x, y);}else if (WEST == 0){y -= 1;path = push(path, x, y);}else if (EAST == 0){y += 1;path = push(path, x, y);}else if (chkExit(x, y, ExitX, ExitY) == 1)break;else{MAZE[x][y] = 2;path = pop(path, &x, &y);}}cout << "迷宫完成图(0的位置未走,1的位置为墙,2的位置已走):\n" << endl;    // 显示地图for (i = 0; i < 10; i++){for (j = 0; j < 12; j++)cout << "   " << MAZE[i][j] << " ";cout << endl;}return 0;
}

效果图:

图4 效果图

五、拓展

在2019年“华为杯”第十六届中国研究生数学建模竞赛中,F题目名称是《多约束条件下智能飞行器航迹快速规划》,该问题类似于一个复杂的迷宫问题,有诸多约束条件限制,要求寻找一条符合约束条件的最优路径。当时我们队伍就是基于约束条件和迷宫算法的思维,设计了新式的迷宫算法,该算法简单来说就是:遍历所有可行的路径,在达到节点时进行判断,如果该节点到终点的直线距离加走过的路程已经小于之前找到过的可行最短路径距离,则该节点往后的路径不用走了直接pass,正因如此,算法的最优求解过程可以快速收敛,计算后期可能还没跑到一半就已经知道这条路径符不符合要求了。其他队伍进行计算有的高达数小时,而我们的算法只需要半分钟。

第三问是概率方面的做的不太好,再加上比赛后期通宵了一晚上精力不佳,录数据的时候犯了粗心错,只拿了国三有些可惜,原本6个答案对了5个,粗心写错了2个。。。

该建模论文资料分享给大家:建模-飞行器航迹最优规划.pdf-算法与数据结构文档类资源-CSDN下载

一起学习努力,加油。论文内含matlab代码,仅供参考,参数命名有些乱,望海涵。


总结

以上就是本文所讲的内容,简单介绍了回溯法以及该方法的一个实际应用——迷宫问题,包含了迷宫实例的解题逻辑和C++代码实现。

如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

基本算法-回溯法(迷宫问题)相关推荐

  1. 算法 --- 回溯法

    回溯法 参考 - 剑指Offer 回溯法可以看成蛮力法的升级版,它从解决问题每一步的所有可能选项里系统地选择出一个可行的解决方案. 回溯法解决的问题的特性: 可以形象地用树状结构表示: 节点: 算法中 ...

  2. java背包算法回溯法_【算法分析】实验 4. 回溯法求解0-1背包等问题

    [TOC] 实验内容 本实验要求基于算法设计与分析的一般过程(即待求解问题的描述.算法设计.算法描述.算法正确性证明.算法分析.算法实现与测试),通过回溯法的在实际问题求解实践中,加深理解其基本原理和 ...

  3. 算法---回溯法--模板解法

    回溯法问题:实际上就是一个决策树的遍历过程 分为三步: 路径:已做出选择的路径. 选择列表:当前可以做的选择 结束条件:就是到达决策树的底层,无法再做出选择的条件.(退出条件 ) template&l ...

  4. c语言实现全排列并存储,C语言实现全排列和回溯法总结

    一.递归实现全排列 #include"cstdio" int A[]; void print_permutation(int n,int *A,int cur){ if(cur== ...

  5. 回溯法解决tsp问题 matlab,回溯法求解tsp问题

    回溯法以这种工作方式递归地在解空间中搜索, 直至找到所 要求的解或解 空间中已无活结点时为止. 回溯法求解 TSP 问题,首先把所有的顶点的访问标志初始化为 0,...... 回溯法求解 TSP 问题 ...

  6. 算法分析与设计——回溯法实验报告

       算法导论  课程设计 成 绩 题    目:    回 溯 法 学院班级:        1613013         学    号:      16130130216       姓     ...

  7. android迷宫生成算法,【Unity算法实现】简单回溯法随机生成 Tile Based 迷宫

    算法学习自 作者eastecho 在IndieNova上发表的文章 简单的使用回溯法生成 Tile Based 迷宫 , 我只是简单做了一下Unity的实现. 基础算法的简单说明 简单说明一下算法步骤 ...

  8. 数据结构与算法(Python)– 回溯法(Backtracking algorithm)

    数据结构与算法(Python)– 回溯法(Backtracking algorithm) 1.回溯法 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条 ...

  9. php生成迷宫图片,PHP实现基于回溯法求解迷宫问题的方法详解

    本文实例讲述了PHP实现基于回溯法求解迷宫问题的方法.分享给大家供大家参考,具体如下: 引言 最近在leetcode上看了些算法题,有些看着很简单的很常用的东西,竟然一下子想不出来怎么求解,比如说:实 ...

最新文章

  1. 镜头上的四线电机怎么驱动_2相四线,四相五线,四相六线步进电机接线及驱动方法...
  2. spark学习(二)
  3. 数据结构C语言实现课后习题答案第6-9章
  4. Golang学习 - sync 包
  5. 中国数码相机镜头行业市场供需与战略研究报告
  6. 用条件变量实现事件等待器的正确与错误做法
  7. bootstrap.min.css和bootstrap.min.js以及bootstrap.bundle.min.js下载,jquery各版本下载
  8. PN结的形成及PN结工作原理(单向导电)讲解
  9. JavaScript基础教程之flag的用法
  10. ITRS/GCRS/J2000坐标系的相互转换
  11. 星际争霸2中文版下载 – 即时战略游戏超大作 (繁体含中文语音)
  12. 常用下载方式的区别-BT下载、磁力链接、电驴
  13. sencha 安装教程
  14. MD5与SHA加密算法
  15. 大数据时代 微软被迫接受开源
  16. 手机里tencent文件夹能删吗_手机上的文件夹能不能删?看完之后秒懂
  17. Maven 私服 Nexus 的部署及项目应用
  18. 微信小程序-批量地图标记
  19. 爪哇国新游记之二十一----快算24
  20. 我与今目标的爱恨情仇

热门文章

  1. 黑盒测试、白盒测试、灰盒测试区别与详细功能描述
  2. 颜色大全:颜色名称和颜色值。色板、色板对照表1
  3. Excel开发帮助文档查看方法
  4. tmall.item.simpleschema.add( 天猫简化发布商品 )
  5. 索尼入局汽车市场,新能源汽车将成主流
  6. cocos2d-x的初步学习七
  7. 各种异常产生原因及如何处理解决 --
  8. 腾讯云TDSQL监控库密码忘记问题解决实战
  9. 单词记忆系统二:音标字符输入(re从字符串中提取音标字符;依序打印音标字符;输入对应序号;替换序号。-> 完成“音标输入”)
  10. 火到服务器瘫痪了,这款小游戏太火爆了,合成大西瓜