Search in sources :

Example 1 with TIntIntMap

use of gnu.trove.map.TIntIntMap in project OpenTripPlanner by opentripplanner.

the class RepeatedRaptorProfileRouter method findInitialStops.

/**
 * Find all transit stops accessible by streets around the origin, leaving behind a shortest path tree of the
 * reachable area in the field preTransitSpt.
 *
 * @param data the raptor data table to use. If this is null (i.e. there is no transit) range is extended,
 *             and we don't care if we actually find any stops, we just want the tree of on-street distances.
 */
@VisibleForTesting
public TIntIntMap findInitialStops(boolean dest, RaptorWorkerData data) {
    LOG.info("Finding initial stops");
    double lat = dest ? request.toLat : request.fromLat;
    double lon = dest ? request.toLon : request.fromLon;
    QualifiedModeSet modes = dest ? request.egressModes : request.accessModes;
    RoutingRequest rr = new RoutingRequest(modes);
    rr.batch = true;
    rr.from = new GenericLocation(lat, lon);
    // rr.walkSpeed = request.walkSpeed;
    rr.to = rr.from;
    rr.setRoutingContext(graph);
    rr.dateTime = request.date.toDateMidnight(DateTimeZone.forTimeZone(graph.getTimeZone())).getMillis() / 1000 + request.fromTime;
    rr.walkSpeed = request.walkSpeed;
    rr.bikeSpeed = request.bikeSpeed;
    if (data == null) {
        // Non-transit mode. Search out to the full 120 minutes.
        // Should really use directModes.
        rr.worstTime = rr.dateTime + RaptorWorker.MAX_DURATION;
        rr.dominanceFunction = new DominanceFunction.EarliestArrival();
    } else {
        // Transit mode, limit pre-transit travel.
        if (rr.modes.contains(TraverseMode.BICYCLE)) {
            rr.dominanceFunction = new DominanceFunction.EarliestArrival();
            rr.worstTime = rr.dateTime + request.maxBikeTime * 60;
        } else {
            // We use walk-distance limiting and a least-walk dominance function in order to be consistent with egress walking
            // which is implemented this way because walk times can change when walk speed changes. Also, walk times are floating
            // point and can change slightly when streets are split. Street lengths are internally fixed-point ints, which do not
            // suffer from roundoff. Great care is taken when splitting to preserve sums.
            // When cycling, this is not an issue; we already have an explicitly asymmetrical search (cycling at the origin, walking at the destination),
            // so we need not preserve symmetry.
            // We use the max walk time for the search at the origin, but we clamp it to MAX_WALK_METERS so that we don;t
            // have every transit stop in the state as an initial transit stop if someone sets max walk time to four days,
            // and so that symmetry is preserved.
            // FIXME kind of arbitrary
            rr.maxWalkDistance = Math.min(request.maxWalkTime * 60 * request.walkSpeed, GraphIndex.MAX_WALK_METERS);
            rr.softWalkLimiting = false;
            rr.dominanceFunction = new DominanceFunction.LeastWalk();
        }
    }
    rr.numItineraries = 1;
    rr.longDistance = true;
    AStar aStar = new AStar();
    preTransitSpt = aStar.getShortestPathTree(rr, 5);
    // otherwise return null and leave preTransitSpt around for later use.
    if (data != null) {
        TIntIntMap accessTimes = data.findStopsNear(preTransitSpt, graph, rr.modes.contains(TraverseMode.BICYCLE), request.walkSpeed);
        LOG.info("Found {} transit stops", accessTimes.size());
        return accessTimes;
    } else {
        return null;
    }
}
Also used : AStar(org.opentripplanner.routing.algorithm.AStar) GenericLocation(org.opentripplanner.common.model.GenericLocation) QualifiedModeSet(org.opentripplanner.api.parameter.QualifiedModeSet) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) DominanceFunction(org.opentripplanner.routing.spt.DominanceFunction) TIntIntMap(gnu.trove.map.TIntIntMap) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with TIntIntMap

use of gnu.trove.map.TIntIntMap in project OpenTripPlanner by opentripplanner.

the class InitialStopsTest method testInitialStopWalkSpeedIncrease.

