首页 > 编程知识 正文

迷宫找出口数学题,回溯法的算法框架按照问题的解空间

时间:2023-05-03 08:53:59 阅读:135369 作者:4532

作者:老款果汁Steven

版权声明:版权归作者所有,商业转载请联系作者取得许可。 非商业转载请注明出处

首先,作为迷宫问题的一个解法,介绍了经典算法——回溯法。 以下是本文的正文内容,包括算法的概要、算法的应用(迷宫问题)、算法的流程、C代码的安装。

一.追溯法概述

回溯法是枚举法的一种,它可以找出所有或部分常见的算法并有效地避免枚举错误的解。 当发现某个解的方向不正确时,不是进一步,而是向上一层减少算法的执行时间。 俗称“如果不顺利,就改道去”。 其特点是在搜索中寻找问题的解,如果发现不满足条件,追溯,通过继续搜索其他路径来提高效率。

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

1 .问题说明

迷宫问题是回溯法的应用。 迷宫的问题是,假设代理人(人、动物或飞机)放在迷宫地图的入口,迷宫里有很多墙壁,大多数路径都被挡住了,无法前进。 代理可以通过遍历所有可能到达出口的路径到达出口。 主体走错路时需要记录错误的路径,在找到出口之前不要走重复的路径。 主体必须遵循以下三个原则:

一次只能走一帧; 如果路径堵塞,请下降直到找到另一个路径。 把走过的路记下来,不再走。 2 .解题思路

首先制作迷宫图。 例如,使用二维数组人工定义MAZE[row][col],MAZE[i][j]=1时表示有墙壁不能通过,MAZE[i][j]=0时表示可以执行,maze

图1初始迷宫图主体在迷宫中前进时,可以选择东南西北,即右下左上四个方向。 下图:

图2的方向图因情况而异,并不是所有的位置都能上下左右前进,只能去MAZE[i][j]=0的地方。 记录在链表中走过的位置并标记为2,将该位置的信息放入堆栈中,进行下一个方向的选择。 进入死胡同,如果没有到达终点,回到前一个分支点,选择另一个方向继续走。 每次添加新内容时,它都位于堆栈的顶部,因此堆栈顶部的指针指向的方格编号就是当前主体所在的位置。 像这样重复直到你走到迷宫的出口。

本文所述的迷宫只是一个简易版的迷宫,对于更复杂的迷宫问题,可以根据其思路进行扩展,也可以采用其他算法。

三.算法流程

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

算法的流程图如下。

图3求解回溯法迷宫问题-算法流程图4、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] //南方//出口x坐标const int ExitY=10; //出口y坐标struct list{int x,y; struct list *next; (; typedef struct list node; typedef node *链接; int maze [ 10 ] [ 12 ]={ 1,1,1,1,1,1,1,/迷宫1,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 linkpop(linkpath,int *x,int *y ); intchkexit(intx,int y,int ex,int ey ); 链接推送(link path,I

nt 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五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。