迷宫寻径--试探回溯法
空间区域限定为由n* n个方格组成的迷宫,除了四周的围墙,还有分布其间的若干障碍物;只能水平或垂直移动。我们的任务是,在任意指定的起始格点与目标格点之间,找出一条通路(如果的确存在)。
1 #pragma once 2 #define LABY_MAX 24 //最大迷宫尺寸 3 typedef enum 4 { 5 AVAILABLE, //原始可用 6 ROUTE, //当前路径上的 7 BACKTRACKED, //所有方向均尝试失败后回溯过的 8 WALL //墙 9 }Status; //迷宫单元格状态 10 typedef enum 11 { 12 UNKNOWN, 13 EAST, 14 SOUTH, 15 WEST, 16 NORTH, 17 NO_WAY 18 }ESWN; 19 20 struct Cell 21 { 22 int x; 23 int y; 24 Status status; 25 ESWN incoming, outgoing; //进入走出方向 26 }; 27 28 inline ESWN nextESWN(ESWN eswn) { return ESWN(eswn + 1); } //依次转至下一邻接方向 29 30 inline Cell* neighbor(Cell* cell) { //查询当前位置的相邻格点 31 switch (cell->outgoing) { 32 case EAST: return cell + LABY_MAX; //向东 33 case SOUTH: return cell + 1; //向南 34 case WEST: return cell - LABY_MAX; //向西 35 case NORTH: return cell - 1; //向北 36 } 37 } 38 39 inline Cell* advance(Cell* cell) //从当前位置转入相邻格点 40 { 41 Cell* next; 42 switch (cell->outgoing) 43 { 44 case EAST: next = cell + LABY_MAX; next->incoming = WEST; break; //向东 45 case SOUTH: next = cell + 1; next->incoming = NORTH; break; //向南 46 case WEST: next = cell - LABY_MAX; next->incoming = EAST; break; //向西 47 case NORTH: next = cell - 1; next->incoming = SOUTH; break; //向北 48 default: 49 next = nullptr; 50 } 51 return next; 52 }
1 #include <random> 2 #include <stack> 3 #include "Cell.h" 4 using namespace std; 5 6 7 8 int labySize; 9 Cell* startCell; 10 Cell* goalCell; 11 Cell laby[LABY_MAX][LABY_MAX]; //迷宫 12 13 void randLaby(); 14 void displayLaby(); 15 void printLabyCell(Cell* elem); 16 bool labyrinth(Cell Laby[LABY_MAX][LABY_MAX], Cell* s, Cell* t); 17 18 int main() 19 { 20 randLaby(); 21 labyrinth(laby, startCell, goalCell) ? //启动算法 22 printf("\nRoute found\a\n") : 23 printf("\nNo route found\a\n"); 24 getchar(); 25 return 0; 26 } 27 28 bool labyrinth(Cell Laby[LABY_MAX][LABY_MAX], Cell* s, Cell* t)//迷宫寻径算法,在起点s和终点t之间寻找一条通路 29 { 30 if ((s->status != AVAILABLE) || (t->status != AVAILABLE)) return false; 31 stack<Cell*> path; //使用栈记录通路 32 s->incoming = UNKNOWN; s->status = ROUTE; 33 path.push(s); 34 do //从起点出发不断试探、回溯,直到抵达终点,或者穷尽所有可能 35 { 36 displayLaby(); 37 getchar(); 38 Cell* c = path.top(); 39 if (c == t) return true; //抵达终点 40 while (NO_WAY>(c->outgoing= nextESWN(c->outgoing))) 41 { 42 Cell* neighborCell = neighbor(c); 43 if (neighborCell->status == AVAILABLE) break;; 44 } 45 if (c->outgoing >= NO_WAY) 46 { 47 c->status = BACKTRACKED; 48 c = path.top(); path.pop(); //回溯一步 49 } 50 else //向前试探一步 51 { 52 c = advance(c); 53 path.push(c); 54 c->outgoing = UNKNOWN; 55 c->status = ROUTE; 56 } 57 } while (!path.empty()); 58 return false; 59 } 60 void randLaby() { //生成随机的迷宫 61 labySize = LABY_MAX / 2 + rand() % (LABY_MAX / 2); /*DSA*/printf("Using a laby of size %d ...\n", labySize); getchar(); 62 for (int i = 0; i < labySize; i++) 63 for (int j = 0; j < labySize; j++) { 64 laby[i][j].x = i; 65 laby[i][j].y = j; 66 laby[i][j].incoming = 67 laby[i][j].outgoing = UNKNOWN; 68 laby[i][j].status = WALL; //边界格点必须是墙 69 } 70 for (int i = 1; i < labySize - 1; i++) 71 for (int j = 1; j < labySize - 1; j++) 72 if (rand() % 4) laby[i][j].status = AVAILABLE; //75%的格点为空可用 73 startCell = &laby[rand() % (labySize - 2) + 1][rand() % (labySize - 2) + 1]; 74 goalCell = &laby[rand() % (labySize - 2) + 1][rand() % (labySize - 2) + 1]; 75 startCell->status = goalCell->status = AVAILABLE; //起始格点必须可用 76 } 77 /****************************************************************************************** 78 * 输出某一迷宫格的信息 79 ******************************************************************************************/ 80 void printLabyCell(Cell* elem) { 81 printf("%d -> (%d, %d) -> %d\n", 82 ((Cell*)elem)->incoming, 83 ((Cell*)elem)->x, 84 ((Cell*)elem)->y, 85 ((Cell*)elem)->outgoing); 86 } 87 88 /****************************************************************************************** 89 * 显示迷宫 90 ******************************************************************************************/ 91 void displayLaby() { //┘└┐┌│─ 92 static char* pattern[5][5] = { 93 "┼", "┼", "┼", "┼", "┼", 94 "┼", " ", "┌", "─", "└", 95 "┼", "┌", " ", "┐", "│", 96 "┼", "─", "┐", " ", "┘", 97 "┼", "└", "│", "┘", " " 98 }; 99 system("cls"); 100 printf(" "); 101 for (int j = 0; j < labySize; j++) 102 (j < 10) ? printf("%2X", j) : printf(" %c", 'A' - 10 + j); 103 printf("\n"); 104 for (int j = 0; j < labySize; j++) { 105 (j < 10) ? printf("%2X", j) : printf(" %c", 'A' - 10 + j); 106 for (int i = 0; i < labySize; i++) 107 if (goalCell == &laby[i][j]) 108 printf("﹩"); 109 else 110 switch (laby[i][j].status) { 111 case WALL: printf("█"); break; 112 case BACKTRACKED: printf("○"); break; 113 case AVAILABLE: printf(" "); break; 114 default: printf("%s", pattern[laby[i][j].outgoing][laby[i][j].incoming]); break; 115 } 116 printf("\n"); 117 }//for 118 }//displayLaby
转载于:https://www.cnblogs.com/larry-xia/p/10391673.html
迷宫寻径--试探回溯法相关推荐
- 栈(Stack)的应用—试探回溯法:八皇后问题、迷宫寻径
栈的应用 试探回溯法 1.八皇后问题 皇后类 struct Queen { //皇后类int x, y; //坐标Queen (int xx = 0, int yy = 0 ) : x(xx), y( ...
- 一、试探回溯法(N皇后问题)
一.试探回溯法概念 在介绍试探回溯法的概念之前,先简要介绍一个简短的古希腊神话故事,邪恶的半人半牛藏身于一个复杂的迷宫,很难找到它并杀死它,就是能成功杀死它怎么回来也是个难事.不过,在公主阿里阿德涅 ...
- 迷宫问题----经典回溯法解决
问题描述: 题目摘自尚硅谷,小球在红色范围内运动,从规定的位置按照一定的运动规则到达指定位置,即可完成迷宫. 算法思路: 因为地图和挡板需要我们自己设置,所以先填充地图,运用二维数组对地图进行填充,我 ...
- java迷宫类编程题_第十届蓝桥杯省赛java类B组 试题 E:迷宫 (动态规划之回溯法)...
问题描述 试题 E: 迷宫 [问题描述] 下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方. 010000 000100 001001 110000 迷宫的入口为 ...
- 基本算法-回溯法(迷宫问题)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 本文介绍一种经典算法--回溯法,可作为迷宫问题的一种解法,以下是本篇文章正文内容,包括算法 ...
- 迷宫寻径问题(数据结构4.4.3)
这里的迷宫寻径问题是针对邓公<数据结构>第四节的再学习的总结,刚开始学数据结构看到这里的时候确实有点看不太明白,现在整体学完后再回归学习一下. 这里的迷宫寻径过程仍然是基于试探回溯法的.其 ...
- 回溯法采用的搜索策略_五大常用算法之四:回溯法
1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径.回溯法是一种选优搜索法,按选优条件向 ...
- [回溯算法] 五大常用算法之回溯法
算法入门6:回溯法 一. 回溯法 – 深度优先搜素 1. 简单概述 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解 ...
- 五大常用算法之回溯法详解及经典例题
一. 回溯法 – 深度优先搜素 1. 简单概述 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解. 基本思 ...
最新文章
- Windows Mobile 6.0 SDK和中文模拟器下载
- 无向图的最小生成树(克鲁斯卡尔算法 Kruskal)
- kvm虚拟化框架结构层次梳理及图形化的使用
- 30岁二刷博士,17个月发6篇一作获顶会最佳!现实版人生重开模拟器
- 国内首个比特币勒索病毒制作者落网,但过程有点好笑...
- java数组编译后_Java中数组和集合的foreach操作编译后究竟是啥
- 当深度学习遇上量化交易——因子挖掘篇
- des加密算法python代码_python des加密算法代码(pydes模块加密)
- New UWP Community Toolkit - ImageEx
- 如何取得select结果数据集的前10条记录。postgresql
- 如何修改Myeclipse的JSP模板
- 本人从事软件技术开发也有多年,打算先尝试往外迈一步试试!
- stm32 matlab 滤波器,STM32实现IIR滤波器,可用matlab生成的头文件
- Mac分区失败导致出现隐藏分区的解决办法
- 为什么这么多人会选择单页设计?
- 相爱容易相守难,盘点那些摔倒在奔跑途中的创业公司
- excel表格打印每页都有表头_Excel打印时如何实现每一页纸上都有表头?
- 计算机设计大赛中南赛区2019通告,我院6支队伍在2019中国大学生计算机设计大赛 中南地区赛喜获佳绩...
- <论文阅读>用于 3D 点线和平面的视觉惯性里程计框架 A Visual Inertial Odometry Framework for 3D Points, Lines and Planes
- Oracle数据库之日期函数