我曾使用 Dijktra 算法和双向 Dijkstra 算法作为迷宫游戏中的寻路技术。在我实施所有内容后,它通常会照常工作。但是,在我插入时间计数以证明 Bidirectional Dijkstra's 在一般理论中比 Dijkta's 快之后,显示的结果是 Dijkstra's 比 Bidirectional Dijkstra's 快。我很困惑我的编码是错误的还是真的那样?
IEnumerator Process_Dijkstra(Tile start, Tile goal, Queue<Tile> path)
{
Dictionary<Tile, Tile> NextTileToGoal = new Dictionary<Tile, Tile>();
Dictionary<Tile, int> costToReachTile = new Dictionary<Tile, int>();
PriorityQueue<Tile> frontier = new PriorityQueue<Tile>();
frontier.Enqueue(goal, 0);
costToReachTile[goal] = 0;
List<Tile> sameCostTiles = new List<Tile>();
// Record the start time
DateTime startTime = DateTime.Now;
while (frontier.Count > 0)
{
Tile curTile = frontier.Dequeue();
if (curTile == start)
break;
foreach (Tile neighbor in _mapGenerator.Neighbors(curTile))
{
//neighbor._Text = "";
int newCost = costToReachTile[curTile] + neighbor._Cost;
if (costToReachTile.ContainsKey(neighbor) == false || newCost < costToReachTile[neighbor])
{
if (neighbor._TileType != Tile.TileType.Wall && neighbor._TileType != Tile.TileType.Trap)
{
costToReachTile[neighbor] = newCost;
int priority = newCost;
frontier.Enqueue(neighbor, priority);
NextTileToGoal[neighbor] = curTile;
neighbor._Text = costToReachTile[neighbor].ToString();
nodeCount=costToReachTile[neighbor] - 1;
}
}
}
yield return null;
}
// Calculate the elapsed time
TimeSpan elapsedTime = DateTime.Now - startTime;
timeCount = elapsedTime;
//Get the Path
//check if tile is reachable
if (NextTileToGoal.ContainsKey(start) == false)
{
path = null;
}
else
{
Tile pathTile = start;
while (goal != pathTile)
{
pathTile = NextTileToGoal[pathTile];
path.Enqueue(pathTile);
}
foreach (Tile tile in path)
{
if (tile != goal && tile != start)
{
tile._Color = new Color(0.7f, 0.7f, 0.01f); // set to whatever color you want
}
goal._Color = Color.red;
goal._Text = "End";
start._Color = Color.green;
start._Text = "Start";
}
}
}
IEnumerator Process_Bidirectional_Dijkstra(Tile start, Tile goal)
{
// Dijkstra algorithm from the start tile
Dictionary<Tile, Tile> NextTileToGoal = new Dictionary<Tile, Tile>();
Dictionary<Tile, int> costToReachStart = new Dictionary<Tile, int>();
PriorityQueue<Tile> frontierStart = new PriorityQueue<Tile>();
frontierStart.Enqueue(start, 0);
costToReachStart[start] = 0;
// Record the start time
DateTime startTime = DateTime.Now;
while (frontierStart.Count > 0)
{
Tile curTile = frontierStart.Dequeue();
if (curTile == goal)
break;
foreach (Tile neighbor in _mapGenerator.Neighbors(curTile))
{
int newCost = costToReachStart[curTile] + neighbor._Cost;
if (costToReachStart.ContainsKey(neighbor) == false || newCost < costToReachStart[neighbor])
{
if (neighbor._TileType != Tile.TileType.Wall && neighbor._TileType != Tile.TileType.Trap)
{
costToReachStart[neighbor] = newCost;
int priority = newCost;
frontierStart.Enqueue(neighbor, priority);
NextTileToGoal[neighbor] = curTile;
neighbor._Text = costToReachStart[neighbor].ToString();
nodeCount = costToReachStart[neighbor] - 1;
yield return null; // Yield each step of the path finding process
}
}
}
}
// Dijkstra algorithm from the goal tile
Dictionary<Tile, Tile> NextTileFromStart = new Dictionary<Tile, Tile>();
Dictionary<Tile, int> costToReachGoal = new Dictionary<Tile, int>();
PriorityQueue<Tile> frontierGoal = new PriorityQueue<Tile>();
frontierGoal.Enqueue(goal, 0);
costToReachGoal[goal] = 0;
while (frontierGoal.Count > 0)
{
Tile curTile = frontierGoal.Dequeue();
if (curTile == start)
break;
foreach (Tile neighbor in _mapGenerator.Neighbors(curTile))
{
int newCost = costToReachGoal[curTile] + neighbor._Cost;
if (costToReachGoal.ContainsKey(neighbor) == false || newCost < costToReachGoal[neighbor])
{
if (neighbor._TileType != Tile.TileType.Wall && neighbor._TileType != Tile.TileType.Trap)
{
costToReachGoal[neighbor] = newCost;
int priority = newCost;
frontierGoal.Enqueue(neighbor, priority);
NextTileFromStart[neighbor] = curTile;
neighbor._Text = costToReachGoal[neighbor].ToString();
yield return null; // Yield each step of the path finding process
}
}
}
}
// Combine the two paths and return the result
Queue<Tile> path = new Queue<Tile>();
Tile intersectionTile = null;
int lowestTotalCost = int.MaxValue;
// Find the tile with the lowest total cost from both directions
foreach (Tile tile in costToReachStart.Keys)
{
if (costToReachGoal.ContainsKey(tile))
{
int totalCost = costToReachStart[tile] + costToReachGoal[tile];
if (totalCost < lowestTotalCost)
{
intersectionTile = tile;
lowestTotalCost = totalCost;
}
}
}
// If no intersection tile was found, the path is not reachable
if (intersectionTile == null)
{
yield break; // Return an empty path
}
// Calculate the elapsed time
TimeSpan elapsedTime = DateTime.Now - startTime;
timeCount = elapsedTime;
// Build the path from start to intersection tile
Tile pathTile = intersectionTile;
while (start != pathTile)
{
pathTile = NextTileToGoal[pathTile];
path.Enqueue(pathTile);
if (pathTile != goal && pathTile != start)
{
pathTile._Color = new Color(0.7f, 0.7f, 0.01f); // set to whatever color you want
}
//pathTile._Color = Color.green; // mark path tile as green
yield return null; // yield for visualizing the path finding process
}
// Build the path from intersection tile to goal
pathTile = intersectionTile;
while (goal != pathTile)
{
path.Enqueue(pathTile);
if (pathTile != goal && pathTile != start)
{
pathTile._Color = new Color(0.7f, 0.7f, 0.01f); // set to whatever color you want
}
//pathTile._Color = Color.green; // mark path tile as green
pathTile = NextTileFromStart[pathTile];
yield return null; // yield for visualizing the path finding process
}
path.Enqueue(goal);
goal._Color = Color.red;
goal._Text = "End";
start._Color = Color.green;
start._Text = "Start";
yield return null; // yield for visualizing the path finding process
yield return path; // return the path as a queue of tiles
}
下面是我的原始结果和图表。有人可以指导我吗?