如何从最短路径算法中提取路径
本文关键字:提取 路径 算法 最短路径 | 更新日期: 2023-09-27 18:04:50
我试图实现一个"6度"风格的算法,因为我试图找到两个链接之间的最短路径。在这个场景中,它是一个电子游戏,它有区域地图,这些地图有相互连接的传送门/翘曲。
每个地图都有一个地图ID int id
,并且可以有几个门户,实现为List<Portal>
。
每个传送门将指向的地图int ToMapID
和包含它的地图Map HomeMap
。
无论如何,我已经成功地在两个地图之间找到了最少的数量的翘曲,这很好,因为这就是我想要的。问题是,我很难想象如何记录从a点到b点的路径。
下面是我实现的:
Map start = allMaps[0];
Map end = allMaps[1];
int distance = 0;
List<Portal> alreadyChecked = new List<Portal>();
List<Portal> queue = start.Portals;
while (queue.Count > 0) {
distance++;
List<Portal> newQueue = new List<Portal>();
foreach (Portal p in queue) {
foreach (Portal tm in theMap.Portals) {
if (!alreadyChecked.Contains(tm)) {
alreadyChecked.Add(tm);
if (tm.ToMap == end.ID) {
Console.WriteLine("Found a path, it is " + distance + " map(s) away;");
Console.ReadKey();
Environment.Exit(0);
}
newQueue.Add(tm);
}
}
}
queue = newQueue;
}
理想情况下,我希望有一个Map[]
数组,它具有从A点到b点的步骤顺序。
我完全不知道从哪里开始,虽然。我如何解开路径?
当你做newQueue.Add(tm);
时,你也应该记录你来自哪里。一个简单的解决方案是将关系添加到字典:dict.Add(tm,p)
。最后,只需请求当前门户的父门户,就可以使用该字典从目标返回路径。
最短路径的工作原理基本是这样的:
起始点的代价为0。所有其他区域的代价都是无穷大
维护一个可达区域队列。一开始只有起始区
迭代可达区域,始终选择成本最低的区域。
对于每个直连区域,计算(成本+当前区域)+(获取连接翘曲点的成本)。
如果该值小于邻居区域的当前开销值,则更新开销值,设置指向当前区域的反向链接指针,并将其加入队列。重复,直到下一个要处理的区域(队列中成本最低的区域)的成本等于或大于目标区域。
然后,从目的区域,按照反向链接指针形成你的路径。
在所有链接成本相等的简单情况下,您可以使用FIFO队列,它将保持排序。如果差旅成本不同,则必须按区域成本对队列进行排序。