public double CalculateWeight(ITransit transit, TimeSpan departureTime) { // Make sure, that the heuristic weight is always lower than any possible path from startNode to endNode. // This isn't a bulletproof way to ensure that, however, having an entity moving 10 times the speed of // a person seems reasonable enough, to say that it's going to be faster than any possible path. return(new Feet().TravelTime(transit.StartNode.Location, transit.EndNode.Location, departureTime).TotalMinutes / 10); }
// Returns bool representing if the path has been found the path itself private Tuple <bool, AStarPath> FindDirectPath(ITransit transit, AStarNode endingNode, TimeSpan time) { ITransit directTransit = null; var originalWeight = endingNode.Weight; var originalHeuristicWeight = endingNode.HeuristicWeight; // We are not interested in direct paths by feet, as it will most likely won't be the best path. // If it is A* will find it in the main part of the algorithm. if (transit.Transport.Alias != "Feet" && transit.Transport.IsTransitPossible(transit.StartNode.Location, endingNode.Location)) { directTransit = new Transit(); directTransit.Transport = transit.Transport; directTransit.StartNode = transit.StartNode; directTransit.EndNode = endingNode; var potentialWeight = _weightCalculator.CalculateWeight(directTransit, time) * 0.75 + ((AStarNode)transit.StartNode).Weight; var potentialHeuristic = _heuristicCalculator.CalculateWeight(transit, time); endingNode.Weight = potentialWeight; endingNode.HeuristicWeight = potentialHeuristic; directTransit.DepartureTime = directTransit.Transport.GetClosestDepartureTime(directTransit.StartNode.Location, time); directTransit.ArrivalTime = directTransit.DepartureTime + directTransit.Transport.TravelTime(directTransit.StartNode.Location, directTransit.EndNode.Location, directTransit.DepartureTime); } AStarPath path = BacktrackPath(directTransit); // Reset ending node weight as to not interfere with the main part of the algorithm endingNode.Weight = originalWeight; endingNode.HeuristicWeight = originalHeuristicWeight; return(Tuple.Create(path.Value > 0, path)); }
public double CalculateWeight(ITransit transit, TimeSpan departureTime) { var startingLocation = transit.StartNode.Location; var endingLocation = transit.EndNode.Location; var actualDepartureTime = transit.Transport.GetClosestDepartureTime(transit.StartNode.Location, departureTime); var waitTime = actualDepartureTime - departureTime; var travelTime = transit.Transport.TravelTime(startingLocation, endingLocation, departureTime); return((waitTime + travelTime).TotalMinutes); }
private AStarPath BacktrackPath(ITransit transit) { var path = new AStarPath(); if (transit == null) { return(path); } path.Add(transit); return(BacktrackPath(transit.StartNode, path)); }
public override void Add(ITransit transit) { Value += ((AStarNode)transit.EndNode).TotalWeight; base.Add(transit); }
public virtual double CalculateWeight(ITransit transit, TimeSpan departureTime) => _underlyingWeightCalculator.CalculateWeight(transit, departureTime);
public virtual void Add(ITransit transit) { _path.Add(transit); }
public Node(ILocation location, List <ITransit> transits) { Location = location; Transits = transits; FastestTransit = null; }
public override double CalculateWeight(ITransit transit, TimeSpan departureTime) { var transportTypePenalty = transit.Transport.Alias == "Feet" ? WALKING_PENALTY : 0d; return(base.CalculateWeight(transit, departureTime) + transportTypePenalty); }