/**
 * Test that increasing the walk speed on a walk-to-transit search
 * a) decreases or leaves unchanged all access times.
 * b) allows access to a superset of the originally accessible stops.
 * c) decreases at least some access times.
 *
 * There was once a bug where bike speed was not correctly applied because we used the distance not the speed.
 */
@Test
public void testInitialStopWalkSpeedIncrease() throws Exception {
    Graph g = buildGraphNoTransit();
    addRegularStopGrid(g);
    addTransitMultipleLines(g);
    link(g);
    g.index(new DefaultStreetVertexIndexFactory());
    ProfileRequest req = new ProfileRequest();
    req.fromLon = req.toLon = -83.0118;
    req.fromLat = req.toLat = 39.9908;
    req.date = new LocalDate(2015, 9, 17);
    req.bikeSpeed = 4.1f;
    req.walkSpeed = 1.3f;
    req.fromTime = 7 * 3600;
    req.toTime = 9 * 3600;
    req.maxBikeTime = 20;
    req.maxWalkTime = 20;
    req.transitModes = new TraverseModeSet("TRANSIT");
    req.accessModes = req.egressModes = req.directModes = new QualifiedModeSet("WALK");
    RaptorWorkerData data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
    assertNotNull(data);
    RepeatedRaptorProfileRouter rrpr = new RepeatedRaptorProfileRouter(g, req);
    TIntIntMap initialStops1 = rrpr.findInitialStops(false, data);
    assertFalse(initialStops1.isEmpty());
    // let's get crazy, set walk speed really high.
    req.walkSpeed = 25f;
    data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
    assertNotNull(data);
    rrpr = new RepeatedRaptorProfileRouter(g, req);
    TIntIntMap initialStops2 = rrpr.findInitialStops(false, data);
    // we should find decreases to at least some stops
    boolean foundDecreases = false;
    for (TIntIntIterator it = initialStops1.iterator(); it.hasNext(); ) {
        it.advance();
        // the reached stops from the faster search should be a superset of the reached stops from the slower search
        assertTrue(initialStops2.containsKey(it.key()));
        assertTrue("Found increase in travel time to stop", initialStops2.get(it.key()) <= it.value());
        foundDecreases = foundDecreases || initialStops2.get(it.key()) < it.value() - EPSILON;
    }
    assertTrue("No decreases were found due to increased walk speed", foundDecreases);
}
Also used : RepeatedRaptorProfileRouter(org.opentripplanner.profile.RepeatedRaptorProfileRouter) FakeGraph(org.opentripplanner.graph_builder.module.FakeGraph) Graph(org.opentripplanner.routing.graph.Graph) TIntIntIterator(gnu.trove.iterator.TIntIntIterator) TaskStatistics(org.opentripplanner.analyst.cluster.TaskStatistics) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) QualifiedModeSet(org.opentripplanner.api.parameter.QualifiedModeSet) RaptorWorkerData(org.opentripplanner.profile.RaptorWorkerData) DefaultStreetVertexIndexFactory(org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory) ProfileRequest(org.opentripplanner.profile.ProfileRequest) LocalDate(org.joda.time.LocalDate) TIntIntMap(gnu.trove.map.TIntIntMap) Test(org.junit.Test)

Example 3 with TIntIntMap

use of gnu.trove.map.TIntIntMap in project OpenTripPlanner by opentripplanner.

the class InitialStopsTest method testInitialStopBikeSpeedIncrease.

/**
 * Test that increasing the bike speed on a bike-to-transit search
 * a) decreases or leaves unchanged all access times.
 * b) allows access to a superset of the originally accessible stops.
 *
 * There was once a bug where bike speed was not correctly applied because we used the distance not the speed.
 */
