Depth-first search to solve the shortest path problem maze

In the previous article we introduced the idea of ​​the depth-first traversal, and an array as an example to achieve a full array arithmetic coding, this article, we first search the shortest path problem solving maze depth. Implement the query to the shortest path from the inlet end of the labyrinth program, need to overcome the obstacle, and can not exceed the limits of the maze.

Graphic algorithm

If the following maze, we need to find the shortest path from the inlet end, wherein the position of the lock mark is not an obstacle arrival.
Shortest Path of Maze
Let's look at the first step could reach the point of what? Only (1,2) and (2,1). If we go to the right first came to (2,1) at this point, the next point to reach only the (2,2), because (1,3) is an obstacle, (1,1) has gone through, You can not go. But we still did not reach the end, so you have to continue to go down, no way out, or until it reaches the end. note! Not reach the finish line to the end, because just try to reach the end of a road, not necessarily the shortest. At some point we just have to choose from multiple directions, so we need to return to these points continue to try to go somewhere else, until all may have to try again, and finally output the shortest path.
Now we try to achieve this depth-first search method dfs (). First, the content dfs methods need to be addressed include: check whether the current end point has been reached, if not reach the end of the next step may be to find a place to go. To achieve the object, DFS function takes three parameters, corresponding to x, y coordinates and the current step number step. It is defined as follows:

        static void dfs(int x,int y,int step)
        {
            
        }

Determine whether the current reaches the end of a very simple, only need to determine whether the same and end point

        static int p ;   //终点y
        static int q ;   //终点坐标y
        static int min;     //当前最短路径步数
        static void dfs(int x,int y,int step)
        {
            //判断是否到达终点
            if (x==p&&y==q)
            {
                //更新最小值
                if (step<min)
                {
                    min = step;
                }
                return; //到达终点则返回
            }
        }

If not reach the end, you need to figure out the next step can take place. Because there are four directions you can go, we define a direction array next, as follows:

        static int[][] next = new int[][]
        {
            new int[] { 0, 1 }, //向右
            new int[] { 1, 0 }, //向下
            new int[] { 0, -1 },//向左
            new int[] { -1, 0 } //向上
        };

Depth-first search
Through this array direction, we can obtain the coordinates of the next step, the next step here we use stored abscissa tx, ty stored next ordinate.

   for (int i = 0; i < next.Length; i++)
   {
        //计算下一步的坐标
        tx = x + next[i][0];
        ty = y + next[i][1];
   }

Next, the next point (tx, ty) judgment, including whether cross-border, whether it is an obstacle, and this point is already gone, we use an array to record the book which has gone through point.
If you meet all the requirements of this point, this point will be the next expansion, namely dfs (step + 1), once the next attempt would mean the number of steps has increased by one.

            for (int i = 0; i < next.Length; i++)
            {
                //计算下一步的坐标
                tx = x + next[i][0];
                ty = y + next[i][1];
                //判断是否越界
                if (tx < 1 || tx > n || ty < 1 || ty > m)
                {
                    continue;
                }
                //判断该点是否为障碍物或者已经在路径中
                if (a[tx][ty] == 0 && book[tx][ty] == 0)
                {
                    book[tx][ty] = 1;   //标记这个点已经走过
                    way.Add(string.Format("({0},{1})", tx, ty));    //记录到路径中,用于输出
                    var index = way.Count - 1;
                    dfs(tx, ty, step + 1);  //开始尝试下一步
                    book[tx][ty] = 0;   //尝试结束后取消这个点的标记
                    way.RemoveAt(index);
                }
            }

We look at the complete implementation and call:

    class Program
    {
        static void Main(string[] args)
        {
            int i, j, startx, starty;
            //初始化迷宫信息5*4
            n = 5;
            m = 4;
            for (i = 1; i <= n; i++)
            {
                a[i] = new int[5];
                book[i] = new int[5];
                for (j = 1; j <= m; j++)
                {
                    //(1,3),(3,3),(4,2),(5,4)处为障碍物
                    if ((i == 1 && j == 3) || (i == 3 && j == 3) || (i == 4 && j == 2) || (i == 5 && j == 4))
                    {
                        a[i][j] = 1;
                    }
                    else
                    {
                        a[i][j] = 0;
                    }
                }
            }
            //终点为(4,3)
            p = 4;
            q = 3;
            way.Add("(1,1)");
            book[1][1] = 1;
            dfs(1, 1, 0);   //起点为(1,1),开始遍历
            Console.WriteLine("最短步数为:" + min);
            Console.ReadKey();
        }
        static int n, m, p, q, min = 99999;
        static int[][] a = new int[6][]; //记录障碍物
        static int[][] book = new int[6][];//记录走过的路径
        static List<string> way = new List<string>();
        static void dfs(int x, int y, int step)
        {
            int[][] next = new int[][]
            {
                new int[] { 0, 1 }, //向右
                new int[] { 1, 0 }, //向下
                new int[] { 0, -1 },//向左
                new int[] { -1, 0 } //向上
            };
            int tx, ty;
            //判断是否到达终点
            if (x == p && y == q)
            {
                //更新最小值
                if (step < min)
                {
                    min = step;
                }
                foreach (var item in way)
                {
                    Console.Write(item + " ");
                }
                Console.WriteLine("到达终点,步数{0}", step);
                return; //到达终点则返回
            }
            for (int i = 0; i < next.Length; i++)
            {
                //计算下一步的坐标
                tx = x + next[i][0];
                ty = y + next[i][1];
                //判断是否越界
                if (tx < 1 || tx > n || ty < 1 || ty > m)
                {
                    continue;
                }
                //判断该点是否为障碍物或者已经在路径中
                if (a[tx][ty] == 0 && book[tx][ty] == 0)
                {
                    book[tx][ty] = 1;   //标记这个点已经走过
                    way.Add(string.Format("({0},{1})", tx, ty));    //记录到路径中,用于输出
                    var index = way.Count - 1;
                    dfs(tx, ty, step + 1);  //开始尝试下一步
                    book[tx][ty] = 0;   //尝试结束后取消这个点的标记
                    way.RemoveAt(index);
                }
            }
            return;
        }

    }

We in the Main method to initialize accordance with the above maze maze, and then call the depth from the starting point (1,1) first search to find and print it leads to the end of the path, the final output of the shortest number of steps, results as shown below:
Shortest Path of Maze
At this point have been completed Search maze shortest path, if the idea of the depth-first traversal are not familiar with can refer to my previous article: C # depth-first traversal

Published 12 original articles · won praise 27 · views 20000 +

Guess you like

Origin blog.csdn.net/Leaderxin/article/details/103119363