宽度优先搜索-----解决迷宫最短路径问题

技术类电子书大放送:电子书

宽度优先搜索-----解决迷宫最短路径问题

一、关于宽度优先搜索的知识

1.深度优先搜索利用栈进行计算,因此一般场景中采用递归的方式实现。

2.宽度优先搜索则利用队列进行计算,搜索时首先将初始状态添加到队列里,此后从队列的最前端不断取出状态,

把从该状态可以转移到的状态中尚未访问过的部分加入队列,如此往复,直至队列被取空或者找到问题的解。

3.宽度优先搜索按照距开始状态由近及远的顺序搜索,因此可以很容易的用来求最短路径、最少操作之类问题的答案。

二、迷宫最短路径问题

​ 输出:22

三、算法分析与实现

1.如果到目的点存在多条路径,那么通过BFS肯定是最短的那条路径最先到达目的点。

2.使用一个二维数组来记录从开始点到每个点的距离。该二维数组被初始化为max_value,当值不等于max_value时,说明该点已经被其他更短路径上 ‘爬虫’ 遍历过,不能重复遍历。

    public class AlgorithmCenter200715
    {
        private char[,] _maze= {

            {'#','S','#','#','#','#','#','#','.','#' },
            {'.','.','.','.','.','.','#','.','.','#' },
            {'.','#','.','#','#','.','#','#','.','#' },
            {'.','#','.','.','.','.','.','.','.','.' },
            {'#','#','.','#','#','.','#','#','#','#' },
            {'.','.','.','.','#','.','.','.','.','#' },
            {'.','#','#','#','#','#','#','#','.','#' },
            {'.','.','.','.','#','.','.','.','.','.' },
            {'.','#','#','#','#','.','#','#','#','.' },
            {'.','.','.','.','#','.','.','.','G','#' }

        };
        private int _sx=0, _sy=1;//迷宫开始位置
        private int _ex=9, _ey=8;//迷宫终点位置
        private int _maxPath => int.MaxValue;
    
        //向四个方向移动矩阵
        private int[] _xMove = {0, 1,0,-1};
        private int[] _yMove = {-1, 0,1,0};


        /// <summary>
        /// 计算迷宫中从开始节点到某个结束节点的最小距离
        /// </summary>
        /// <returns></returns>
        public int CaluateMazeShortestPath()
        {
            int h = _maze.GetLength(0);
            int w = _maze.GetLength(1);

            //存储从开始位置到每个位置的举例
            int[,] path=new int[h,w];
            //初始化成最大值
            path.InitToSameValue(int.MaxValue);
            path[_sx, _sy] = 0;

            //用于实现BFS的队列
            Queue<Point> que = new Queue<Point>();

            //先将开始点坐标存入队列
            que.Enqueue(new Point(_sx,_sy));


            while (que.Count > 0)
            {
                var p = que.Dequeue();
                
                //如果发现已经到达目标点,那么不需要在遍历队列中的其他点,说明已经通过最短路径到达了这个点
                if (_maze[p.X, p.Y] == 'G')
                    break;

                //向四个方向移动
                for (int i = 0; i < 4; i++)
                {
                    int dx = p.X + _xMove[i];
                    int dy = p.Y + _yMove[i];

                    //当path[dx,dy]==int.MaxValue时说明该点还没有被遍历到
                    if (dx>=0&&dx<h&&dy>=0&&dy<w&&_maze[dx,dy]!='#'&&path[dx,dy]==int.MaxValue)
                    {
                        path[dx, dy] = path[p.X, p.Y] + 1;
                        que.Enqueue(new Point(dx,dy));
                    }
                }

            }
            return path[_ex,_ey];
        }


        class Point {
            public Point(int x, int y)
            {
                X = x;
                Y = y;
            }
            public int X { get; set; }

            public int Y { get; set; }
        }
    }
        public static void InitToSameValue(this int[,] a,int v)
        {
            int h = a.GetLength(0);
            int w = a.GetLength(1);
            for (int i = 0, j = h - 1; i <= j;i++,j--)
            {
                for (int m = 0; m<w; m++)
                {
                    a[i,m]= v;
                    a[j, m] = v;
                }
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

浪舟子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值