@Test
public void testInitialStopBikeSpeedIncrease() throws Exception {
    Graph g = buildGraphNoTransit();
    addRegularStopGrid(g);
    addTransitMultipleLines(g);
    link(g);
    g.index(new DefaultStreetVertexIndexFactory());
    ProfileRequest req = new ProfileRequest();
    req.fromLon = req.toLon = -83.0118;
    req.fromLat = req.toLat = 39.9908;
    req.date = new LocalDate(2015, 9, 17);
    req.bikeSpeed = 4.1f;
    req.walkSpeed = 1.3f;
    req.fromTime = 7 * 3600;
    req.toTime = 9 * 3600;
    req.maxBikeTime = 20;
    req.transitModes = new TraverseModeSet("TRANSIT");
    req.accessModes = req.egressModes = req.directModes = new QualifiedModeSet("BICYCLE");
    RaptorWorkerData data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
    assertNotNull(data);
    RepeatedRaptorProfileRouter rrpr = new RepeatedRaptorProfileRouter(g, req);
    TIntIntMap initialStops1 = rrpr.findInitialStops(false, data);
    assertFalse(initialStops1.isEmpty());
    // let's get crazy, set bike speed really high.
    req.bikeSpeed = 25f;
    data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
    assertNotNull(data);
    rrpr = new RepeatedRaptorProfileRouter(g, req);
    TIntIntMap initialStops2 = rrpr.findInitialStops(false, data);
    // we should find decreases to at least some stops
    boolean foundDecreases = false;
    for (TIntIntIterator it = initialStops1.iterator(); it.hasNext(); ) {
        it.advance();
        // the reached stops from the faster search should be a superset of the reached stops from the slower search
        assertTrue(initialStops2.containsKey(it.key()));
        assertTrue("Found increase in travel time to stop", initialStops2.get(it.key()) <= it.value());
        foundDecreases = foundDecreases || initialStops2.get(it.key()) < it.value() - EPSILON;
    }
    assertTrue(foundDecreases);
}
Also used : RepeatedRaptorProfileRouter(org.opentripplanner.profile.RepeatedRaptorProfileRouter) FakeGraph(org.opentripplanner.graph_builder.module.FakeGraph) Graph(org.opentripplanner.routing.graph.Graph) TIntIntIterator(gnu.trove.iterator.TIntIntIterator) TaskStatistics(org.opentripplanner.analyst.cluster.TaskStatistics) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) QualifiedModeSet(org.opentripplanner.api.parameter.QualifiedModeSet) RaptorWorkerData(org.opentripplanner.profile.RaptorWorkerData) DefaultStreetVertexIndexFactory(org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory) ProfileRequest(org.opentripplanner.profile.ProfileRequest) LocalDate(org.joda.time.LocalDate) TIntIntMap(gnu.trove.map.TIntIntMap) Test(org.junit.Test)

Example 4 with TIntIntMap

use of gnu.trove.map.TIntIntMap in project BiomeTweaker by superckl.

the class PropertyDecorationPerChunk method get.

@Override
public Integer get(final Object obj) throws IllegalStateException, IllegalArgumentException {
    if (!(obj instanceof Biome))
        throw new IllegalArgumentException("Passed object is not an instance of Biome!");
    if (!BiomeEventHandler.getDecorationsPerChunk().containsKey(this.type))
        throw new IllegalStateException("Decoration " + this.type.name() + " has not been set for biome" + ((Biome) obj).getBiomeName() + "!");
    final int id = Biome.getIdForBiome((Biome) obj);
    final TIntIntMap map = BiomeEventHandler.getDecorationsPerChunk().get(this.type);
    if (!map.containsKey(id))
        throw new IllegalStateException("Decoration " + this.type.name() + " has not been set for biome" + ((Biome) obj).getBiomeName() + "!");
    return map.get(id);
}
Also used : Biome(net.minecraft.world.biome.Biome) TIntIntMap(gnu.trove.map.TIntIntMap)

Example 5 with TIntIntMap

use of gnu.trove.map.TIntIntMap in project OpenTripPlanner by opentripplanner.

the class RaptorWorker method runRaptor.

/**
 * @param accessTimes a map from transit stops to the time it takes to reach those stops
 * @param nonTransitTimes the time to reach all targets without transit. Targets can be vertices or points/samples.
 */
