public virtual double CalculateWeight(ITransit transit, TimeSpan departureTime) => _underlyingWeightCalculator.CalculateWeight(transit, departureTime);
Exemple #2
0
        public IPath FindFastestPath(AStarNode startingNode, AStarNode endingNode, TimeSpan departureTime)
        {
            var visitedNodes          = new HashSet <AStarNode>();
            var nodesToVisit          = new SimplePriorityQueue <AStarNode>();
            var temporaryArrivalTimes = new Dictionary <INode, TimeSpan>();

            nodesToVisit.Enqueue(startingNode, 0);

            temporaryArrivalTimes[startingNode] = departureTime;
            startingNode.Weight          = 0;
            startingNode.HeuristicWeight = 0;

            while (nodesToVisit.Count > 0)
            {
                var currentNode = nodesToVisit.Dequeue();

                if (currentNode == endingNode)
                {
                    break;
                }

                foreach (var transit in currentNode.Transits)
                {
                    var endNode = (AStarNode)transit.EndNode;

                    var potentialWeight    = _weightCalculator.CalculateWeight(transit, temporaryArrivalTimes[currentNode]) + currentNode.Weight;
                    var potentialHeuristic = _heuristicCalculator.CalculateWeight(transit, temporaryArrivalTimes[currentNode]);

                    var weightUpdated = false;
                    if (potentialWeight < endNode.Weight)
                    {
                        weightUpdated           = true;
                        endNode.Weight          = potentialWeight;
                        endNode.HeuristicWeight = potentialHeuristic;
                        endNode.FastestTransit  = transit;

                        var intermediateDepartureTime = transit.Transport.GetClosestDepartureTime(currentNode.Location, temporaryArrivalTimes[currentNode]);
                        temporaryArrivalTimes[endNode] = intermediateDepartureTime + transit.Transport.TravelTime(transit.StartNode.Location, transit.EndNode.Location, intermediateDepartureTime);

                        transit.DepartureTime = intermediateDepartureTime;
                        transit.ArrivalTime   = temporaryArrivalTimes[endNode];
                    }

                    if (!visitedNodes.Contains(endNode))
                    {
                        var isInVisitList = nodesToVisit.Contains(endNode);

                        if (!isInVisitList)
                        {
                            nodesToVisit.EnqueueWithoutDuplicates(endNode, (float)endNode.TotalWeight);
                        }
                        else if (isInVisitList && weightUpdated)
                        {
                            nodesToVisit.UpdatePriority(endNode, (float)endNode.TotalWeight);
                        }
                    }
                }

                visitedNodes.Add(currentNode);
            }

            return(BacktrackPath(endingNode));
        }