我一直在尝试使用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值。
答案 0 :(得分:-1)
如果您进入迷宫并仅选择一侧(左墙或右墙)并沿着该路径行驶,则需要您退出。显然它不会给你最短的路径。但是,只有你走过两次的像素才会使路径更长,所以只能将它们从中移除。
我希望这会有所帮助。