public virtual double CalculateWeight(ITransit transit, TimeSpan departureTime) => _underlyingWeightCalculator.CalculateWeight(transit, departureTime);
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)); }