回溯算法解决迷宫问题

回溯算法:

所谓“回溯”,其实就是回退、倒退的意思,利用回溯算法来查找正确答案,一旦不是正确答案的话就会直接进行“回溯”。以图中的A--->K的路径,

回溯算法查找从 A 到 K 路线的过程是:

  • 从 A 出发,先选择 A-B 路线;继续从 B 出发,先选择 B-C 路线;到达 C 点后发现无路可选,表明当前路线无法达到 K 点,该算法会立刻回退到上一个节点,也就是 B 点;
  • 从 B 点出发,选择 B-D 路线,达到 D 点后发现无法到达 K 点,该算法再回退到 B 点;
  • 从 B 点出发已经没有新的线路可以选择,该算法再次回退到 A 点,选择新的 A-E 路线;
  • 继续以同样的方式测试 A-E-F-G、A-E-F-H、A-E-J-I 这 3 条线路后,最终找到 A-E-J-K 路线。

迷宫问题:

迷宫问题指的是:在给定区域内,找到一条甚至所有从某个位置到另一个位置的移动路线。就可以采用回溯算法解决,即从起点开始,采用不断“回溯”的方式逐一试探所有的移动路线,最终找到可以到达终点的路线。

 回溯算法解决迷宫问题思路:

1)首先,从起始位置开始,会有四个方向(上下左右四个方向),进行判断能否向着四个方向进行移动

2)然后选择一个方向进行移动,将行走过的位置记为“Y”,如果这个位置就是终点位置的话就表示找到了一条通向终点的路线(这样的话打印出来的就是Y就表示一条路线)。如果不是的话,那么此位置又会有四个方向可以选择移动,

3)如果四个方向都无法移动的话(将该位置标记为1),那么就回溯上一个位置,继续判断其他方向是否能有移动

4)重复2,3步,要么会找到终点的位置,要么会回溯到起点位置,表明所有位置都已经判断完毕了

在程序中我们运用不同的字符来表示迷宫中的不同区域,1表示可以行走的位置,0表示黑色墙壁障碍,这样的话迷宫就可以用矩阵来表示

1 0 1 1 1
1 1 1 0 1
1 0 0 1 1
1 0 0 1 0
1 0 0 1 1

 迷宫问题伪代码:
输入 maze[ROW][COL]   //输入迷宫地图,0 表示黑色区域,1 表示可行走区域
//(row,col) 表示起点,(outrow,outcol)表示终点
maze_puzzle(maze,row,col,outrow,outcol):
    //回溯过程中,行走的每一区域都设为 Y,表示已经进行了判断
    maze[row][col] <- 'Y'
    //如果行走至终点,表明有从起点到终点的路线
    if row == outrow && col == outcol:
        Print maze  // 输出行走路线
        return
    //判断是否可以向上移动
    if canMove(maze,row-1,col):
        maze_puzzle(maze,row-1,col,outrow,outcol)
    //判断是否可以向左移动
    if canMove(maze,row,col-1):
        maze_puzzle(maze,row,col-1,outrow,outcol)
    //判断是否可以向下移动
    if canmove(maze,row+1,col):
        maze_puzzle(maze,row+1,col,outrow,outcol)
    //判断是否可以向右移动
    if canmove(maze,row,col+1):
        maze_puzzle(maze,row,col+1,outrow,outcol)
迷宫代码实现: 
//迷宫问题,并不涉及最端路径问题
#include <stdio.h>
//typedef enum { false, true } bool;
#define ROW 5
#define COL 5
//设置一个5*5的二维矩阵
bool find = false;

//进行判断能否进行相应方向的移动
bool can_move(char maze[ROW][COL], int row, int col)
{
	//如果目标位于地图区域,同时不是障碍,且没有走过,则返回true,否则返回false
	return row >= 0 && row <= ROW - 1 && col >= 0 && col <= COL - 1 && 
    maze[row][col] != '0' && maze[row][col] != 'Y';
}

//进行打印最后的路径
void maze_print(char maze[ROW][COL])
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			printf("%c ", maze[i][j]);
		}
		printf("\n");
	}
}
//(row,col)表示开始位置,(outrow,outcol)表示中间位置
void maze_puzzle(char maze[ROW][COL], int row, int col, int outrow, int outcol)
{
	maze[row][col] = 'Y';
	//进行判断什么时候进行结束递归
	if (row == outrow && col == outcol)
	{
		find = true;
		printf("find the final point\n");
		maze_print(maze);
		return;
	}
	//查看能否向上移动
	if (can_move(maze, row-1, col))
	{
		maze_puzzle(maze,row-1,col,outrow,outcol);
		//如果行走不通的话就将该位置标记为1,然后回溯
		maze[row - 1][col] = '1';
	}
	//查看能否向右移动
	if (can_move(maze, row, col + 1))
	{
		maze_puzzle(maze,row,col +1,outrow,outcol);
		//行走不通就将该位置标记为1,然后回溯
		maze[row][col+1] = '1';
	}
	//查看能否向下移动
	if (can_move(maze, row + 1, col))
	{
		maze_puzzle(maze, row + 1, col, outrow, outcol);
		//行走不通的话就将该位置标记为1,然后回溯
		maze[row + 1][col] = '1';
	}
	//查看能否向左移动
	if (can_move(maze, row, col - 1))
	{
		maze_puzzle(maze, row, col - 1, outrow, outcol);
	}
	maze[row][col - 1] = '1';
}

int main()
{
	//设置好迷宫的数组,1表示可以行走的路径,0表示障碍
	char maze[ROW][COL] = { {1,0,1,1,1},
                            {1,1,1,0,1},
                            {1,0,0,1,1},
                            {1,0,0,1,0},
                            {1,0,0,1,1} };
	//进行判断路径
	maze_puzzle(maze, 0, 0, ROW - 1, COL - 1);
	if (find == false)
	{
		printf("can't find the way\n");
	}
	return 0;
}

执行结果:

 Y 0 Y Y Y
Y Y Y 0 Y
1 0 0 Y Y
1 0 0 Y 0
1 00 Y Y 

注意:此回溯算法解决迷宫问题并不涉及解决迷宫问题的最短路径问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇见陌生人了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值