回溯法之迷宫问题

参考:http://www.cnblogs.com/hustcat/archive/2008/04/09/1144645.html

方法:(回溯法)

1、总结问题解决问题的思想。

2、总结具体的算法流程和典型问题解决思路。

3、编程实现具体实例。

将这个方法推广到其他算法上,快速高效的掌握算法思想。

回溯法一种系统的搜索问题解答的办法。

1、思想:碰壁返回

2、算法流程:首先定义一个解空间,这个解空间必须至少包含问题的一个解。其次需要组织解空间使它容易被搜索,典型的组织方法是图或者二叉搜索树。最后按深度优先搜索的方法从开始结点开始搜索。

在搜索的任意时刻,只保存开始结点到当前结点的路径。

3、具体实例(迷宫问题)

// Maze.cpp : 定义控制台应用程序的入口点。

//



#include "stdafx.h"

#include<stack>

#include<iostream>

using namespace std;



#define MazeNum 10







//通道块坐标结点

struct PosType

{

	int x;		//横坐标

	int y;		//纵坐标

};

//入栈结点类型

struct SElemType

{

	int ord;	//通道块在路径上的序号

	PosType seat;	//通道块在迷宫中的坐标位置

	int di;		//从此通道块走向下一个通道的方向

};



//路径全局变量

PosType path[64];



int _tmain(int argc, _TCHAR* argv[])

{

	cout<<"----------------回溯法求解迷宫问题----------"<<endl;

	int maze[MazeNum][MazeNum]=		//迷宫方阵 入口:(1,1) 出口:(8,8)

	{

		{1,1,1,1,1,1,1,1,1,1},//0

		{1,0,0,1,0,0,0,1,0,1},//1

		{1,0,0,1,0,0,0,1,0,1},//2

		{1,0,0,0,0,1,1,0,0,1},//3

		{1,0,1,1,1,0,0,0,0,1},//4

		{1,0,0,0,1,0,0,0,0,1},//5

		{1,0,1,0,0,0,1,0,0,1},//6

		{1,0,1,1,1,0,1,1,0,1},//7

		{1,1,0,0,0,0,0,0,0,1},//8

		{1,1,1,1,1,1,1,1,1,1} //9

	};

	//初始化路径数组

	for(int i=0;i<64;i++)

	{

		path[i].x=0;

		path[i].y=0;

	}



	PosType start,end;

	start.x=1;

	start.y=1;

	end.x=8;

	end.y=8;

	PosType NextPosition(PosType curpos,int di);

	bool Maze(int maze[MazeNum][MazeNum],PosType start,PosType end);

	void PrintPath();

	

	//如果该迷宫可以通行,则打印路径

	if(Maze(maze,start,end))

	{

		PrintPath();

	}

	else

	{

		cout<<"从起点到终点木有路径可达"<<endl;

	}



	return 0;

}//main



//选择当前位置的下一个位置:1:东 2:南 3:西 4:北

PosType NextPosition(PosType curpos,int di)

{

	PosType nextpos;

	switch (di)

	{

	case 1:		//东

		nextpos.x=curpos.x+1;

		nextpos.y=curpos.y;

		return nextpos;

		break;

	case 2:		//南

		nextpos.x=curpos.x;

		nextpos.y=curpos.y+1;

		return nextpos;

		break;

	case 3:		//西

		nextpos.x=curpos.x-1;

		nextpos.y=curpos.y;

		return nextpos;

		break;

	case 4:		//北

		nextpos.x=curpos.x;

		nextpos.y=curpos.y-1;

		return nextpos;

	default:

		break;

	}

}//NextPosition









//迷宫算法

bool Maze(int maze[MazeNum][MazeNum],PosType start,PosType end)

{

	PosType cur_postion=start;	//设定当前位置为入口位置

	int curstep=0;				//探索第一步

	stack<SElemType> m_stack;	//初始化栈

	SElemType setType;

	do

	{

		//如果当前位置可以通过

		if (maze[cur_postion.x][cur_postion.y]==0)

		{

			setType.ord=curstep;

			setType.seat=cur_postion;

			setType.di=1;

			

			//记录该路径

			path[curstep]=cur_postion;



			m_stack.push(setType);	//入栈



			//如果当前位置等于终点,则结束,否则切换到当前位置的东邻方向

			if(cur_postion.x==end.x && cur_postion.y==end.y)return true;

			

			cur_postion=NextPosition(cur_postion,1);	//切换到下一个位置

			curstep++;		//当前路径长度加1

			

		}

		//如果当前位置不能通过,则回溯

		else

		{

			//当前栈不为空,且有其他方向没有探索

			if(!m_stack.empty())

			{

				

				setType=m_stack.top();		//访问栈顶元素

				cur_postion=setType.seat;	//返回上一个位置

				m_stack.pop();				//删除栈顶元素



				while(setType.di==4 && !m_stack.empty())

				{

				//	m_stack.pop();	//如果某个路径的其他路径都不通,只能后退一步

				}//while

				if(setType.di<4)			//还有其他方向未被探索

				{

					setType.di++;			//切换到下一个方向

					cur_postion	=NextPosition(cur_postion,setType.di);

						

				}



			}



		}



	} while (!m_stack.empty());

	return false;

}//Maze



//打印路径

void PrintPath()

{

	int i=0;

	while(path[i].x!=0 && path[i].y!=0)

	{

		cout<<"("<<path[i].x<<","<<path[i].y<<")"<<"-->";

		i++;

		if(i%4==0)

			cout<<endl;

	}

	cout<<endl;

}//PrintPath

声明:此程序中存在一点小bug,待修复。

 

你可能感兴趣的:(问题)