问题描述:实验心理学中的一个典型的问题,心理学家吧一只老鼠从一个无顶的大盒子的入口处赶进迷宫。迷宫设置很多隔壁,对前进方向形成了许多障碍,心理学家在迷宫的唯一出口处放置了一块奶酪,吸引老鼠仔迷宫中寻找通路以到达出口。
求解思想:回溯法是一种不断试探且及时纠正错误的搜索方法,下面的求解过程采用回溯法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达一个新点,否则试探下一个方向;若所有的方向均没有通路,则沿原路返回前一点,换下一个方向继续试探,直到所有可能的通路都搜索到,或找到一条通路,或无路可走又返回到入口点。这里可以用一个栈来实现,每走一步,将该位置压入栈中,若该点无路可走,则出栈返回上一位置。
需要解决的四个问题:
(1)表示迷宫的数据结构
设迷宫为m行n列,利用数组maze[m][n]来表示一个迷宫,maze[i][j]=0或1,其中0表示通路,1表示不通,2 表示已走过。迷宫该数组四边都为1,代表迷宫四周都是墙。这样就可以保证每个点都有8个方向可以试探。
入口为(1,1),出口为(6,8)
1,1,1,1,1,1,1,1,1,1
0,0,1,1,1,0,1,1,1,1
1,1,0,1,0,1,1,1,1,1
1,0,1,0,0,0,0,0,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,0,1,1,0,0,0,1
1,0,1,1,0,0,1,1,0,1
1,1,1,1,1,0,1,1,1,1
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<stack> #include<assert.h> #define N 10 #include<iostream> using namespace std; struct pos //坐标点 { int _row; //行 int _col; //列 }; void GetMaze(int* a, int n) //从文件中读取数据,存储在数组中 { assert(a); FILE* fout = fopen("E:\\比特科技编程\\数据结构\\迷宫实现\\maze.txt", "r"); assert(fout); for (int i = 0; i < n; i++) { for (int j = 0; j < n;) { char ch = fgetc(fout); if (ch == ‘1‘ || ch == ‘0‘) { a[i * n + j] = ch - ‘0‘; j++; } else { continue; } } } fclose(fout); } bool CheckisAccess(int *a, int n, const pos& next) //判断是否可以前进 { int row = next._row; int col = next._col; if (row >= 0 && row < n&&col >= 0 && col < n&&a[next._row*n + next._col] == 0) { return true; } else { return false; } } bool searchpath(int* a, int n, pos entry, stack<pos>& paths) { assert(a); paths.push(entry); while (!paths.empty()) //如果栈为空,就没找到出口 { pos cur = paths.top(); a[cur._row*n + cur._col] = 2; if (cur._row == n - 1 ||cur._col==n-1) { return true; } pos next = cur; next._row--;//向上搜索 if (CheckisAccess(a, n, next)) { cur = next; paths.push(cur); continue; } next = cur; next._col++;//向右搜索 if (CheckisAccess(a, n, next)) { cur = next; paths.push(cur); continue; } next = cur; next._row++;//向下搜索 if (CheckisAccess(a, n, next)) { cur = next; paths.push(cur); continue; } next = cur; next._col--;// 向左搜索 if (CheckisAccess(a, n, next)) { cur = next; paths.push(cur); continue; } // next = cur; paths.pop(); //如果没有出路,则出栈,原路返回 } return false; } void display(int* a, int n) //打印迷宫 { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << a[i*n + j] << " "; } cout << endl; } }
测试代码如下:
#include"MazeMap.h" #include<stdio.h> void test() { int a[N][N]; GetMaze((int*)a, N); stack<pos> paths; //定义栈 pos entry = { 2, 0 }; // 调用入口 cout << searchpath((int*)a, N, entry, paths) << endl; display((int*)a, N); } int main() { test(); system("pause"); return 0; }
本文出自 “零点时光” 博客,请务必保留此出处http://10741764.blog.51cto.com/10731764/1771950
原文地址:http://10741764.blog.51cto.com/10731764/1771950