public PropagatedTimesStore runRaptor(Graph graph, TIntIntMap accessTimes, int[] nonTransitTimes, TaskStatistics ts) {
    long beginCalcTime = System.currentTimeMillis();
    TIntIntMap initialStops = new TIntIntHashMap();
    TIntIntIterator initialIterator = accessTimes.iterator();
    while (initialIterator.hasNext()) {
        initialIterator.advance();
        int stopIndex = initialIterator.key();
        int accessTime = initialIterator.value();
        initialStops.put(stopIndex, accessTime);
    }
    PropagatedTimesStore propagatedTimesStore = new PropagatedTimesStore(graph, this.req, data.nTargets);
    // optimization: if no schedules, only run Monte Carlo
    int fromTime = req.fromTime;
    int monteCarloDraws = MONTE_CARLO_COUNT_PER_MINUTE;
    if (!data.hasSchedules) {
        // only do one iteration
        fromTime = req.toTime - 60;
        monteCarloDraws = TOTAL_MONTE_CARLO_COUNT;
    }
    // if no frequencies, don't run Monte Carlo
    int iterations = (req.toTime - fromTime - 60) / 60 + 1;
    // if we multiply when we're not doing monte carlo, we'll end up with too many iterations.
    if (data.hasFrequencies)
        // we add 2 because we do two "fake" draws where we do min or max instead of a monte carlo draw
        iterations *= (monteCarloDraws + 2);
    ts.searchCount = iterations;
    // Iterate backward through minutes (range-raptor) taking a snapshot of router state after each call
    int[][] timesAtTargetsEachIteration = new int[iterations][data.nTargets];
    // for each iteration, whether it is the result of a schedule or Monte Carlo search, or whether it is an extrema.
    // extrema are not included in averages.
    boolean[] includeIterationInAverages = new boolean[iterations];
    Arrays.fill(includeIterationInAverages, true);
    // TODO don't hardwire timestep below
    ts.timeStep = 60;
    // times at targets from scheduled search
    int[] scheduledTimesAtTargets = new int[data.nTargets];
    Arrays.fill(scheduledTimesAtTargets, UNREACHED);
    // current iteration
    int iteration = 0;
    // FIXME this should be changed to tolerate a zero-width time range
    for (int departureTime = req.toTime - 60, n = 0; departureTime >= fromTime; departureTime -= 60, n++) {
        if (n % 15 == 0) {
            LOG.info("minute {}", n);
        }
        // run the scheduled search
        this.runRaptorScheduled(initialStops, departureTime);
        this.doPropagation(bestNonTransferTimes, scheduledTimesAtTargets, departureTime);
        // walking a block
        for (int i = 0; i < scheduledTimesAtTargets.length; i++) {
            if (nonTransitTimes[i] != UNREACHED && nonTransitTimes[i] + departureTime < scheduledTimesAtTargets[i])
                scheduledTimesAtTargets[i] = nonTransitTimes[i] + departureTime;
        }
        // run the frequency searches
        if (data.hasFrequencies) {
            for (int i = 0; i < monteCarloDraws + 2; i++) {
                // make copies for just this search. We need copies because we can't use dynamic
                // programming/range-raptor with randomized schedules
                int[] bestTimesCopy = Arrays.copyOf(bestTimes, bestTimes.length);
                int[] bestNonTransferTimesCopy = Arrays.copyOf(bestNonTransferTimes, bestNonTransferTimes.length);
                int[] previousPatternsCopy = Arrays.copyOf(previousPatterns, previousPatterns.length);
                // special cases: calculate the best and the worst cases as well
                // Note that this (intentionally) does not affect searches where the user has requested
                // an assumption other than RANDOM, or stops with transfer rules.
                RaptorWorkerTimetable.BoardingAssumption requestedBoardingAssumption = req.boardingAssumption;
                if (i == 0 && req.boardingAssumption == RaptorWorkerTimetable.BoardingAssumption.RANDOM) {
                    req.boardingAssumption = RaptorWorkerTimetable.BoardingAssumption.WORST_CASE;
                    // don't include extrema in averages
                    includeIterationInAverages[iteration] = false;
                } else if (i == 1 && req.boardingAssumption == RaptorWorkerTimetable.BoardingAssumption.RANDOM) {
                    req.boardingAssumption = RaptorWorkerTimetable.BoardingAssumption.BEST_CASE;
                    // don't include extrema in averages
                    includeIterationInAverages[iteration] = false;
                } else if (requestedBoardingAssumption == RaptorWorkerTimetable.BoardingAssumption.RANDOM)
                    // use a new Monte Carlo draw each time
                    // included in averages by default
                    offsets.randomize();
                this.runRaptorFrequency(departureTime, bestTimesCopy, bestNonTransferTimesCopy, previousPatternsCopy);
                req.boardingAssumption = requestedBoardingAssumption;
                // do propagation
                int[] frequencyTimesAtTargets = timesAtTargetsEachIteration[iteration++];
                System.arraycopy(scheduledTimesAtTargets, 0, frequencyTimesAtTargets, 0, scheduledTimesAtTargets.length);
                // updates timesAtTargetsEachIteration directly because it has a reference into the array.
                this.doPropagation(bestNonTransferTimesCopy, frequencyTimesAtTargets, departureTime);
                // convert to elapsed time
                for (int t = 0; t < frequencyTimesAtTargets.length; t++) {
                    if (frequencyTimesAtTargets[t] != UNREACHED)
                        frequencyTimesAtTargets[t] -= departureTime;
                }
            }
        } else {
            final int dt = departureTime;
            timesAtTargetsEachIteration[iteration++] = IntStream.of(scheduledTimesAtTargets).map(i -> i != UNREACHED ? i - dt : i).toArray();
        }
    }
    // iteration should be incremented past end of array by ++ in assignment above
    if (iteration != iterations)
        throw new IllegalStateException("Iterations did not completely fill output array");
    long calcTime = System.currentTimeMillis() - beginCalcTime;
    LOG.info("calc time {}sec", calcTime / 1000.0);
    LOG.info("  propagation {}sec", totalPropagationTime / 1000.0);
    LOG.info("  raptor {}sec", (calcTime - totalPropagationTime) / 1000.0);
    ts.propagation = (int) totalPropagationTime;
    ts.transitSearch = (int) (calcTime - totalPropagationTime);
    // dumpVariableByte(timesAtTargetsEachMinute);
    // we can use min_max here as we've also run it once with best case and worst case board,
    // so the best and worst cases are meaningful.
    propagatedTimesStore.setFromArray(timesAtTargetsEachIteration, includeIterationInAverages, PropagatedTimesStore.ConfidenceCalculationMethod.MIN_MAX);
    return propagatedTimesStore;
}
Also used : TIntIntIterator(gnu.trove.iterator.TIntIntIterator) TIntIntHashMap(gnu.trove.map.hash.TIntIntHashMap) TIntIntMap(gnu.trove.map.TIntIntMap)

