迷宫求解器使用BFS处理时间

时间:2016-12-07 00:19:53

标签: c#

我一直在尝试使用BFS解决迷宫。

我已经在python中编写了代码,并且我使用相同的概念来解决它,但是处理它需要更长的时间。对于441x441迷宫,需要大约5~10分钟。

这是我的代码

        public static List<Tuple<int, int>> BFS(List<List<Tuple<byte, byte, byte>>> list, Tuple<int, int> startPixel, Tuple<int, int> endPixel, int width, int height)
        {
            var startPixelList = new List<Tuple<int, int>> { startPixel };
            var endPixelList = new List<Tuple<int, int>> { endPixel };

            Queue<List<Tuple<int, int>>> Q = new Queue<List<Tuple<int, int>>> { };
            Q.Enqueue(startPixelList);

            Tuple<byte, byte, byte> black = Tuple.Create(Convert.ToByte(0), Convert.ToByte(0), Convert.ToByte(0));
            list[startPixel.Item1][startPixel.Item2] = black;

            while (Q.Count != 0)
            {
                var path = Q.Dequeue();
                var pathClone = DeepClone(path);
                var pixel = path[path.Count - 1];
                if (pixel.Item1 == endPixel.Item1 && pixel.Item2 == endPixel.Item2)
                {
                    return path;
                }
                Tuple<int, int> pixelLeft = getLeftPixel(pixel.Item1, pixel.Item2);
                Tuple<int, int> pixelRight = getRightPixel(pixel.Item1, pixel.Item2);
                Tuple<int, int> pixelTop = getTopPixel(pixel.Item1, pixel.Item2);
                Tuple<int, int> pixelBottom = getBottomPixel(pixel.Item1, pixel.Item2);
                int leftX = pixelLeft.Item1;
                int leftY = pixelLeft.Item2;
                int rightX = pixelRight.Item1;
                int rightY = pixelRight.Item2;
                int topX = pixelTop.Item1;
                int topY = pixelTop.Item2;
                int bottomX = pixelBottom.Item1;
                int bottomY = pixelBottom.Item2;
                if (leftX < 0 || leftY < 0 || leftX > width || leftY > height)
                {

                }
                //check if it is white
                else if (checkWhite(list[leftX][leftY]))
                {
                    list[leftX][leftY] = black; //set the pixel to black so we would not visit again
                    var temp = DeepClone(pathClone);
                    path = temp;
                    path.Add(pixelLeft);
                    Q.Enqueue(path);
                }
                if (rightX < 0 || rightY < 0 || rightX > width || rightY > height)
                {

                }
                else if (checkWhite(list[rightX][rightY]))
                {
                    var temp = DeepClone(pathClone);
                    path = temp;
                    path.Add(pixelRight);
                    Q.Enqueue(path);
                }

                if (topX < 0 || topY < 0 || topX > width || topY > height)
                {

                }
                else if (checkWhite(list[topX][topY]))
                {
                    list[topX][topY] = black; //set the pixel to black so we would not visit again
                    var temp = DeepClone(pathClone);
                    path = temp;
                    path.Add(pixelTop);
                    Q.Enqueue(path);
                }

                if (bottomX < 0 || bottomY < 0 || bottomX > width || bottomY > height)
                {

                }
                else if (checkWhite(list[bottomX][bottomY]))
                {
                    list[bottomX][bottomY] = black; //set the pixel to black so we would not visit again
                    var temp = DeepClone(pathClone);
                    path = temp;
                    path.Add(pixelBottom);
                    Q.Enqueue(path);
                }
            }
            Console.WriteLine("Path not found");
            return null;
        }
    }

}

基本上我的每个像素具有RGB值的列表是

列表&gt;&gt;,包含元组的二维列表,所以列出[i] [j],其中i是宽度#,j是高度#。

BFS获取整个列表,起始像素,结束像素,图像宽度和图像高度。

我将起始像素出列,这是一个元组列表,找到左,右,上,下(相邻)像素并查看它是否为白色。如果是白色,我会将每个像素附加到原始路径,然后将它们排队。

我认为我的问题是因为我正在深入克隆我的路径列表。我正在创建路径的深层副本,因为每次附加相邻像素时,都会删除原始路径。我需要原始路径才能检查右侧,顶部和底部。 (如果这有意义的话)

例如,如果我的像素从(51,5)开始,我检查左边是(50,5),如果是白色,我将它附加到原始路径,所以我入队[(51, 5),(50,5)。但如果我想检查像素的右侧,我需要原始路径像素(51,5),而不是更新的路径。所以我深度克隆(因为c#使用指针)来维持原始像素。

请帮助我如何使这段代码比我现在更高效,更快。我正在使用Bitmap来获取每个像素的RGB值。

1 个答案:

答案 0 :(得分:-1)

如果您进入迷宫并仅选择一侧(左墙或右墙)并沿着该路径行驶,则需要您退出。显然它不会给你最短的路径。但是,只有你走过两次的像素才会使路径更长,所以只能将它们从中移除。

我希望这会有所帮助。