Exemplo n.º 1
0
        public Result Run()
        {
            Init();
            while (fringe.Count > 0)
            {
                Intermediate.Visited++;
                var currentInfo = fringe.Dequeue();
                if (MaximumAcceptableCost.HasValue)
                {
                    if (Destination != null && currentInfo.HeuristicCostLeft > MaximumAcceptableCost.Value)
                    {
                        // We are never gonna make it in time. Quit.
                        return(new Result()
                        {
                            Type = "MaxDurationExceeded"
                        });
                    }
                    if (currentInfo.Cost > MaximumAcceptableCost.Value)
                    {
                        return(new Result()
                        {
                            Type = "MaxDurationExceeded"
                        });
                    }
                }

                var current = currentInfo.Node;
                currentInfo.IsVisited = true;
                if (current == Destination)
                {
                    // Found our destination
                    CreateRoute(Destination);
                    return(new Result()
                    {
                        Type = "ExactRouteFound",
                        NodeCount = currentInfo.NodeCount()
                    });
                }

                foreach (var edge in network.GetEdges(current))
                {
                    var neighbour      = network.GetOtherNode(edge, current);
                    var neighbourId    = network.GetNodeId(neighbour);
                    var neighbourVisit = Intermediate.Vertices.GetVisit(neighbourId);
                    if (neighbourVisit == null || !neighbourVisit.IsVisited)
                    {
                        var edgeCost      = network.GetCost(edge);
                        var tentativeCost = currentInfo.Cost + edgeCost;
                        var added         = false;
                        if (neighbourVisit == null)
                        {
                            added          = true;
                            neighbourVisit = new NodeVisit()
                            {
                                Node = neighbour,
                                HeuristicCostLeft = network.EstimateMinimumCost(neighbour, Destination)
                            };
                            Intermediate.Vertices.AddVisit(neighbourId, neighbourVisit);
                        }
                        if (added || tentativeCost < neighbourVisit.Cost)
                        {
                            neighbourVisit.PredecessingEdge      = edge;
                            neighbourVisit.PredecessingNodeVisit = currentInfo;
                            neighbourVisit.Cost = tentativeCost;
                            if (added)
                            {
                                fringe.Enqueue(neighbourVisit, neighbourVisit.EstimatedArrivalAtDestination);
                            }
                            else
                            {
                                fringe.UpdatePriority(neighbourVisit, neighbourVisit.EstimatedArrivalAtDestination);
                            }
                        }
                    }
                }
            }

            if (Destination == null)
            {
                return(new Result()
                {
                    Type = "ExhaustiveSearchCompleted"
                });
            }
            return(new Result()
            {
                Type = "NoRouteFound"
            });
        }