0

I had used the Dijktra's algorithm and Bidirectional Dijkstra's as the path finding techniques in the maze game. After I implement everything, it normally works as usual. However, after I insert the time count to prove that Bidirectional Dijkstra's is faster than Dijkta's in general theory, the result shown is Dijkstra's is faster than Bidirectional Dijkstra's. I am confused about whether my coding is wrong or actually like that?

  • Dijstra's Algorthim
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";

            }


        }

    }
  • Bidirectional Dijkstra's Algorthim
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
    }

Below are my original result with diagram. Can someone guide me?

Dijkstra's

Bidirectional Dijkstra's

Alexander
  • 11
  • 3
  • Haven't had time to look through your implementation in detail, but the fact that you're using `new` for a local variable in multiple places, leaking memory, suggests that your implementation simply isn't very good, so that comparing speeds isn't very sensible at the current state. – Marcus Müller Apr 22 '23 at 07:41

0 Answers0