Aggregations

TIntIntMap (gnu.trove.map.TIntIntMap)12 TIntIntHashMap (gnu.trove.map.hash.TIntIntHashMap)5 Test (org.junit.Test)4 FakeGraph (org.opentripplanner.graph_builder.module.FakeGraph)4 Graph (org.opentripplanner.routing.graph.Graph)4 DefaultStreetVertexIndexFactory (org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory)4 TIntIntIterator (gnu.trove.iterator.TIntIntIterator)3 QualifiedModeSet (org.opentripplanner.api.parameter.QualifiedModeSet)3 GenericLocation (org.opentripplanner.common.model.GenericLocation)3 AStar (org.opentripplanner.routing.algorithm.AStar)3 RoutingRequest (org.opentripplanner.routing.core.RoutingRequest)3 TIntArrayList (gnu.trove.list.array.TIntArrayList)2 BitSet (java.util.BitSet)2 LocalDate (org.joda.time.LocalDate)2 TaskStatistics (org.opentripplanner.analyst.cluster.TaskStatistics)2 ProfileRequest (org.opentripplanner.profile.ProfileRequest)2 RaptorWorkerData (org.opentripplanner.profile.RaptorWorkerData)2 RepeatedRaptorProfileRouter (org.opentripplanner.profile.RepeatedRaptorProfileRouter)2 State (org.opentripplanner.routing.core.State)2 TraverseModeSet (org.opentripplanner.routing.core.TraverseModeSet)2