回溯算法之迷宫问题

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SeqListSort
{
    /// <summary>
    /// <ather>
    /// <lihonglin>
    /// </ather>
    /// <content>
    /// 随机生成 Row 行* Col列的迷宫,0为可以通过,1为不可以通过,若可以通过显示出路径,不能通过则显示
    /// 出内容
    /// </content>
    /// </summary>
    public struct Point
    {
        public int x;
        public int y;
        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
    class MazePath
    {
        const int ROW = 10;
        const int COL = 10;//
        //static int[,] map = new int[ROW,COL];
        //测试
        static int[,] map = new int[,]
                        {{1,1,1,1,1,1,1,1,1,1},
                        {1,0,1,1,1,0,1,1,1,1},
                        {1,0,0,1,0,1,1,1,1,1},
                        {1,0,1,0,0,0,0,0,1,1},
                        {1,0,0,0,1,0,1,0,1,1},
                        {1,1,1,0,1,1,0,0,1,1},
                        {1,0,1,0,0,0,1,0,0,1},
                        {1,0,1,1,0,0,1,1,0,1},
                        {1,0,1,1,0,0,0,0,0,1},
                        {1,1,1,1,1,1,1,1,1,1}};//迷宫地图
        static Stack<Point> path = new Stack<Point>();//迷宫路径

        public static void InitMap()
        {
            Random r = new Random();
            for (int i = 0; i < ROW; ++i )
            {
                for (int j = 0; j < COL; ++j )
                {
                    if ( 1 == i && 1 == j )
                    {
                        map[i, j] = 0;// 定义入口
                        Console.Write("   *");
                    }
                    else if (i == ROW - 2 && j == COL - 2)
                    {
                        map[i, j] = 0;//定义出口
                        Console.Write("   #");
                    }
                    else if ((0 == i || 0 == j) || (i == ROW - 1 || j == COL - 1))
                    {
                        map[i, j] = 1;//绘制墙
                        Console.Write("   " + map[i, j]);
                    }
                    else
                    {
                        map[i, j] = r.Next(0, 2);// 0为可以通过,1为不可以
                        Console.Write("   " + map[i,j]);
                    }
                }
                Console.WriteLine( );
            }
        }

        public static void FindPaths()
        {
            int i = 1;
            int j = 1;

            path.Push(new Point(i, j));
            // 从右边开始按照顺时针开始查询
            while( path.Count > 0 )
            {
                // right
                if (0 == map[i, j + 1])
                {
                    map[i, ++j] = 2;
                    path.Push(new Point(i, j));
                }
                // bottom
                else if (0 == map[i + 1, j] )
                {
                    map[++i, j] = 2;
                    path.Push(new Point(i, j));
                }
                //left
                else if (0 == map[i, j - 1])
                {
                    map[i, j - 1] = 2;
                    path.Push(new Point(i, j - 1));
                    j--;
                }
                // top
                else if (0 == map[i - 1, j])
                {
                    map[i - 1, j] = 2;
                    path.Push(new Point(i - 1, j));
                    i--;
                }
                else
                {
                    //Point p = path.Peek();
                    path.Pop();
                    if (path.Count <= 0)
                    {
                        Console.WriteLine("没有路径");
                        break;
                    }
                }

                i = path.Peek().x;
                j = path.Peek().y;
                if ( i == ROW - 2 && j == COL - 2)
                {
                    Console.WriteLine("找到路径显示如下:");
                    break;
                }

            }

            for (i = 0; i < ROW ; ++i)
            {
                for (j = 0; j < COL ; ++j)
                {
                    if (1 == i && 1 == j)
                    {
                        Console.Write("   *");
                    }
                    else if (i == ROW - 2 && j == COL - 2)
                    {
                        Console.Write("   #");
                    }
                    else
                        Console.Write("   " + map[i,j]);
                }
                Console.WriteLine( );
            }
        }
    }
}
时间: 2024-10-17 06:25:35

回溯算法之迷宫问题的相关文章

回溯算法求解迷宫问题

package sort; public class HuiSu { public static void main(String args[]){ int data[][]={{1,1,1,1,1,1,1,1,1}, //10行9列的迷宫 {0,0,0,0,0,0,0,0,1}, {1,0,1,0,0,1,1,0,1}, {1,0,0,1,0,1,0,0,1}, {1,1,0,1,0,0,1,0,1}, {1,0,0,0,1,0,1,0,1}, {1,0,1,1,0,0,1,0,1}, {1,

从迷宫问题、连连看、红与黑说回溯算法遍历解空间

今天上午完成了“迷宫”问题,也思考了“2.5基本算法之搜索”的另外几个问题:小游戏(就一连连看),马走日,红与黑等.我所关注的这几个问题都可以用回溯算法来进行解决.回溯算法简单说就是当运行到叶子节点证明不是解时回到上一层节点继续遍历,如此循环直到找到一个解:如果需要全部解,可以继续遍历,如果不需要可以直接退出.很明显,回溯算法是一种深度优先的搜索算法,非常适合在解空间中找到一个解的问题. 一.迷宫问题: 1792:迷宫 总时间限制: 3000ms 内存限制: 65536kB 描述 一天Exten

C++使用回溯算法解决简单迷宫问题

给你一个矩阵,如何在其中找到一条通路呢? (是不是很凌乱?^_^) 在C++中怎么实现呢? 较好的解决方案:使用栈解决. 解决思路: 使用FILE*和open预先打开文件(绝对路径和相对路径1),注意断言. 正确读取文件,判断字符和空格,空格略过,读取字符. 从入口进入,每走一步,判断上下左右4个方向有无道路. 如果4个方向有路,则按次序先进入其中一条(将字符压栈push),并将所走过字符重置数字(后面回溯). 如果4个方向没有,则出栈pop,即回溯,并再次判断. 逐次循环,直至判断下一个有效节

C程序设计的抽象思维-回溯算法-迷宫问题

[迷宫问题] 两种方法:1. 堆栈回溯,2.递归回溯. [算法1---堆栈回溯] 计算机解迷宫时,通常用的是"试探和回溯"的方法,即从入口出发,顺某一方向向前探索,若能走通,则继续往前走:否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止,如果所有可能的通路都试探过,还是不能走到终点,那就说明该迷宫不存在从起点到终点的通道. 1.从入口进入迷宫之后,不管在迷宫的哪一个位置上,都是先往东走,如果走得通就继续往东走,如果在某个位置上往东走不通的话,就依次试探往南.往西和往

回溯法求迷宫问题

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”.本文使用回溯法求解迷宫问题迷宫问题,有一个m行n列的矩阵代表迷宫,1代表此路不通,0代表此路通.指定入口和出口,判断是否能从入口进,从出口走出.此程序只判断从路口到出口是否能走通,找到的路不一定是最短路(最短路的程序在下一篇中使用BFS算法给出),注意:从入口到

蚁群算法求解迷宫最优路径问题

本段程序的基本思想是利用蚁群算法中的蚁周模型,来对全局的迷宫图进行信息素的跟新 和为每一只蚂蚁选择下一个方格. 一共会进行RcMax = 2000轮模拟(理论上模拟的次数越多结果 会越接近真实值),而在每一轮中会排除 M = 10只蚂蚁进行探路.同时在算法的回溯思想上采用的 是栈的数据结构来实现的.当栈最终为空时则表示无解.但同时这段程序的一缺点就是:由于我没在 算法中对每一轮的每只探路蚂蚁采用多线程的模式,所以整体的运行效率还不是很高.如读者有好的 思想或建议,请留言. #include<io

穷举递归和回溯算法终结篇

穷举递归和回溯算法 在一般的递归函数中,如二分查找.反转文件等,在每个决策点只需要调用一个递归(比如在二分查找,在每个节点我们只需要选择递归左子树或者右子树),在这样的递归调用中,递归调用形成了一个线性结构,而算法的性能取决于调用函数的栈深度.比如对于反转文件,调用栈的深度等于文件的大小:再比如二分查找,递归深度为O(nlogn),这两类递归调用都非常高效. 现在考虑子集问题或者全排列问题,在每一个决策点我们不在只是选择一个分支进行递归调用,而是要尝试所有的分支进行递归调用.在每一个决策点有多种

回溯算法入门及经典案例剖析(初学者必备宝典)

前言 基于有需必写的原则,并且当前这个目录下的文章数量为0(都是因为我懒QAQ),作为开局第一篇文章,为初学者的入门文章,自然要把该说明的东西说明清楚,于是...我整理了如下这篇文章,作者水平有限,有不足之处还望大家多多指出~~~ 概念 首先,回溯是什么意思?很多初学者都会问这样的一个问题.我们可以举这样一个例子: 1 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 我们看到了如图所示的一个4*4的迷宫了,我们假设数字1标记的位置为道路,数字0标记的位置为一堵墙,一个人由起点(0.0

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr