zoukankan      html  css  js  c++  java
  • 回溯法之迷宫问题

    参考: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,待修复。

  • 相关阅读:
    linux运维、架构之路-MySQL备份与恢复(四)
    linux运维、架构之路-MHA高可用方案
    Tensorflow环境安装
    Sublime Text3 旧版本下载以及破解激活方式
    《SDN期末作业——实现负载均衡》
    SDN第六次上机作业
    自定义Toast的出现样式
    SDN第五次上机作业
    SDN第4次上机作业
    Context与ApplicationContext的区别
  • 原文地址:https://www.cnblogs.com/fistao/p/3117099.html
Copyright © 2011-2022 走看看