迷宫求解

求解迷宫是一件挺简单的事情,对于计算机而已,则需要按算法遍历直到找到解,有路口、有死胡同,所以这个过程和栈的进出过程一样。

若是需要最优解,则需要遍历所有路线找到路径最短的解。

下面是一些对于迷宫求解的算法,希望有用

1.建立一个mazemap。

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#pragma warning(disable :4996)
using namespace std;
#define M 10
#define N 10

struct Pos
{
	size_t _row;
	size_t _col;
};



void GetMaze(int maze[M][N])
{
	FILE* out = fopen("maze.txt", "r");
	assert(out);

	for (size_t i = 0; i < M; i++)
	{
		for (size_t j = 0; j < N; )
		{ 
			char ch = fgetc(out);
			if (ch == '0' || ch == '1')     //文件内的迷宫0表示可走1表示不能走 其他的是多余的
			{
				maze[i][j] = ch - '0';
				j++;
			}
		}
	}
}

 void PrintMaze(int maze[M][N])
{
	for (size_t i = 0; i < M; i++)
	{
		for (size_t j = 0; j < N; j++)
		{
			printf("%3d",maze[i][j]);
		}
		cout << endl;
	}
}
      
      
     
     
    
    
   
   

2.首先可以用循环的方式(这里用上右下左的顺序遍历),直到找到一条出路后结束循环。

若是遇到死胡同则通过出站,回溯的方式退回,来继续寻找解法。

bool Step(int maze[M][N], Pos step)     //判断是否可以走
 {
	 if (step._row >= 0 && step._col >= 0
		 && step._row < M &&step._col < N
		 &&maze[step._row][step._col] == 0)
	 {
		 return true;
	 }
	 return false;
 }

 bool Path(int maze[M][N], Pos entry)  //试探—回溯的方法循环求出迷宫的解
 {
	 stack
   
   
    
     path;
	 path.push(entry);
	 while (!path.empty())
	 {
		 Pos cur = path.top();
		 maze[cur._row][cur._col] = 2;
		 Pos next = cur;
		 if (cur._row == N - 1)   //判断此处是否为出口
		 {
			 return true;
		 }


		 //向上方试探
		 next._row--;
		 if (Step(maze, next))
		 {
			 path.push(next);
			 continue;
		 }
		 next = cur;
		 //向右试探
		 next._col++;
		 if (Step(maze, next))
		 {
			 path.push(next);
			 continue;
		 }
		 next = cur;
		 //向下试探
		 next._row++;
		 if (Step(maze, next))
		 {
			 path.push(next);
			 continue;
		 }
		 next = cur;
		 //向左试探
		 next._col--;
		 if (Step(maze, next))
		 {
			 path.push(next);
			 continue;
		 }
		 next = cur;

		 maze[cur._row][cur._col] = 3;
		 path.pop();
	 }
	 return false;
 }
   
   
这里也可以用递归的方式来遍历出一条路径。

测试:

3.对于最优解便一定要要遍历所有路径,而且以上的走过的路标记为2,回退的路标记为3已经满足不了需求所以,可以用每向前走一步就
+1的方式来进行,而且多一个可以向已经走过但是更大的数字移动。这样不会少遍历而忽略了更小的路径。
然后每次一旦找到一条通路便与上一条最短路径比较,若更短则更新。

bool ShortStep(int maze[M][N],Pos next, Pos cur)  //判断可以可以走
 {
	 if (next._row >= 0 && next._col >= 0
		 && next._row < M &&next._col < N
		 && (maze[next._row][next._col] == 0 || maze[next._row][next._col]>maze[cur._row][cur._col]))
		 {
			 return true;
		}
		return false;
 }

 void ShortPath(int maze[M][N], Pos cur, stack
   
   
    
    & path, stack
    
    
     
     & shortpath)
 {
	 path.push(cur);
	 if (cur._row == N - 1)   //判断此处是否为出口
	 {
		 if (shortpath.empty()||path.size() < shortpath.size())
		 {
			 shortpath = path;

		 }
	 }

	 //向上试探
	 static Pos next;
	 next = cur;
	 next._row --;
	 if (ShortStep(maze, next, cur))
	 {
		 maze[next._row][next._col] = maze[cur._row][cur._col] + 1;  //每次试探都在原来基础上+1
		 ShortPath(maze, next, path, shortpath);

	 }
	 //向右试探
	 next = cur;
	 next._col ++;
	 if (ShortStep(maze, next, cur))
	 {
		 maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
		 ShortPath(maze, next, path, shortpath);

	 }
	 //向下试探
	 next = cur;
	 next._row ++;
	 if (ShortStep(maze, next, cur))
	 {
		 maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
		 ShortPath(maze, next, path, shortpath);
	
	 }
	 //向左试探
	 next = cur;
	 next._col --;
	 if (ShortStep(maze, next, cur))
	 {
		 maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
		 ShortPath(maze, next, path, shortpath);
	
	 }
	 path.pop();

 }

    
    
   
   

测试:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值