为什么搜索 Bidirectional Dijkstra's 的时间比 Dijkstra's 多?

问题描述 投票:0回答:0

我曾使用 Dijktra 算法和双向 Dijkstra 算法作为迷宫游戏中的寻路技术。在我实施所有内容后,它通常会照常工作。但是,在我插入时间计数以证明 Bidirectional Dijkstra's 在一般理论中比 Dijkta's 快之后,显示的结果是 Dijkstra's 比 Bidirectional Dijkstra's 快。我很困惑我的编码是错误的还是真的那样?

  • Dijstra 的算法
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";

            }


        }

    }
  • 双向 Dijkstra 算法
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
    }

下面是我的原始结果和图表。有人可以指导我吗?

dijkstra path-finding bidirectional-search
© www.soinside.com 2019 - 2024. All rights reserved.