All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.transit.raptor.rangeraptor.multicriteria.McRangeRaptorWorkerState Maven / Gradle / Ivy

There is a newer version: 2.5.0
Show newest version
package org.opentripplanner.transit.raptor.rangeraptor.multicriteria;

import org.opentripplanner.transit.raptor.api.path.Path;
import org.opentripplanner.transit.raptor.api.transit.CostCalculator;
import org.opentripplanner.transit.raptor.api.transit.IntIterator;
import org.opentripplanner.transit.raptor.api.transit.RaptorTransfer;
import org.opentripplanner.transit.raptor.api.transit.RaptorTripSchedule;
import org.opentripplanner.transit.raptor.rangeraptor.WorkerLifeCycle;
import org.opentripplanner.transit.raptor.rangeraptor.WorkerState;
import org.opentripplanner.transit.raptor.rangeraptor.multicriteria.arrivals.AbstractStopArrival;
import org.opentripplanner.transit.raptor.rangeraptor.multicriteria.arrivals.AccessStopArrival;
import org.opentripplanner.transit.raptor.rangeraptor.multicriteria.arrivals.TransferStopArrival;
import org.opentripplanner.transit.raptor.rangeraptor.multicriteria.arrivals.TransitStopArrival;
import org.opentripplanner.transit.raptor.rangeraptor.multicriteria.heuristic.HeuristicsProvider;
import org.opentripplanner.transit.raptor.rangeraptor.path.DestinationArrivalPaths;
import org.opentripplanner.transit.raptor.rangeraptor.transit.TransitCalculator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;


/**
 * Tracks the state of a RAPTOR search, specifically the best arrival times at each transit stop at
 * the end of a particular round, along with associated data to reconstruct paths etc.
 * 

* This is grouped into a separate class (rather than just having the fields in the raptor worker * class) because we want the Algorithm to be as clean as possible and to be able to swap the state * implementation - try out and experiment with different state implementations. * * @param The TripSchedule type defined by the user of the raptor API. */ final public class McRangeRaptorWorkerState implements WorkerState { private final Stops stops; private final DestinationArrivalPaths paths; private final HeuristicsProvider heuristics; private final List> arrivalsCache = new ArrayList<>(); private final CostCalculator costCalculator; private final TransitCalculator transitCalculator; /** * create a RaptorState for a network with a particular number of stops, and a given maximum * duration */ public McRangeRaptorWorkerState( Stops stops, DestinationArrivalPaths paths, HeuristicsProvider heuristics, CostCalculator costCalculator, TransitCalculator transitCalculator, WorkerLifeCycle lifeCycle ) { this.stops = stops; this.paths = paths; this.heuristics = heuristics; this.costCalculator = costCalculator; this.transitCalculator = transitCalculator; // Attach to the RR life cycle lifeCycle.onSetupIteration((ignore) -> setupIteration()); lifeCycle.onTransitsForRoundComplete(this::transitsForRoundComplete); lifeCycle.onTransfersForRoundComplete(this::transfersForRoundComplete); } // The below methods are ordered after the sequence they naturally appear in the algorithm, // also private life-cycle callbacks are listed here (not in the private method section). // This method is private, but is part of Worker life cycle private void setupIteration() { arrivalsCache.clear(); // clear all touched stops to avoid constant rexploration stops.clearTouchedStopsAndSetStopMarkers(); } @Override public void setInitialTimeForIteration(RaptorTransfer accessLeg, int departureTime) { addStopArrival( new AccessStopArrival<>( departureTime, costCalculator.walkCost(accessLeg.durationInSeconds()), accessLeg ) ); } @Override public boolean isNewRoundAvailable() { return stops.updateExist(); } @Override public IntIterator stopsTouchedPreviousRound() { return stops.stopsTouchedIterator(); } @Override public IntIterator stopsTouchedByTransitCurrentRound() { return stops.stopsTouchedIterator(); } Iterable> listStopArrivalsPreviousRound(int stop) { return stops.listArrivalsAfterMarker(stop); } /** * Set the time at a transit stop iff it is optimal. */ final void transitToStop( final PatternRide ride, final int alightStop, final int alightTime, final int alightSlack ) { final int stopArrivalTime = alightTime + alightSlack; if (exceedsTimeLimit(stopArrivalTime)) { return; } // Calculate wait time before and after the transit leg final int waitTime = ride.boardWaitTime + alightSlack; final int costTransitLeg = costCalculator.transitArrivalCost( ride.prevArrival, waitTime, alightTime - ride.boardTime, alightStop, ride.trip ); arrivalsCache.add( new TransitStopArrival<>( ride.prevArrival, alightStop, stopArrivalTime, costTransitLeg, ride.trip ) ); } /** * Set the time at a transit stops iff it is optimal. */ @Override public void transferToStops(int fromStop, Iterator transfers) { Iterable> fromArrivals = stops.listArrivalsAfterMarker(fromStop); while (transfers.hasNext()) { transferToStop(fromArrivals, transfers.next()); } } // This method is private, but is part of Worker life cycle private void transitsForRoundComplete() { stops.clearTouchedStopsAndSetStopMarkers(); commitCachedArrivals(); } // This method is private, but is part of Worker life cycle private void transfersForRoundComplete() { commitCachedArrivals(); } @Override public Collection> extractPaths() { stops.debugStateInfo(); return paths.listPaths(); } @Override public boolean isDestinationReachedInCurrentRound() { return paths.isReachedCurrentRound(); } /* private methods */ private void transferToStop(Iterable> fromArrivals, RaptorTransfer transfer) { final int transferTimeInSeconds = transfer.durationInSeconds(); for (AbstractStopArrival it : fromArrivals) { int arrivalTime = it.arrivalTime() + transferTimeInSeconds; if (!exceedsTimeLimit(arrivalTime)) { int cost = costCalculator.walkCost(transferTimeInSeconds); arrivalsCache.add(new TransferStopArrival<>(it, transfer, arrivalTime, cost)); } } } private void commitCachedArrivals() { for (AbstractStopArrival arrival : arrivalsCache) { addStopArrival(arrival); } arrivalsCache.clear(); } private void addStopArrival(AbstractStopArrival arrival) { if (heuristics.rejectDestinationArrivalBasedOnHeuristic(arrival)) { return; } stops.addStopArrival(arrival); } private boolean exceedsTimeLimit(int time) { return transitCalculator.exceedsTimeLimit(time); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy