迷宫(回溯,递归)
来源:互联网 发布:上海赤森网络 编辑:程序博客网 时间:2024/06/04 17:56
回溯法
基本思想:对一个包括有很多个结点,每个结点有若干个搜索分支的问题,把原问题分解为多若干个子问题求解的算法;当搜索到某个结点发现无法再继续搜索下去时,就让搜索过程回溯(回退)到该节点的前一个结点,继续搜索该节点外的其他尚未搜索的分支;如果发现该结点无法再搜索下去,就让搜索过程回溯到这个结点的前一结点继续这样的搜索过程;这样的搜索过程一致进行到搜索到问题的解或者搜索完了全部可搜索分子没有解存在为止。
#include <iostream>#include <stack>using namespace std;#define MAX_ROW 10#define MAX_COL 10struct Seat{ int x; int y;};class Maze{public: Maze(int array[MAX_ROW][MAX_COL]) { for(int i = 0; i < MAX_ROW; i++) { for(int j = 0; j <MAX_COL; j++) { map[i][j] = array[i][j]; } } } bool IsPass(const Seat& s) { if((s.x >= 0 && s.x < MAX_ROW) && (s.y >= 0 && s.y < MAX_COL)) return 1 == map[s.x][s.y]; return 0; } void PassMaze(stack<Seat>& s, Seat& next) { s.push(next); map[next.x][next.y] = 2; while(!s.empty()) { if(s.top().x == 0 || s.top().x == MAX_ROW || s.top().y == 0 || s.top().y == MAX_ROW) { cout<<"找到出口"<<endl; return; } next = s.top(); Seat up = {next.x-1, next.y}; Seat left = {next.x, next.y-1}; Seat right = {next.x, next.y+1}; Seat down = {next.x+1, next.y}; if(IsPass(up)) { s.push(up); map[up.x][up.y] = 2; continue; } if(IsPass(left)) { s.push(left); map[left.x][left.y] = 2; continue; } if(IsPass(right)) { s.push(right); map[right.x][right.y] = 2; continue; } if(IsPass(down)) { s.push(down); map[down.x][down.y] = 2; continue; } map[next.x][next.y] = 3; s.pop(); next = s.top(); } cout<<"没有出口"<<endl; } void PrintMap() { for(int i = 0; i < MAX_ROW; i++) { for(int j = 0; j < MAX_COL; j++) { cout<<map[i][j]<<" "; } cout<<endl; } }private: int map[MAX_ROW][MAX_COL];};int main(){ int mapArr[MAX_ROW][MAX_COL] = { {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 0, 0} }; Seat entry = {9, 6}; stack<Seat> s; Maze m(mapArr); m.PassMaze(s, entry); m.PrintMap(); return 0;}
运行结果:(存在缺陷)
递归
#include <iostream>using namespace std;#define MAX_ROW 10#define MAX_COL 10struct Seat{ int x; int y;};class Maze{public: Maze(int array[MAX_ROW][MAX_COL]) { for(int i = 0; i < MAX_ROW; i++) { for(int j = 0; j <MAX_COL; j++) { map[i][j] = array[i][j]; } } } bool IsPass(const Seat& s) { if((s.x >= 0 && s.x < MAX_ROW) && (s.y >= 0 && s.y < MAX_COL)) return 1 == map[s.x][s.y]; return 0; } bool PassMaze(const Seat& s) { if(s.x >= MAX_ROW || s.x < 0 || s.y >= MAX_COL || s.y < 0) return true; if(IsPass(s)) { map[s.x][s.y] = 2; Seat up = {s.x-1, s.y}; Seat left = {s.x, s.y-1}; Seat right = {s.x, s.y+1}; Seat down = {s.x+1, s.y}; if(PassMaze(up)) { return true; } else if(PassMaze(left)) { return true; } else if(PassMaze(right)) { return true; } else if(PassMaze(down)) { return true; } else { map[s.x][s.y] = 3; } } return false; } void PrintMap() { for(int i = 0; i < MAX_ROW; i++) { for(int j = 0; j < MAX_COL; j++) { cout<<map[i][j]<<" "; } cout<<endl; } }private: int map[MAX_ROW][MAX_COL];};int main(){ int mapArr[MAX_ROW][MAX_COL] = { {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 0, 0} }; Seat s = {9, 6}; Maze m(mapArr); m.PassMaze(s); m.PrintMap(); return 0;}
运行结果:(这种求法和类似于回溯法找出口,根据你代码搜素方式只会找到一条出口,然后就会退出)
无返回值的递归求解
#include <iostream>using namespace std;#define MAX_ROW 10#define MAX_COL 10struct Seat{ int x; int y;};class Maze{public: Maze(int array[MAX_ROW][MAX_COL]) { for(int i = 0; i < MAX_ROW; i++) { for(int j = 0; j <MAX_COL; j++) { map[i][j] = array[i][j]; } } } bool IsPass(const Seat& s) { if((s.x >= 0 && s.x < MAX_ROW) && (s.y >= 0 && s.y < MAX_COL)) return 1 == map[s.x][s.y]; return 0; } void PassMaze(const Seat& s) { if(IsPass(s)) { map[s.x][s.y] = 2; Seat up = {s.x-1, s.y}; Seat left = {s.x, s.y-1}; Seat right = {s.x, s.y+1}; Seat down = {s.x+1, s.y}; if(IsPass(up)) { PassMaze(up); } if(IsPass(left)) { PassMaze(left); } if(IsPass(right)) { PassMaze(right); } if(IsPass(down)) { PassMaze(down); } } } void PrintMap() { for(int i = 0; i < MAX_ROW; i++) { for(int j = 0; j < MAX_COL; j++) { cout<<map[i][j]<<" "; } cout<<endl; } }private: int map[MAX_ROW][MAX_COL];};int main(){ int mapArr[MAX_ROW][MAX_COL] = { {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 1, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 0, 0} }; Seat s = {9, 6}; Maze m(mapArr); m.PassMaze(s); m.PrintMap(); return 0;}
运行结果:(这种无终止条件的递归直接粗暴,会遍历所有给出的路径。但在有多个出口的情况时,还是无法得出最优路径)
有待完善^_^
阅读全文
0 0
- 迷宫(回溯,递归)
- 小型迷宫实现---迷宫算法(递归回溯法)
- 回溯法解决迷宫问题(方法1---递归)
- 数据结构 迷宫的非递归实现(回溯法)
- 迷宫(回溯算法)
- 用回溯法递归实现迷宫
- 迷宫问题(深搜+回溯)
- 迷宫问题--非递归回溯 C语言实现
- 迷宫问题--非递归回溯 C语言实现
- 迷宫BFS+递归回溯找爹打印路径
- 走迷宫问题:回溯法和递归法
- 迷宫问题(递归)
- 【数据结构】迷宫(递归)
- (回溯法) 数据结构_回溯法求解迷宫路径
- 迷宫问题 (上)栈 回溯法
- 迷宫求解(C语言回溯法)
- poj 3984 迷宫问题(BFS+回溯)
- 走迷宫回溯算法(Java实现)
- tf.identity()的理解
- Python按照索引访问list
- HTML初学心得笔记2
- 机器学习:支持向量机(SVM)与Python实现第(二)篇
- Codeforce-126B:Password(KMP模板题)
- 迷宫(回溯,递归)
- 面试题
- 码云
- 1401 Factorial
- 数据库的优化策略
- 浅谈存在与信念
- Spring声明式事务管理(基于注解方式实现)
- hdu 6113 度度熊的01世界【搜索好题】
- 【LeetCode】005 Longest Palindromic Substring 最长的回文子字符串