回溯法求迷宫问题

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
本文使用回溯法求解迷宫问题
迷宫问题,有一个m行n列的矩阵代表迷宫,1代表此路不通,0代表此路通。指定入口和出口,判断是否能从入口进,从出口走出。此程序只判断从路口到出口是否能走通,找到的路不一定是最短路(最短路的程序在下一篇中使用BFS算法给出),注意:从入口到出口可能没有路径或者不止一条路径。此处迷宫走法是8个方向,分别是左上,上,右上,右,右下,下,左下,左。程序中使用offsets myMove给出八个方向的表示。
include <iostream>
#include <stack>
using namespace std;

struct offsets
{
 int a,b;//a,b是x,y方向的偏移
 char* dir;//dir方向
};
offsets myMove[8] = {//各个方向的偏移表
 {-1,0,"N"},
 {-1,1,"NE"},
 {0,1,"E"},
 {1,1,"SE"},
 {1,0,"S"},
 {1,-1,"SW"},
 {0,-1,"W"},
 {-1,0-1,"NW"}
 
};
struct items
{
 int x,y,dir;//位置和前进方向的序号
};
const int MAXNUM = 5;
int mark[MAXNUM][MAXNUM] = {0};//标记数组
int Maze[MAXNUM][MAXNUM] = {
 1,1,1,1,1,
 1,0,1,0,1,
 1,0,0,1,1,
 1,1,1,0,1,
 1,1,1,1,1
}; //迷宫

void printPath(stack<items>& st)
{
 int num = st.size();
 for (int index = 0; index < num; index++)
 {
  items tmpIt = st.top();
  cout<<"("<<tmpIt.x<<","<<tmpIt.y<<","<<tmpIt.dir<<")"<<"<-";
  st.pop();
 }
 cout<<endl;
}
void Mypath(int m,int p)
{
 int flag = 0;
 int Currx,Curry,Currd,Searchx,Searchy;
 mark[1][1] = 1;//(1,1)是入口
 stack<items> st;
 items tmp;
 tmp.x = 1,tmp.y = 1,tmp.dir = 2;
 st.push(tmp);
 while (! st.empty())
 {
  if (flag == 1)
  {
   st.pop();
  }
  flag = 0;
  items tmpItems = st.top();
  Currx = tmpItems.x,Curry = tmpItems.y,Currd = tmpItems.dir;
  while (Currd < 8)
  {
   Searchx = Currx + myMove[Currd].a,Searchy = Curry + myMove[Currd].b;
   
   if (Maze[Searchx][Searchy] == 0 && mark[Searchx][Searchy] == 0)
   {
    flag = 1;
    mark[Searchx][Searchy] = 1;
    tmp.x = Searchx,tmp.y = Searchy,tmp.dir = Currd;
    st.push(tmp);
    Currx = Searchx;Curry = Searchy; Currd = 0;
   }
   else
   {
    Currd++;
   }
   if (Searchx == m && Searchy == p)
   {
    cout<<m<<" "<<p<<endl;
    cout<<"("<<m<<","<<p<<","<<Currd<<")"<<"<-";
    printPath(st);

return;
   }
   
   
  }
  
 }
 cout<<"no path in Maze"<<endl;
}

int main()
{
 Mypath(2,1);
}

时间: 2024-10-07 05:30:11

回溯法求迷宫问题的相关文章

回溯法 求集合全排列、子集

全排列: 全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个. 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而得到所有元素的全排列. 以对字符串abc进行全排列为例,我们可以这么做:以abc为例固定a,求后面bc的排列:abc,acb,求好后,a和b交换,得到bac固定b,求后面ac的排列:bac,bca,求好后,c放到第一位置,得到cba固定c,求后面ba的排列:cba,cab. 这个思想和回溯法比较吻合. 代码可如下编

回溯法解决迷宫问题

现在有迷宫地图:(回溯法) 1 1 1 1 1 1 1 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 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 将迷宫地图存于文件中,将文件里的信息依次读入到二维数组中,设置入口,先将

算法学习之【回溯法】--迷宫问题

题目描述 定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线.入口点为[0,0],即第一空格是可以走的路. Input 一个N 

回溯法求装载问题

1.回溯法 (1)描述:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法.  (2)原理: 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解.如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯:否则,进入该子树,继续按深度优先策略搜索. 回溯法的基本做法是搜索,或是一种组织得井井有条的,

回溯法找迷宫最短路径

有一个二维数组,0表示路,-1表示墙,求其中任意两点的最短路径 我们先看,怎么求一条路径:求两点路径是一个数据结构上的典型的迷宫问题,解决办法如下: 从一点开始出发,向四个方向查找(上,右,下,左),每走一步,把走过的点的值+1,防止重复行走,并把走过的点压入堆栈(表示路径),如果遇到墙.或者已走过的点则不能前进,如果前方已经无路可走,则返回,路径退栈,这样递归调用,直到找到终点为止. 如果我们调整查找的顺序,改为左.右.上.下,可能会得到更短的路径,但这种方法不能保证一定是最短路径. 经过网上

用回溯法走迷宫,较简易代码

这应该算是第一份回溯写迷宫的代码,寒假写的时候出了点小毛病一直显示找不到路径,连续几天都没有思绪,后面来学校在学霸的帮助下发现了原因 在main函数里定义了offset数组,在外面又同时定义了一个数组,结果在seekpath函数里面调用的是外面定义的那个,外面定义的没赋值..结果就一直.. #include<iostream> #include<cstdio> using namespace std ; const int m = 4 , p = 4 ; struct offset

C++回溯法走迷宫

#include <iostream> #include <iomanip> #include <cstdlib> using namespace std; #define MaxSize 100 int maze[10][10] = //定义一个迷宫,0表示通道,1表示墙 { {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,1,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,

递归回溯法求N皇后问题

问题描述:在一个NN(比如44)的方格中,在每一列中放置一个皇后,要求放置的皇后不在同一行,同一列,同一斜线上,求一共有多少种放置方法,输出放置的数组. 思路解析:从(1,1)开始,一列一列的放置皇后,第一列放置在(1,1).第二列(1,2)不行,(2,2)不行,(2,3)可以,自此第2列放置完成.第三列依次判断. 可以看到对于第j列都要从第一行开始判断(1,j),(2,j),(3,j)...(N,j).如果有一个满足则暂停该列,向后判断下一列,(1,j+1),(2,j+1),(3,j+1)..

回溯法求n的阶乘

代码如下: #include <iostream> #include <algorithm> #include <stdio.h> #include <cstring> #include <cmath> #include <map> #include <bitset> using namespace std; typedef long long LL; int x[105]; int n; void Backtrack(i