diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterFactory.java b/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterFactory.java deleted file mode 100644 index 7fba53c4198..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.matsim.contrib.common.randomizedtransitrouter;/* *********************************************************************** * - * project: org.matsim.* - * RandomizedTransitRouterFacotry - * * - * *********************************************************************** * - * * - * copyright : (C) 2013 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -import org.matsim.core.config.Config; -import org.matsim.pt.router.*; -import org.matsim.pt.transitSchedule.api.TransitSchedule; - -import jakarta.inject.Inject; -import jakarta.inject.Provider; - - -/** - * @author dgrether - * - */ -public class RandomizingTransitRouterFactory implements Provider { - - private TransitRouterConfig trConfig; - private TransitSchedule schedule; - private TransitRouterNetwork routerNetwork; - - @Inject - RandomizingTransitRouterFactory(Config config, TransitSchedule schedule) { - this.trConfig = new TransitRouterConfig(config); - this.schedule = schedule; - this.routerNetwork = TransitRouterNetwork.createFromSchedule(schedule, trConfig.getBeelineWalkConnectionDistance()); - } - - @Override - public TransitRouter get() { - RandomizingTransitRouterTravelTimeAndDisutility ttCalculator = new RandomizingTransitRouterTravelTimeAndDisutility(trConfig); - ttCalculator.setDataCollection(RandomizingTransitRouterTravelTimeAndDisutility.DataCollection.randomizedParameters, true) ; - ttCalculator.setDataCollection(RandomizingTransitRouterTravelTimeAndDisutility.DataCollection.additionalInformation, false) ; - return new TransitRouterImpl(trConfig, new PreparedTransitSchedule(schedule), routerNetwork, ttCalculator, ttCalculator); - } - -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterModule.java b/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterModule.java deleted file mode 100644 index 1dc0dec0300..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterModule.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.matsim.contrib.common.randomizedtransitrouter;/* - * *********************************************************************** * - * * project: org.matsim.* - * * RandomizedTransitRouterModule.java - * * * - * * *********************************************************************** * - * * * - * * copyright : (C) 2015 by the members listed in the COPYING, * - * * LICENSE and WARRANTY file. * - * * email : info at matsim dot org * - * * * - * * *********************************************************************** * - * * * - * * This program is free software; you can redistribute it and/or modify * - * * it under the terms of the GNU General Public License as published by * - * * the Free Software Foundation; either version 2 of the License, or * - * * (at your option) any later version. * - * * See also COPYING, LICENSE and WARRANTY file * - * * * - * * *********************************************************************** - */ - -import org.matsim.core.controler.AbstractModule; -import org.matsim.pt.router.TransitRouter; - -public class RandomizingTransitRouterModule extends AbstractModule { - @Override - public void install() { - bind(TransitRouter.class).toProvider(RandomizingTransitRouterFactory.class); - } -} diff --git a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterTravelTimeAndDisutility.java b/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterTravelTimeAndDisutility.java deleted file mode 100644 index d75e386838e..00000000000 --- a/contribs/common/src/main/java/org/matsim/contrib/common/randomizedtransitrouter/RandomizingTransitRouterTravelTimeAndDisutility.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.matsim.contrib.common.randomizedtransitrouter;/* *********************************************************************** * - * project: org.matsim.* - * RandomizedTransitRouterNetworkTravelTimeAndDisutility2 - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.population.Person; -import org.matsim.core.gbl.MatsimRandom; -import org.matsim.pt.router.CustomDataManager; -import org.matsim.pt.router.TransitRouterConfig; -import org.matsim.pt.router.TransitRouterNetwork.TransitRouterNetworkLink; -import org.matsim.pt.router.TransitRouterNetworkTravelTimeAndDisutility; -import org.matsim.vehicles.Vehicle; - -import java.util.HashMap; -import java.util.Map; - - -/** - * When plugged into the transit router, will switch to a different, randomly generated combination of - * marginal utilities every time it is called for a new agent. - *

- * Comments: - * @author kai - * @author dgrether - * - */ -public class RandomizingTransitRouterTravelTimeAndDisutility extends TransitRouterNetworkTravelTimeAndDisutility { - - public enum DataCollection {randomizedParameters, additionalInformation} - private Id cachedPersonId = null ; - private final TransitRouterConfig originalTransitRouterConfig ; - - private double localMarginalUtilityOfTravelTimeWalk_utl_s = Double.NaN ; - private double localMarginalUtilityOfWaitingPt_utl_s = Double.NaN ; - private double localUtilityOfLineSwitch_utl = Double.NaN ; - private double localMarginalUtilityOfTravelTimePt_utl_s = Double.NaN ; - private double localMarginalUtilityOfTravelDistancePt_utl_m = Double.NaN ; - - private Map dataCollectionConfig = new HashMap() ; - private Map dataCollectionStrings = new HashMap() ; - - public RandomizingTransitRouterTravelTimeAndDisutility(TransitRouterConfig routerConfig) { - super(routerConfig); - - prepareDataCollection(); - - // make sure that some parameters are not zero since otherwise the randomization will not work: - - // marg utl time wlk should be around -3/h or -(3/3600)/sec. Give warning if not at least 1/3600: - if ( -routerConfig.getMarginalUtilityOfTravelTimeWalk_utl_s() < 1./3600. ) { - LogManager.getLogger(this.getClass()).warn( "marg utl of walk rather close to zero; randomization may not work") ; - } - // utl of line switch should be around -300sec or -0.5u. Give warning if not at least 0.1u: - if ( -routerConfig.getUtilityOfLineSwitch_utl() < 0.1 ) { - LogManager.getLogger(this.getClass()).warn( "utl of line switch rather close to zero; randomization may not work") ; - } - - this.originalTransitRouterConfig = routerConfig ; - - this.localMarginalUtilityOfTravelDistancePt_utl_m = routerConfig.getMarginalUtilityOfTravelDistancePt_utl_m(); - this.localMarginalUtilityOfTravelTimePt_utl_s = routerConfig.getMarginalUtilityOfTravelTimePt_utl_s() ; - this.localMarginalUtilityOfTravelTimeWalk_utl_s = routerConfig.getMarginalUtilityOfTravelTimeWalk_utl_s() ; -// this.localMarginalUtilityOfWaitingPt_utl_s = routerConfig.getMarginalUtilityOfTravelTimePt_utl_s() ; - this.localMarginalUtilityOfWaitingPt_utl_s = routerConfig.getMarginalUtilityOfWaitingPt_utl_s() ; - this.localUtilityOfLineSwitch_utl = routerConfig.getUtilityOfLineSwitch_utl() ; - } - public final String getDataCollectionString( DataCollection item ) { - return dataCollectionStrings.get(item).toString() ; - } - - @Override - public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, - final CustomDataManager dataManager) { - - regenerateUtilityParametersIfPersonHasChanged(person); - - double disutl; - if (((TransitRouterNetworkLink) link).getRoute() == null) { - // (this means that it is a transfer link (walk)) - - double transfertime = getLinkTravelTime(link, time, person, vehicle); - double waittime = this.originalTransitRouterConfig.getAdditionalTransferTime(); - - // say that the effective walk time is the transfer time minus some "buffer" - double walktime = transfertime - waittime; - - disutl = - walktime * localMarginalUtilityOfTravelTimeWalk_utl_s - - waittime * localMarginalUtilityOfWaitingPt_utl_s - - localUtilityOfLineSwitch_utl; - - } else { - - double offVehWaitTime = offVehicleWaitTime(link, time); - - double inVehTime = getLinkTravelTime(link,time, person, vehicle) - offVehWaitTime ; - - disutl = -inVehTime * this.localMarginalUtilityOfTravelTimePt_utl_s - - offVehWaitTime * this.localMarginalUtilityOfWaitingPt_utl_s - - link.getLength() * this.localMarginalUtilityOfTravelDistancePt_utl_m; - } - - if ( this.dataCollectionConfig.get(DataCollection.additionalInformation )) { - StringBuffer strb = this.dataCollectionStrings.get(DataCollection.additionalInformation ) ; - strb.append("also collecting additional information") ; - } - - return disutl; - } - - @Override - public double getWalkTravelDisutility(Person person, Coord coord, Coord toCoord) { - regenerateUtilityParametersIfPersonHasChanged(person); - return - getWalkTravelTime(person, coord, toCoord) * localMarginalUtilityOfTravelTimeWalk_utl_s ; - } - - public final void setDataCollection( DataCollection item, Boolean bbb ) { - LogManager.getLogger(this.getClass()).info( " settin data collection of " + item.toString() + " to " + bbb.toString() ) ; - dataCollectionConfig.put( item, bbb ) ; - } - - private void prepareDataCollection() { - for ( DataCollection dataCollection : DataCollection.values() ) { - switch ( dataCollection ) { - case randomizedParameters: - dataCollectionConfig.put( dataCollection, false ) ; - dataCollectionStrings.put( dataCollection, new StringBuffer() ) ; - break; - case additionalInformation: - dataCollectionConfig.put( dataCollection, false ) ; - dataCollectionStrings.put( dataCollection, new StringBuffer() ) ; - break; - } - } - } - - private void regenerateUtilityParametersIfPersonHasChanged(final Person person) { - if ( !person.getId().equals(this.cachedPersonId)) { - // yyyyyy probably not thread safe (?!?!) - - // person has changed, so ... - - // ... memorize new person id: - this.cachedPersonId = person.getId() ; - - // ... generate new random parameters: - { - double tmp = this.originalTransitRouterConfig.getMarginalUtilityOfTravelTimeWalk_utl_s() ; - tmp *= 5. * MatsimRandom.getRandom().nextDouble() ; - localMarginalUtilityOfTravelTimeWalk_utl_s = tmp ; - // yy if this becomes too small, they may walk the whole way (is it really clear why this can happen?) - } - { - double tmp = this.originalTransitRouterConfig.getUtilityOfLineSwitch_utl() ; - tmp *= 5. * MatsimRandom.getRandom().nextDouble() ; - localUtilityOfLineSwitch_utl = tmp ; - } - { - double tmp = this.originalTransitRouterConfig.getMarginalUtilityOfWaitingPt_utl_s(); - tmp *= 5. * MatsimRandom.getRandom().nextDouble(); - localMarginalUtilityOfWaitingPt_utl_s = tmp; - } - { - // (Conceptually, the following is not necessary, but empirically, it seems to help. kai, jan'13) - double tmp = this.originalTransitRouterConfig.getMarginalUtilityOfTravelTimePt_utl_s() ; - tmp *= 5. * MatsimRandom.getRandom().nextDouble(); - localMarginalUtilityOfTravelTimePt_utl_s = tmp; - } - - if ( this.dataCollectionConfig.get(DataCollection.randomizedParameters) ) { -// StringBuffer strb = this.dataCollectionStrings.get(DataCollection.randomizedParameters) ; -// strb.append - System.out.println("personId: " + person.getId() + - "; margUtlOfTimeWlk_h: " + this.localMarginalUtilityOfTravelTimeWalk_utl_s*3600. + - "; utlOfLineSwitch: " + this.localUtilityOfLineSwitch_utl + - "; margUtlOfWait_h: " + this.localMarginalUtilityOfWaitingPt_utl_s*3600. + - "; margUtlOfTimePt_h: " + this.localMarginalUtilityOfTravelTimePt_utl_s*3600. ) ; - } - } - } - -} diff --git a/matsim/src/main/java/org/matsim/pt/router/AbstractTransitRouter.java b/matsim/src/main/java/org/matsim/pt/router/AbstractTransitRouter.java deleted file mode 100644 index 87639032e8f..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/AbstractTransitRouter.java +++ /dev/null @@ -1,208 +0,0 @@ - -/* *********************************************************************** * - * project: org.matsim.* - * AbstractTransitRouter.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2019 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - - package org.matsim.pt.router; - -import java.util.ArrayList; -import java.util.List; - -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.TransportMode; -import org.matsim.api.core.v01.population.Leg; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.Route; -import org.matsim.core.network.NetworkUtils; -import org.matsim.core.population.PopulationUtils; -import org.matsim.core.population.routes.RouteUtils; -import org.matsim.core.router.TripStructureUtils; -import org.matsim.core.utils.misc.OptionalTime; -import org.matsim.pt.routes.DefaultTransitPassengerRoute; -import org.matsim.pt.routes.TransitPassengerRoute; - -public class AbstractTransitRouter { - - private TransitRouterConfig trConfig; - private TransitTravelDisutility travelDisutility; - - protected AbstractTransitRouter (TransitRouterConfig transitRouterConfig){ - this.trConfig = transitRouterConfig; - } - - protected AbstractTransitRouter(TransitRouterConfig config, TransitTravelDisutility transitTravelDisutility){ - this.trConfig = config; - this.travelDisutility = transitTravelDisutility; - } - - // a setter is required for default PT router, I dont see any other way to make AbstractTransitRouter 'general purpose'. - protected void setTransitTravelDisutility(TransitTravelDisutility transitTravelDisutility){ - this.travelDisutility = transitTravelDisutility; - } - - // methods - protected final double getWalkTime(Person person, Coord coord, Coord toCoord) { - return getTravelDisutility().getWalkTravelTime(person, coord, toCoord); - } - - protected final double getTransferTime(Person person, Coord coord, Coord toCoord) { - return getTravelDisutility().getWalkTravelTime(person, coord, toCoord) + this.getConfig().getAdditionalTransferTime(); - } - - /** - * TODO: Replace by FallbackRoutingModule?! - gl-nov'19 - */ - @Deprecated - protected final List createDirectWalkLegList(Person person, Coord fromCoord, Coord toCoord) { - List legs = new ArrayList<>(); - Leg leg = PopulationUtils.createLeg(TransportMode.walk); - double walkTime = getWalkTime(person, fromCoord, toCoord); - leg.setTravelTime(walkTime); - TripStructureUtils.setRoutingMode(leg, TransportMode.pt); - Route walkRoute = RouteUtils.createGenericRouteImpl(null, null); - walkRoute.setTravelTime(walkTime); - leg.setRoute(walkRoute); - legs.add(leg); - return legs; - } - - private Leg createAccessTransitWalkLeg(Coord fromCoord, RouteSegment routeSegement) { - Leg leg = this.createTransitWalkLeg(fromCoord, routeSegement.fromStop.getCoord()); - Route walkRoute = RouteUtils.createGenericRouteImpl(null, routeSegement.fromStop.getLinkId()); - walkRoute.setTravelTime(leg.getTravelTime().seconds()); - walkRoute.setDistance(trConfig.getBeelineDistanceFactor() * NetworkUtils.getEuclideanDistance(fromCoord, routeSegement.fromStop.getCoord())); - leg.setRoute(walkRoute); - return leg; - } - - private Leg createEgressTransitWalkLeg(RouteSegment routeSegement, Coord toCoord) { - Leg leg = this.createTransitWalkLeg(routeSegement.toStop.getCoord(), toCoord); - Route walkRoute = RouteUtils.createGenericRouteImpl(routeSegement.toStop.getLinkId(), null); - walkRoute.setTravelTime(leg.getTravelTime().seconds()); - walkRoute.setDistance(trConfig.getBeelineDistanceFactor() * NetworkUtils.getEuclideanDistance(routeSegement.toStop.getCoord(), toCoord)); - leg.setRoute(walkRoute); - return leg; - } - - private Leg createTransferTransitWalkLeg(RouteSegment routeSegement) { - Leg leg = this.createTransitWalkLeg(routeSegement.getFromStop().getCoord(), routeSegement.getToStop().getCoord()); - Route walkRoute = RouteUtils.createGenericRouteImpl(routeSegement.getFromStop().getLinkId(), routeSegement.getToStop().getLinkId()); -// walkRoute.setTravelTime(leg.getTravelTime() ); - // transit walk leg should include additional transfer time; Amit, Aug'17 - leg.setTravelTime( getTransferTime(null, routeSegement.getFromStop().getCoord(), routeSegement.getToStop().getCoord()) ); - walkRoute.setTravelTime(getTransferTime(null, routeSegement.getFromStop().getCoord(), routeSegement.getToStop().getCoord()) ); - walkRoute.setDistance(trConfig.getBeelineDistanceFactor() * NetworkUtils.getEuclideanDistance(routeSegement.fromStop.getCoord(), routeSegement.toStop.getCoord())); - leg.setRoute(walkRoute); - - return leg; - } - - protected List convertPassengerRouteToLegList(double departureTime, InternalTransitPassengerRoute p, Coord fromCoord, Coord toCoord, Person person) { - // convert the route into a sequence of legs - List legs = new ArrayList<>(); - - // access leg - Leg accessLeg; - // check if first leg extends walking distance - if (p.getRoute().get(0).getRouteTaken() == null) { - // route starts with transfer - extend initial walk to that stop - //TODO: what if first leg extends the walking distance to more than first routeSegment i.e., (accessLeg, transfer, transfer ...). Amit Jan'18 -// accessLeg = createTransitWalkLeg(fromCoord, p.getRoute().get(0).getToStop().getCoord()); - accessLeg = createAccessTransitWalkLeg(fromCoord, p.getRoute().get(0)); - p.getRoute().remove(0); - } else { - // do not extend it - add a regular walk leg - // -// accessLeg = createTransitWalkLeg(fromCoord, p.getRoute().get(0).getFromStop().getCoord()); - accessLeg = createAccessTransitWalkLeg(fromCoord, p.getRoute().get(0)); - } - - // egress leg - Leg egressLeg; - // check if first leg extends walking distance - if (p.getRoute().get(p.getRoute().size() - 1).getRouteTaken() == null) { - // route starts with transfer - extend initial walk to that stop -// egressLeg = createTransitWalkLeg(p.getRoute().get(p.getRoute().size() - 1).getFromStop().getCoord(), toCoord); - egressLeg = createEgressTransitWalkLeg(p.getRoute().get(p.getRoute().size() - 1), toCoord); - p.getRoute().remove(p.getRoute().size() - 1); - } else { - // do not extend it - add a regular walk leg - // access leg -// egressLeg = createTransitWalkLeg(p.getRoute().get(p.getRoute().size() - 1).getToStop().getCoord(), toCoord); - egressLeg = createEgressTransitWalkLeg(p.getRoute().get(p.getRoute().size() - 1), toCoord); - } - - - // add very first leg - legs.add(accessLeg); - - // route segments are now in pt-walk-pt sequence - for (RouteSegment routeSegement : p.getRoute()) { - if (routeSegement.getRouteTaken() == null) {// transfer - if (!routeSegement.fromStop.equals(routeSegement.toStop)) { // same to/from stop => no transfer. Amit Feb'18 - legs.add(createTransferTransitWalkLeg(routeSegement)); - } - } else { - // pt leg - legs.add(createTransitLeg(routeSegement)); - } - } - - // add last leg - legs.add(egressLeg); - - return legs; - } - - private Leg createTransitLeg(RouteSegment routeSegment) { - Leg leg = PopulationUtils.createLeg(TransportMode.pt); - - TransitPassengerRoute ptRoute = new DefaultTransitPassengerRoute( // - routeSegment.getFromStop().getLinkId(), routeSegment.getToStop().getLinkId(), // - routeSegment.getFromStop().getId(), routeSegment.getToStop().getId(), // - routeSegment.getLineTaken(), routeSegment.getRouteTaken() - ); - - ptRoute.setTravelTime(routeSegment.travelTime); - leg.setRoute(ptRoute); - - leg.setTravelTime(routeSegment.getTravelTime()); - return leg; - } - - private Leg createTransitWalkLeg(Coord fromCoord, Coord toCoord) { - Leg leg = PopulationUtils.createLeg(TransportMode.walk); - double walkTime = getWalkTime(null, fromCoord, toCoord); - leg.setTravelTime(walkTime); - return leg; - } - - protected final TransitRouterConfig getConfig() { - return trConfig; - } - - protected final double getWalkDisutility(Person person, Coord coord, Coord toCoord) { - return getTravelDisutility().getWalkTravelDisutility(person, coord, toCoord); - } - - protected final TransitTravelDisutility getTravelDisutility() { - return travelDisutility; - } - -} \ No newline at end of file diff --git a/matsim/src/main/java/org/matsim/pt/router/CustomDataManager.java b/matsim/src/main/java/org/matsim/pt/router/CustomDataManager.java deleted file mode 100644 index 52ced005624..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/CustomDataManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import java.util.HashMap; - -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Node; - -/** - * A helper class to store custom data for {@link TransitTravelDisutility} which can be used - * to e.g. keep track of paid fares during the routing process. - * The stored data will be invalidated for each new routing request. - * - * @author mrieser / senozon - */ -public class CustomDataManager { - - private final HashMap data = new HashMap(); - private Node fromNode = null; - private Node toNode = null; - - private Object tmpToNodeData = null; - - public void setToNodeCustomData(final Object data) { - this.tmpToNodeData = data; - } - - /** - * @param node - * @return the stored data for the given node, or null if there is no data stored yet. - */ - public Object getFromNodeCustomData() { - return this.data.get(this.fromNode); - } - - public void initForLink(final Link link) { - this.fromNode = link.getFromNode(); - this.toNode = link.getToNode(); - this.tmpToNodeData = null; - } - - public void storeTmpData() { - if (this.tmpToNodeData != null) { - this.data.put(this.toNode, this.tmpToNodeData); - } - } - - public void reset() { - this.data.clear(); - this.fromNode = null; - this.toNode = null; - this.tmpToNodeData = null; - } - -} diff --git a/matsim/src/main/java/org/matsim/pt/router/FakeFacility.java b/matsim/src/main/java/org/matsim/pt/router/FakeFacility.java deleted file mode 100644 index 00c2edade64..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/FakeFacility.java +++ /dev/null @@ -1,47 +0,0 @@ - -/* *********************************************************************** * - * project: org.matsim.* - * FakeFacility.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2019 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - - package org.matsim.pt.router; - -import java.util.Map; - -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.facilities.Facility; - -public final class FakeFacility implements Facility { - private Coord coord; - public FakeFacility( Coord coord ) { this.coord = coord ; } - @Override public Coord getCoord() { - return this.coord ; - } - - @Override - public Map getCustomAttributes() { - throw new RuntimeException("not implemented") ; - } - - @Override - public Id getLinkId() { - throw new RuntimeException("not implemented") ; - } - -} diff --git a/matsim/src/main/java/org/matsim/pt/router/InternalTransitPassengerRoute.java b/matsim/src/main/java/org/matsim/pt/router/InternalTransitPassengerRoute.java deleted file mode 100644 index 61f04a3f20a..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/InternalTransitPassengerRoute.java +++ /dev/null @@ -1,52 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2015 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import java.util.List; - -/** - * - * @author aneumann - * - */ -public class InternalTransitPassengerRoute { - - private final double cost; - private final List route; - - public InternalTransitPassengerRoute(double cost, List leastCostRoute) { - this.cost = cost; - this.route = leastCostRoute; - - } - - public double getTravelCost() { - return this.cost; - } - - public List getRoute() { - return this.route; - } - - @Override - public String toString() { - return "Cost: " + this.cost + " via " + this.route; - } -} diff --git a/matsim/src/main/java/org/matsim/pt/router/PreparedTransitSchedule.java b/matsim/src/main/java/org/matsim/pt/router/PreparedTransitSchedule.java index 0de8829631f..35a9c3c4131 100644 --- a/matsim/src/main/java/org/matsim/pt/router/PreparedTransitSchedule.java +++ b/matsim/src/main/java/org/matsim/pt/router/PreparedTransitSchedule.java @@ -29,19 +29,21 @@ import org.matsim.pt.transitSchedule.api.TransitSchedule; /** - * + * * Allows fast queries of a TransitSchedule for the next departure of a given route at a given stop, from a given point * in time. If you need further queries of a TransitSchedule, put them here! - * + * * (I renamed this class and put the TransitSchedule in the constructor to make the purpose clear. michaz '13) - * + * * Thread-safe. - * + * * @author mrieser * */ public class PreparedTransitSchedule { - + + final static double MIDNIGHT = 24.0*3600; + /* * This needs to be a ConcurrentHashMap since multiple threads might add * data concurrently. Alternatively, the map could be filled with data @@ -55,7 +57,7 @@ public class PreparedTransitSchedule { * Conceptually, an instance of this class wraps a TransitSchedule to optimize a function of it. */ public PreparedTransitSchedule(TransitSchedule schedule) { - + } @Deprecated @@ -65,20 +67,20 @@ public PreparedTransitSchedule(TransitSchedule schedule) { public PreparedTransitSchedule() { } - + public double getNextDepartureTime(final TransitRoute route, final TransitRouteStop stop, final double depTime) { - + double earliestDepartureTimeAtTerminus = depTime - stop.getDepartureOffset().seconds(); // This shifts my time back to the terminus. - - if (earliestDepartureTimeAtTerminus >= TransitRouterNetworkTravelTimeAndDisutility.MIDNIGHT) { - earliestDepartureTimeAtTerminus = earliestDepartureTimeAtTerminus % TransitRouterNetworkTravelTimeAndDisutility.MIDNIGHT; + + if (earliestDepartureTimeAtTerminus >= MIDNIGHT) { + earliestDepartureTimeAtTerminus = earliestDepartureTimeAtTerminus % MIDNIGHT; } if (earliestDepartureTimeAtTerminus < 0) { // this may happen when depTime < departureOffset, e.g. I want to start at 24:03, but the bus departs at 23:55 at terminus - earliestDepartureTimeAtTerminus += TransitRouterNetworkTravelTimeAndDisutility.MIDNIGHT; + earliestDepartureTimeAtTerminus += MIDNIGHT; } - + // this will search for the terminus departure that corresponds to my departure at the stop: double[] cache = sortedDepartureCache.get(route); if (cache == null) { @@ -102,14 +104,14 @@ public double getNextDepartureTime(final TransitRoute route, final TransitRouteS } double bestDepartureTime = cache[pos]; // (departure time at terminus) - + bestDepartureTime += stop.getDepartureOffset().seconds(); // (resulting departure time at stop) - + while (bestDepartureTime < depTime) { - bestDepartureTime += TransitRouterNetworkTravelTimeAndDisutility.MIDNIGHT; + bestDepartureTime += MIDNIGHT; // (add enough "MIDNIGHT"s until we are _after_ the desired departure time) } return bestDepartureTime; } -} \ No newline at end of file +} diff --git a/matsim/src/main/java/org/matsim/pt/router/RouteSegment.java b/matsim/src/main/java/org/matsim/pt/router/RouteSegment.java deleted file mode 100644 index f3a9199504c..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/RouteSegment.java +++ /dev/null @@ -1,73 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2015 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import org.matsim.api.core.v01.Id; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitRoute; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; - -/** - * - * @author aneumann - * - */ -public class RouteSegment { - - final TransitStopFacility fromStop; - final TransitStopFacility toStop; - final double travelTime; - final Id lineTaken; - final Id routeTaken; - - public RouteSegment(TransitStopFacility fromStop, TransitStopFacility toStop, double travelTime, Id lineTaken, Id routeTaken) { - this.fromStop = fromStop; - this.toStop = toStop; - this.travelTime = travelTime; - this.lineTaken = lineTaken; - this.routeTaken = routeTaken; - } - - @Override - public String toString() { - return "From: " + fromStop.getId() + " to " + toStop.getId() + " in " + travelTime + "s via " + routeTaken; - } - - public double getTravelTime() { - return travelTime; - } - - public TransitStopFacility getFromStop() { - return fromStop; - } - - public TransitStopFacility getToStop() { - return toStop; - } - - public Id getLineTaken() { - return lineTaken; - } - - public Id getRouteTaken() { - return routeTaken; - } -} - diff --git a/matsim/src/main/java/org/matsim/pt/router/TransitLeastCostPathTree.java b/matsim/src/main/java/org/matsim/pt/router/TransitLeastCostPathTree.java deleted file mode 100644 index 19bfbe2c2f1..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/TransitLeastCostPathTree.java +++ /dev/null @@ -1,534 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * TransitDijkstra.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2009 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.Node; -import org.matsim.api.core.v01.population.Person; -import org.matsim.core.router.InitialNode; -import org.matsim.core.router.util.DijkstraNodeData; -import org.matsim.core.router.util.LeastCostPathCalculator.Path; -import org.matsim.core.router.util.TravelTime; -import org.matsim.core.utils.collections.PseudoRemovePriorityQueue; -import org.matsim.core.utils.collections.RouterPriorityQueue; -import org.matsim.pt.router.TransitRouterNetwork.TransitRouterNetworkLink; -import org.matsim.pt.router.TransitRouterNetwork.TransitRouterNetworkNode; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitRoute; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; -import org.matsim.vehicles.Vehicle; - -/** - * This class is based on and similar to org.matsim.contrib.eventsBasedPTRouter.MultiNodeDijkstra - * - * In contrast to org.matsim.contrib.eventsBasedPTRouter.MultiNodeDijkstra, however, it stores the last - * LeastCostPathTree. It is, therefore, much faster than it, in cases where many routes - * starting with the same fromNode are calculated subsequently as every route from that - * fromCoord can be retrieved now without having to compute the tree again. - * - * Call createLeastCostPathTree(fromNodes, person, fromCoord) in order to create and cache the - * LeastCostPathTree. Every following call of getPath(toNodes) will return the leastCostPath - * from the fromNodes to the toNodes. - * - * The fromCoord you passed in createLeastCostPathTree operates as a primary key to determine - * if you are working with the LeastCostPathTree you think you are. You can just pass the - * original requested origin here. - * - * Please keep in mind, that you are responsible to order all queries in a way such that all - * those originating in the same fromCoord are done subsequently. Otherwise, the mentioned - * efficiency gain with not take effect. - * - * @author gthunig - */ -public class TransitLeastCostPathTree { - - /** - * The network on which we find routes. - */ - protected Network network; - - /** - * The cost calculator. Provides the cost for each link and time step. - */ - private final TransitTravelDisutility costFunction; - - /** - * The travel time calculator. Provides the travel time for each link and time step. - */ - private final TravelTime timeFunction; - - private final HashMap, DijkstraNodeData> nodeData; - private Person person = null; - private Vehicle vehicle = null; - private CustomDataManager customDataManager = new CustomDataManager(); - private Map fromNodes = null; - - private RouterPriorityQueue pendingNodes; - - public TransitLeastCostPathTree(final Network network, final TransitTravelDisutility costFunction, - final TravelTime timeFunction, - final Map fromNodes, final Person person) { - this.network = network; - this.costFunction = costFunction; - this.timeFunction = timeFunction; - - this.nodeData = new HashMap<>((int)(network.getNodes().size() * 1.1), 0.95f); - - //create tree - this.resetNetworkVisited(); - this.person = person; - this.customDataManager.reset(); - this.fromNodes = fromNodes; - - pendingNodes = (RouterPriorityQueue) createRouterPriorityQueue(); - for (Map.Entry entry : fromNodes.entrySet()) { - DijkstraNodeData data = getData(entry.getKey()); - visitNode(entry.getKey(), data, pendingNodes, entry.getValue().initialTime, entry.getValue().initialCost, null); - } - - // do the real work - while (pendingNodes.size() > 0) { - Node outNode = pendingNodes.poll(); - relaxNode(outNode, pendingNodes); - } - } - - public TransitLeastCostPathTree(final Network network, final TransitTravelDisutility costFunction, - final TravelTime timeFunction, - final Map fromNodes, final Map toNodes, - final Person person) { - this.network = network; - this.costFunction = costFunction; - this.timeFunction = timeFunction; - - this.nodeData = new HashMap<>((int)(network.getNodes().size() * 1.1), 0.95f); - - //create tree - this.resetNetworkVisited(); - this.person = person; - this.customDataManager.reset(); - this.fromNodes = fromNodes; - - pendingNodes = (RouterPriorityQueue) createRouterPriorityQueue(); - for (Map.Entry entry : fromNodes.entrySet()) { - DijkstraNodeData data = getData(entry.getKey()); - visitNode(entry.getKey(), data, pendingNodes, entry.getValue().initialTime, entry.getValue().initialCost, null); - } - - expandNodeData(toNodes); - } - - private int getIterationId() { -// TODO could delete all the now unnecessary occurrences of the IterationID especially in DijkstraNodeData and -// TODO replace it with a flag visited but that would interfere the useage of the MultiNodeDijkstra - return 0; - } - - /** - * Resets all nodes in the network as if they have not been visited yet. - */ - private void resetNetworkVisited() { - for (Node node : this.network.getNodes().values()) { - DijkstraNodeData data = getData(node); - data.resetVisited(); - } - } - - private void expandNodeData(final Map toNodes) { - Set endNodes = new HashSet<>(toNodes.keySet()); - double minCost = Double.POSITIVE_INFINITY; - - // do the real work - while (endNodes.size() > 0) { - Node outNode = pendingNodes.poll(); - - if (outNode == null) { - // seems we have no more nodes left, but not yet reached all endNodes... - endNodes.clear(); - } else { - DijkstraNodeData data = getData(outNode); - boolean isEndNode = endNodes.remove(outNode); - if (isEndNode) { - InitialNode initData = toNodes.get(outNode); - double cost = data.getCost() + initData.initialCost; - if (cost < minCost) { - minCost = cost; - } - } - if (data.getCost() > minCost) { - endNodes.clear(); // we can't get any better now - } else { - relaxNode(outNode, pendingNodes); - } - } - } - } - - /** - * Method to request the passenger route from the (cached) fromNodes to the passed toNodes. - * Should only be requested after calling createTransitLeastCostPathTree(). - * - * @param toNodes - * The nodes that are the next stops to the toCoord and you like to route to. - * - * @return - * the transitPassengerRoute between the fromNode and the toNode. - * Will be null if the route could not be found. - */ - public InternalTransitPassengerRoute getTransitPassengerRoute(final Map toNodes) { - //find the best node - double minCost = Double.POSITIVE_INFINITY; - Node minCostNode = null; - for (Map.Entry e : toNodes.entrySet()) { - Node currentNode = e.getKey(); - DijkstraNodeData r = this.nodeData.get(currentNode.getId()); - if (r == null) { - expandNodeData(toNodes); - } - DijkstraNodeData data = getData(currentNode); - InitialNode initData = e.getValue(); - double cost = data.getCost() + initData.initialCost; - if (data.getCost() != 0.0 || fromNodes.containsKey(currentNode)) { - if (cost < minCost) { - minCost = cost; - minCostNode = currentNode; - } - } - } - - if (minCostNode == null) { - return null; - } - - // now construct route segments, which are required for TransitPassengerRoute - List routeSegments = new ArrayList<>(); - - TransitRouterNetworkLink link = (TransitRouterNetworkLink) getData(minCostNode).getPrevLink(); - TransitRouterNetworkLink downstreamLink = null; - Node previousFromNode = minCostNode; - double transferCost = 0.; - - while (link != null) { - TransitRouterNetworkNode fromNode = link.fromNode; - TransitRouterNetworkNode toNode = link.toNode; - - double travelTime = getData(toNode).getTime() - getData(fromNode).getTime(); - Id transitLineId = null; - Id routeId = null; - - boolean isTransferLeg = false; - if (link.line==null) isTransferLeg = true; - else { - transitLineId = link.line.getId(); - routeId = link.route.getId(); - } - - if (downstreamLink==null && isTransferLeg) { - // continuous transfers: see TransitRouterImplTest.testDoubleWalk. - // Another possibility is that trip start with transfer itself, see TransitRouterImplTest.testDoubleWalkOnly. - double tempTravelTime = 0.; - TransitStopFacility toStop = null; - - if (routeSegments.size()==0) { // very first leg starts with transfer - toStop = toNode.stop.getStopFacility(); - } else { - RouteSegment routeSegment = routeSegments.remove(0); - travelTime = routeSegment.travelTime; - toStop = routeSegment.toStop; - } - - routeSegments.add(0, - new RouteSegment(fromNode.stop.getStopFacility(), - toStop, - tempTravelTime+travelTime, - transitLineId, - routeId)); - //not sure, if transferCost will be included for every transfer or not. Currently, transfer cost will be accumulated for every transfer. Amit Sep'17 - } else if (downstreamLink == null // very first pt leg or first pt leg after transfer - || isTransferLeg ) { - routeSegments.add(0, new RouteSegment( fromNode.stop.getStopFacility(), - toNode.stop.getStopFacility(), - travelTime, - transitLineId, - routeId - )); - } else if (downstreamLink.line.getId() == link.line.getId() && downstreamLink.route.getId() == link.route.getId() ){ - //same route --> update the top routeSegment - RouteSegment routeSegment = routeSegments.remove(0); - routeSegments.add(0, new RouteSegment(fromNode.stop.getStopFacility(), - routeSegment.toStop, - routeSegment.travelTime+travelTime, - transitLineId, - routeId)); - } - - if (isTransferLeg) { - // transfer cost - if ( ! (this.costFunction instanceof TransitRouterNetworkTravelTimeAndDisutility) ) { - throw new RuntimeException("TransitTravelDisutility is not instance of "+TransitRouterNetworkTravelTimeAndDisutility.class.getSimpleName() - +". An acc "); - } - - transferCost += ((TransitRouterNetworkTravelTimeAndDisutility) this.costFunction).defaultTransferCost(link, - Double.NEGATIVE_INFINITY,null,null); - - downstreamLink = null; - } else { - downstreamLink = link; - } - - previousFromNode = fromNode; - link = (TransitRouterNetworkLink) getData(fromNode).getPrevLink(); - } - - DijkstraNodeData startNodeData = getData(previousFromNode); - DijkstraNodeData toNodeData = getData(minCostNode); - - double cost = toNodeData.getCost() - startNodeData.getCost() - + this.fromNodes.get(previousFromNode).initialCost - + toNodes.get(minCostNode).initialCost - + transferCost; - - // if there is no connection found, getPath(...) return a path with nothing in it, however, I (and AN) think that it should throw null. Amit Sep'17 - if (routeSegments.size()==0) return null; - else return new InternalTransitPassengerRoute(cost, routeSegments); - } - - /** - * Method to request the path from the (cached) fromNodes to the passed toNodes. - * Should only be requested after calling createTransitLeastCostPathTree(). - * - * @param toNodes - * The nodes that are the next stops to the toCoord and you like to route to. - * - * @return - * the leastCostPath between the fromNode and the toNode. - * Will be null if the path could not be found. - */ - public Path getPath(final Map toNodes) { - - //find the best node - double minCost = Double.POSITIVE_INFINITY; - Node minCostNode = null; - for (Map.Entry e : toNodes.entrySet()) { - Node currentNode = e.getKey(); - DijkstraNodeData r = this.nodeData.get(currentNode.getId()); - if (r == null) { - expandNodeData(toNodes); - } - DijkstraNodeData data = getData(currentNode); - InitialNode initData = e.getValue(); - double cost = data.getCost() + initData.initialCost; - if (data.getCost() != 0.0 || fromNodes.containsKey(currentNode)) { - if (cost < minCost) { - minCost = cost; - minCostNode = currentNode; - } - } - } - - if (minCostNode == null) { - return null; - } - - // now construct the path - List nodes = new LinkedList<>(); - List links = new LinkedList<>(); - - nodes.add(0, minCostNode); - Link tmpLink = getData(minCostNode).getPrevLink(); - while (tmpLink != null) { - links.add(0, tmpLink); - nodes.add(0, tmpLink.getFromNode()); - tmpLink = getData(tmpLink.getFromNode()).getPrevLink(); - } - - DijkstraNodeData startNodeData = getData(nodes.get(0)); - DijkstraNodeData toNodeData = getData(minCostNode); - - return new Path(nodes, links, toNodeData.getTime() - startNodeData.getTime(), - toNodeData.getCost() - startNodeData.getCost()); - } - - /** - * Allow replacing the RouterPriorityQueue. - */ - @SuppressWarnings("static-method") - /*package*/ RouterPriorityQueue createRouterPriorityQueue() { - return new PseudoRemovePriorityQueue<>(500); - } - - /** - * Inserts the given Node n into the pendingNodes queue and updates its time - * and cost information. - * - * @param n - * The Node that is revisited. - * @param data - * The data for n. - * @param pendingNodes - * The nodes visited and not processed yet. - * @param time - * The time of the visit of n. - * @param cost - * The accumulated cost at the time of the visit of n. - * @param outLink - * The node from which we came visiting n. - */ - protected void visitNode(final Node n, final DijkstraNodeData data, - final RouterPriorityQueue pendingNodes, final double time, final double cost, - final Link outLink) { - data.visit(outLink, cost, time, getIterationId()); - pendingNodes.add(n, getPriority(data)); - } - - /** - * Expands the given Node in the routing algorithm; may be overridden in - * sub-classes. - * - * @param outNode - * The Node to be expanded. - * @param pendingNodes - * The set of pending nodes so far. - */ - protected void relaxNode(final Node outNode, final RouterPriorityQueue pendingNodes) { - - DijkstraNodeData outData = getData(outNode); - double currTime = outData.getTime(); - double currCost = outData.getCost(); - for (Link l : outNode.getOutLinks().values()) { - relaxNodeLogic(l, pendingNodes, currTime, currCost); - } - } - - /** - * Logic that was previously located in the relaxNode(...) method. - * By doing so, the FastDijkstra can overwrite relaxNode without copying the logic. - */ - /*package*/ void relaxNodeLogic(final Link l, final RouterPriorityQueue pendingNodes, - final double currTime, final double currCost) { - addToPendingNodes(l, l.getToNode(), pendingNodes, currTime, currCost); - } - - /** - * Adds some parameters to the given Node then adds it to the set of pending - * nodes. - * - * @param l - * The link from which we came to this Node. - * @param n - * The Node to add to the pending nodes. - * @param pendingNodes - * The set of pending nodes. - * @param currTime - * The time at which we started to traverse l. - * @param currCost - * The cost at the time we started to traverse l. - * @return true if the node was added to the pending nodes, false otherwise - * (e.g. when the same node already has an earlier visiting time). - */ - protected boolean addToPendingNodes(final Link l, final Node n, - final RouterPriorityQueue pendingNodes, final double currTime, - final double currCost) { - - this.customDataManager.initForLink(l); - double travelTime = this.timeFunction.getLinkTravelTime(l, currTime, this.person, this.vehicle); - double travelCost = this.costFunction.getLinkTravelDisutility(l, currTime, this.person, this.vehicle, this.customDataManager); - DijkstraNodeData data = getData(n); - double nCost = data.getCost(); - if (!data.isVisited(getIterationId())) { - visitNode(n, data, pendingNodes, currTime + travelTime, currCost + travelCost, l); - this.customDataManager.storeTmpData(); - return true; - } - double totalCost = currCost + travelCost; - if (totalCost < nCost) { - revisitNode(n, data, pendingNodes, currTime + travelTime, totalCost, l); - this.customDataManager.storeTmpData(); - return true; - } - - return false; - } - - /** - * Changes the position of the given Node n in the pendingNodes queue and - * updates its time and cost information. - * - * @param n - * The Node that is revisited. - * @param data - * The data for n. - * @param pendingNodes - * The nodes visited and not processed yet. - * @param time - * The time of the visit of n. - * @param cost - * The accumulated cost at the time of the visit of n. - * @param outLink - * The link from which we came visiting n. - */ - void revisitNode(final Node n, final DijkstraNodeData data, - final RouterPriorityQueue pendingNodes, final double time, final double cost, - final Link outLink) { - pendingNodes.remove(n); - - data.visit(outLink, cost, time, getIterationId()); - pendingNodes.add(n, getPriority(data)); - } - - /** - * The value used to sort the pending nodes during routing. - * This implementation compares the total effective travel cost - * to sort the nodes in the pending nodes queue during routing. - */ - private double getPriority(final DijkstraNodeData data) { - return data.getCost(); - } - - /** - * Returns the data for the given node. Creates a new NodeData if none exists - * yet. - * - * @param n - * The Node for which to return the data. - * @return The data for the given Node - */ - protected DijkstraNodeData getData(final Node n) { - DijkstraNodeData r = this.nodeData.get(n.getId()); - if (null == r) { - r = new DijkstraNodeData(); - this.nodeData.put(n.getId(), r); - } - return r; - } - -} diff --git a/matsim/src/main/java/org/matsim/pt/router/TransitRouter.java b/matsim/src/main/java/org/matsim/pt/router/TransitRouter.java index 7fbe8110802..a2318e18052 100644 --- a/matsim/src/main/java/org/matsim/pt/router/TransitRouter.java +++ b/matsim/src/main/java/org/matsim/pt/router/TransitRouter.java @@ -29,6 +29,6 @@ */ public interface TransitRouter { - public abstract List calcRoute(RoutingRequest request); + List calcRoute(RoutingRequest request); } diff --git a/matsim/src/main/java/org/matsim/pt/router/TransitRouterImpl.java b/matsim/src/main/java/org/matsim/pt/router/TransitRouterImpl.java deleted file mode 100644 index 716490a972f..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/TransitRouterImpl.java +++ /dev/null @@ -1,188 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * TranitRouter.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2009 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.network.Node; -import org.matsim.api.core.v01.population.Leg; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.core.router.InitialNode; -import org.matsim.core.router.RoutingRequest; -import org.matsim.core.router.util.TravelTime; -import org.matsim.core.utils.geometry.CoordUtils; -import org.matsim.facilities.Facility; -import org.matsim.pt.transitSchedule.api.TransitSchedule; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Not thread-safe because MultiNodeDijkstra is not. Does not expect the TransitSchedule to change once constructed! michaz '13 - * - * @author mrieser - */ -public class TransitRouterImpl extends AbstractTransitRouter implements TransitRouter { - - private final TransitRouterNetwork transitNetwork; - private final TravelTime travelTime; - private final TransitTravelDisutility travelDisutility; - private final PreparedTransitSchedule preparedTransitSchedule; - - private boolean cacheTree; - private TransitLeastCostPathTree tree; - private Facility previousFromFacility; - private double previousDepartureTime; - - public TransitRouterImpl(final TransitRouterConfig trConfig, final TransitSchedule schedule) { - super(trConfig); - this.transitNetwork = TransitRouterNetwork.createFromSchedule(schedule, - trConfig.getBeelineWalkConnectionDistance()); - this.preparedTransitSchedule = new PreparedTransitSchedule(schedule); - TransitRouterNetworkTravelTimeAndDisutility transitRouterNetworkTravelTimeAndDisutility = new TransitRouterNetworkTravelTimeAndDisutility( - trConfig, - new PreparedTransitSchedule(schedule)); - this.travelDisutility = transitRouterNetworkTravelTimeAndDisutility; - this.travelTime = transitRouterNetworkTravelTimeAndDisutility; - setTransitTravelDisutility(this.travelDisutility); - - this.cacheTree = trConfig.isCacheTree(); - } - - public TransitRouterImpl( - final TransitRouterConfig trConfig, - final PreparedTransitSchedule preparedTransitSchedule, - final TransitRouterNetwork routerNetwork, - final TravelTime travelTime, - final TransitTravelDisutility travelDisutility) { - - super(trConfig, travelDisutility); - - this.transitNetwork = routerNetwork; - this.preparedTransitSchedule = preparedTransitSchedule; - this.travelDisutility = travelDisutility; - this.travelTime = travelTime; - - this.cacheTree = trConfig.isCacheTree(); - } - - private Map locateWrappedNearestTransitNodes(Person person, Coord coord, double departureTime) { - Collection nearestNodes = getTransitRouterNetwork().getNearestNodes( - coord, - this.getConfig().getSearchRadius()); - if (nearestNodes.size() < 2) { - // also enlarge search area if only one stop found, maybe a second one is near the border of the search area - TransitRouterNetwork.TransitRouterNetworkNode nearestNode = this.getTransitRouterNetwork() - .getNearestNode(coord); - if (nearestNode != null) { // transit schedule might be completely empty! - double distance = CoordUtils.calcEuclideanDistance(coord, - nearestNode.stop.getStopFacility().getCoord()); - nearestNodes = this.getTransitRouterNetwork() - .getNearestNodes(coord, distance + this.getConfig().getExtensionRadius()); - } - } - Map wrappedNearestNodes = new LinkedHashMap<>(); - for (TransitRouterNetwork.TransitRouterNetworkNode node : nearestNodes) { - Coord toCoord = node.stop.getStopFacility().getCoord(); - double initialTime = getWalkTime(person, coord, toCoord); - double initialCost = getWalkDisutility(person, coord, toCoord); - wrappedNearestNodes.put(node, new InitialNode(initialCost, initialTime + departureTime)); - } - return wrappedNearestNodes; - } - - @Override - public List calcRoute( final RoutingRequest request ) { - final Facility fromFacility = request.getFromFacility(); - final Facility toFacility = request.getToFacility(); - final double departureTime = request.getDepartureTime(); - final Person person = request.getPerson(); - - // find possible start stops - Map wrappedFromNodes = this.locateWrappedNearestTransitNodes(person, - fromFacility.getCoord(), - departureTime); - - - // find possible end stops - Map wrappedToNodes = this.locateWrappedNearestTransitNodes(person, - toFacility.getCoord(), - departureTime); - - InternalTransitPassengerRoute transitPassengerRoute = null; - - if (cacheTree) { - if ((fromFacility != previousFromFacility) && (departureTime != previousDepartureTime)) { // Compute tree only if fromFacility and departure time are different from previous request. - tree = new TransitLeastCostPathTree(getTransitRouterNetwork(), - getTravelDisutility(), - getTravelTime(), - wrappedFromNodes, - person); - } - } else { // Compute new tree for every routing request - tree = new TransitLeastCostPathTree(getTransitRouterNetwork(), - getTravelDisutility(), - getTravelTime(), - wrappedFromNodes, - wrappedToNodes, - person); - // yyyyyy This sounds like it is doing the full tree. But I think it is not. Kai, nov'16 - // Yes, only if you leave out the wrappedToNodes from the argument list, it does compute the full tree. See the new case above. dz, june'18 - } - - // find routes between start and end stop - transitPassengerRoute = tree.getTransitPassengerRoute(wrappedToNodes); - - if (transitPassengerRoute == null) { - return null; // TripRouter / FallbackRoutingModule will create a direct walk leg - } - double pathCost = transitPassengerRoute.getTravelCost(); - - double directWalkCost = getWalkDisutility(person, fromFacility.getCoord(), toFacility.getCoord()); - - if (directWalkCost * getConfig().getDirectWalkFactor() < pathCost) { - return null; // TripRouter / FallbackRoutingModule will create a direct walk leg - } - - previousFromFacility = fromFacility; - previousDepartureTime = departureTime; - - return convertPassengerRouteToLegList(departureTime, - transitPassengerRoute, - fromFacility.getCoord(), - toFacility.getCoord(), - person); - } - - public TransitRouterNetwork getTransitRouterNetwork() { - return transitNetwork; - } - - TravelTime getTravelTime() { - return travelTime; - } - - PreparedTransitSchedule getPreparedTransitSchedule() { - return preparedTransitSchedule; - } -} diff --git a/matsim/src/main/java/org/matsim/pt/router/TransitRouterNetwork.java b/matsim/src/main/java/org/matsim/pt/router/TransitRouterNetwork.java deleted file mode 100644 index 3ecc02f77dd..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/TransitRouterNetwork.java +++ /dev/null @@ -1,488 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * TransitRouterNetwork.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2009 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.NetworkFactory; -import org.matsim.api.core.v01.network.Node; -import org.matsim.core.utils.collections.IdentifiableArrayMap; -import org.matsim.core.utils.collections.QuadTree; -import org.matsim.core.utils.collections.Tuple; -import org.matsim.core.utils.geometry.CoordUtils; -import org.matsim.core.utils.misc.Counter; -import org.matsim.core.utils.misc.Time; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitRoute; -import org.matsim.pt.transitSchedule.api.TransitRouteStop; -import org.matsim.pt.transitSchedule.api.TransitSchedule; -import org.matsim.utils.objectattributes.attributable.Attributes; - -/** - * Converting the TransitRouterNetwork into a {@link org.matsim.core.router.util.RoutingNetwork} might - * speed up the routing and additionally reduce the memory consumption (e.g. by using array for a nodes - * in- and outgoing links). cdobler, nov'12 - * - * @author mrieser - * @author nagel - */ -public final class TransitRouterNetwork implements Network { - - private final static Logger log = LogManager.getLogger(TransitRouterNetwork.class); - - private final Map, TransitRouterNetworkLink> links = new LinkedHashMap<>(); - private final Map, TransitRouterNetworkNode> nodes = new LinkedHashMap<>(); - private QuadTree qtNodes = null; - - private long nextNodeId = 0; - private long nextLinkId = 0; - - - public static final class TransitRouterNetworkNode implements Node { - - public final TransitRouteStop stop; - public final TransitRoute route; - public final TransitLine line; - final Id id; - final Map, TransitRouterNetworkLink> ingoingLinks = new IdentifiableArrayMap<>(); - final Map, TransitRouterNetworkLink> outgoingLinks = new IdentifiableArrayMap<>(); - - public TransitRouterNetworkNode(final Id id, final TransitRouteStop stop, final TransitRoute route, final TransitLine line) { - this.id = id; - this.stop = stop; - this.route = route; - this.line = line; - } - - @Override - public Map, ? extends Link> getInLinks() { - return this.ingoingLinks; - } - - @Override - public Map, ? extends Link> getOutLinks() { - return this.outgoingLinks; - } - - @Override - public boolean addInLink(final Link link) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addOutLink(final Link link) { - throw new UnsupportedOperationException(); - } - - @Override - public Coord getCoord() { - return this.stop.getStopFacility().getCoord(); - } - - @Override - public Id getId() { - return this.id; - } - - public TransitRouteStop getStop() { - return stop; - } - - public TransitRoute getRoute() { - return route; - } - - public TransitLine getLine() { - return line; - } - - @Override - public String toString() { - return this.id.toString(); - } - - @Override - public Link removeInLink(Id linkId) { - throw new RuntimeException("not implemented") ; - } - - @Override - public Link removeOutLink(Id outLinkId) { - throw new RuntimeException("not implemented") ; - } - - @Override - public void setCoord(Coord coord) { - throw new RuntimeException("not implemented") ; - } - - @Override - public Attributes getAttributes() { - throw new UnsupportedOperationException(); - } - } - - /** - * Looks to me like an implementation of the Link interface, with get(Transit)Route and get(Transit)Line on top. - * To recall: TransitLine is something like M44. But it can have more than one route, e.g. going north, going south, - * long route, short route. That is, presumably we have one such TransitRouterNetworkLink per TransitRoute. kai/manuel, feb'12 - */ - public static final class TransitRouterNetworkLink implements Link { - - public final TransitRouterNetworkNode fromNode; - public final TransitRouterNetworkNode toNode; - final TransitRoute route; - final TransitLine line; - final Id id; - private final double length; - - public TransitRouterNetworkLink(final Id id, final TransitRouterNetworkNode fromNode, final TransitRouterNetworkNode toNode, final TransitRoute route, final TransitLine line, double length) { - this.id = id; - this.fromNode = fromNode; - this.toNode = toNode; - this.route = route; - this.line = line; - this.length = length; - } - - public TransitRouterNetworkLink(final Id id, final TransitRouterNetworkNode fromNode, final TransitRouterNetworkNode toNode, final TransitRoute route, final TransitLine line) { - this(id, fromNode, toNode, route, line, CoordUtils.calcEuclideanDistance(toNode.stop.getStopFacility().getCoord(), fromNode.stop.getStopFacility().getCoord())); - } - - @Override - public TransitRouterNetworkNode getFromNode() { - return this.fromNode; - } - - @Override - public TransitRouterNetworkNode getToNode() { - return this.toNode; - } - - @Override - public double getCapacity() { - return 9999; - } - - @Override - public double getCapacity(final double time) { - return getCapacity(); - } - - @Override - public double getFreespeed() { - return 10; - } - - @Override - public double getFreespeed(final double time) { - return getFreespeed(); - } - - @Override - public Id getId() { - return this.id; - } - - @Override - public double getNumberOfLanes() { - return 1; - } - - @Override - public double getNumberOfLanes(final double time) { - return getNumberOfLanes(); - } - - @Override - public double getLength() { - return this.length; - } - - @Override - public void setCapacity(final double capacity) { - throw new UnsupportedOperationException(); - } - - @Override - public void setFreespeed(final double freespeed) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setFromNode(final Node node) { - throw new UnsupportedOperationException(); - } - - @Override - public void setNumberOfLanes(final double lanes) { - throw new UnsupportedOperationException(); - } - - @Override - public void setLength(final double length) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean setToNode(final Node node) { - throw new UnsupportedOperationException(); - } - - @Override - public Coord getCoord() { - throw new UnsupportedOperationException(); - } - - @Override - public Set getAllowedModes() { - return null; - } - - @Override - public void setAllowedModes(final Set modes) { - throw new UnsupportedOperationException(); - } - - public TransitRoute getRoute() { - return route; - } - - public TransitLine getLine() { - return line; - } - - @Override - public String toString() { - return "[" + this.id.toString() + " (" + this.getFromNode().id + " > " + this.getToNode().id + ")]"; - } - - @Override - public double getCapacityPeriod() { - throw new UnsupportedOperationException(); - } - - @Override - public Attributes getAttributes() { - throw new UnsupportedOperationException(); - } - } - - public TransitRouterNetworkNode createNode(final TransitRouteStop stop, final TransitRoute route, final TransitLine line) { - final TransitRouterNetworkNode node = new TransitRouterNetworkNode(Id.create(this.nextNodeId++, Node.class), stop, route, line); - this.nodes.put(node.getId(), node); - return node; - } - - public TransitRouterNetworkLink createLink(final TransitRouterNetworkNode fromNode, final TransitRouterNetworkNode toNode, final TransitRoute route, final TransitLine line) { - final TransitRouterNetworkLink link = new TransitRouterNetworkLink(Id.create(this.nextLinkId++, Link.class), fromNode, toNode, route, line); - this.links.put(link.getId(), link); - fromNode.outgoingLinks.put(link.getId(), link); - toNode.ingoingLinks.put(link.getId(), link); - return link; - } - - @Override - public Map, ? extends TransitRouterNetworkNode> getNodes() { - return this.nodes; - } - - @Override - public Map, ? extends TransitRouterNetworkLink> getLinks() { - return this.links; - } - - public void finishInit() { - double minX = Double.POSITIVE_INFINITY; - double minY = Double.POSITIVE_INFINITY; - double maxX = Double.NEGATIVE_INFINITY; - double maxY = Double.NEGATIVE_INFINITY; - - for (TransitRouterNetworkNode node : this.nodes.values()) { - Coord c = node.stop.getStopFacility().getCoord(); - if (c.getX() < minX) { - minX = c.getX(); - } - if (c.getY() < minY) { - minY = c.getY(); - } - if (c.getX() > maxX) { - maxX = c.getX(); - } - if (c.getY() > maxY) { - maxY = c.getY(); - } - } - - QuadTree quadTree = new QuadTree(minX, minY, maxX, maxY); - for (TransitRouterNetworkNode node : this.nodes.values()) { - Coord c = node.stop.getStopFacility().getCoord(); - quadTree.put(c.getX(), c.getY(), node); - } - this.qtNodes = quadTree; - } - - public Collection getNearestNodes(final Coord coord, final double distance) { - return this.qtNodes.getDisk(coord.getX(), coord.getY(), distance); - } - - public TransitRouterNetworkNode getNearestNode(final Coord coord) { - return this.qtNodes.getClosest(coord.getX(), coord.getY()); - } - - @Override - public double getCapacityPeriod() { - return 3600.0; - } - - @Override - public NetworkFactory getFactory() { - return null; - } - - @Override - public double getEffectiveLaneWidth() { - return 3; - } - - @Override - public void addNode(Node nn) { - throw new UnsupportedOperationException(); - } - - @Override - public void addLink(Link ll) { - throw new UnsupportedOperationException(); - } - - @Override - public Link removeLink(Id linkId) { - throw new UnsupportedOperationException(); - } - - @Override - public Node removeNode(Id nodeId) { - throw new UnsupportedOperationException(); - } - - public static TransitRouterNetwork createFromSchedule(final TransitSchedule schedule, final double maxBeelineWalkConnectionDistance) { - log.info("start creating transit network"); - final TransitRouterNetwork network = new TransitRouterNetwork(); - final Counter linkCounter = new Counter(" link #"); - final Counter nodeCounter = new Counter(" node #"); - // build nodes and links connecting the nodes according to the transit routes - for (TransitLine line : schedule.getTransitLines().values()) { - for (TransitRoute route : line.getRoutes().values()) { - TransitRouterNetworkNode prevNode = null; - for (TransitRouteStop stop : route.getStops()) { - TransitRouterNetworkNode node = network.createNode(stop, route, line); - nodeCounter.incCounter(); - if (prevNode != null) { - network.createLink(prevNode, node, route, line); - linkCounter.incCounter(); - } - prevNode = node; - } - } - } - network.finishInit(); // not nice to call "finishInit" here before we added all links... - // in my view, it would be possible to completely do without finishInit: do the - // additions to the central data structures as items come in, not near the end. I would - // prefer that because nobody could forget the "finishInit". kai, apr'10 - // well, not really. finishInit creates the quadtree, for this, the extent must be known, - // which is not at the very start, so the quadtree data structure cannot be updated as - // links come in. mrieser, dec'10 - log.info("add transfer links"); - - List> toBeAdded = new LinkedList>(); - // connect all stops with walking links if they're located less than beelineWalkConnectionDistance from each other - for (TransitRouterNetworkNode node : network.getNodes().values()) { - if (node.getInLinks().size() > 0) { // only add links from this node to other nodes if agents actually can arrive here - for (TransitRouterNetworkNode node2 : network.getNearestNodes(node.stop.getStopFacility().getCoord(), maxBeelineWalkConnectionDistance)) { - if ((node != node2) && (node2.getOutLinks().size() > 0)) { // only add links to other nodes when agents can depart there - if ((node.line != node2.line) || (node.stop.getStopFacility() != node2.stop.getStopFacility())) { - // do not yet add them to the network, as this would change in/out-links - toBeAdded.add(new Tuple(node, node2)); - } - } - } - } - } - log.info(toBeAdded.size() + " transfer links to be added."); - for (Tuple tuple : toBeAdded) { - network.createLink(tuple.getFirst(), tuple.getSecond(), null, null); - linkCounter.incCounter(); - } - - log.info("transit router network statistics:"); - log.info(" # nodes: " + network.getNodes().size()); - log.info(" # links total: " + network.getLinks().size()); - log.info(" # transfer links: " + toBeAdded.size()); - - return network; - } - - @Override - public void setCapacityPeriod(double capPeriod) { - throw new RuntimeException("not implemented") ; - } - - @Override - public void setEffectiveCellSize(double effectiveCellSize) { - throw new RuntimeException("not implemented") ; - } - - @Override - public void setEffectiveLaneWidth(double effectiveLaneWidth) { - throw new RuntimeException("not implemented") ; - } - - @Override - public void setName(String name) { - throw new RuntimeException("not implemented") ; - } - - @Override - public String getName() { - throw new RuntimeException("not implemented") ; - } - - @Override - public double getEffectiveCellSize() { - throw new RuntimeException("not implemented") ; - } - - @Override - public Attributes getAttributes() { - throw new UnsupportedOperationException(); - } -} diff --git a/matsim/src/main/java/org/matsim/pt/router/TransitRouterNetworkTravelTimeAndDisutility.java b/matsim/src/main/java/org/matsim/pt/router/TransitRouterNetworkTravelTimeAndDisutility.java deleted file mode 100644 index 79de4237b65..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/TransitRouterNetworkTravelTimeAndDisutility.java +++ /dev/null @@ -1,219 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * TransitRouterNetworkCost.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2009 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.population.Person; -import org.matsim.core.router.util.TravelTime; -import org.matsim.core.utils.geometry.CoordUtils; -import org.matsim.pt.router.TransitRouterNetwork.TransitRouterNetworkLink; -import org.matsim.pt.transitSchedule.api.TransitRouteStop; -import org.matsim.vehicles.Vehicle; - -/** - * TravelTime and TravelCost calculator to be used with the transit network used for transit routing. - * - * This class is NOT thread-safe! - * - * @author mrieser - */ -public class TransitRouterNetworkTravelTimeAndDisutility implements TravelTime, TransitTravelDisutility { - - final static double MIDNIGHT = 24.0*3600; - - protected final TransitRouterConfig config; - private Link previousLink = null; - private double previousTime = Double.NaN; - private double cachedTravelTime = Double.NaN; - - private final PreparedTransitSchedule preparedTransitSchedule; - - /* - * If this constructor is used, every instance use its own PreparedTransitSchedule which might - * consume a lot of memory. - * - * cdobler, nov'12 - */ - @Deprecated - public TransitRouterNetworkTravelTimeAndDisutility(final TransitRouterConfig config) { - this(config, new PreparedTransitSchedule()); - } - - public TransitRouterNetworkTravelTimeAndDisutility(final TransitRouterConfig config, PreparedTransitSchedule preparedTransitSchedule) { - this.config = config; - this.preparedTransitSchedule = preparedTransitSchedule; - } - - @Override - public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, final CustomDataManager dataManager) { - double cost; - if (((TransitRouterNetworkLink) link).getRoute() == null) { - // "route" here means "pt route". If no pt route is attached, it means that it is a transfer link. - - cost = defaultTransferCost(link, time, person, vehicle); - - } else { - double offVehWaitTime = offVehicleWaitTime(link, time); - double inVehTime = getLinkTravelTime(link,time, person, vehicle) - offVehWaitTime; - cost = - inVehTime * this.config.getMarginalUtilityOfTravelTimePt_utl_s() - -offVehWaitTime * this.config.getMarginalUtilityOfWaitingPt_utl_s() - -link.getLength() * this.config.getMarginalUtilityOfTravelDistancePt_utl_m(); - - } - return cost; - } - - /** - * method to allow inclusion of offVehicleWaitTime without code replication. kai, oct'12 - * - * @param link - * @param time - * @return - */ - protected double offVehicleWaitTime(final Link link, final double time) { - double offVehWaitTime=0; - double nextVehArrivalTime = getVehArrivalTime(link, time); - if (time < nextVehArrivalTime){ // it means the agent waits outside the veh - offVehWaitTime = nextVehArrivalTime-time; - } - return offVehWaitTime; - - } - - /** - * convenience method for derived classes in order to bring Manuel's version closer to this one here. - * kai, oct'12 - */ - protected final double defaultTransferCost(final Link link, final double time, - final Person person, final Vehicle vehicle) { - double cost; - double transfertime = getLinkTravelTime(link, time, person, vehicle); - double waittime = this.config.getAdditionalTransferTime(); - - // say that the effective walk time is the transfer time minus some "buffer" - double walktime = transfertime - waittime; - // (this looks like walktime might become negative. But at least in the default version, the additional transfer time is always - // _added_ to the walk time (see getLinkTravelTime below) so at least in that case this cannot happen. kai, triggered by cd, may'16) - if ( walktime < 0. ) { - throw new RuntimeException( "negative walk time; should not happen; needs to be repaired" ) ; - } - - double walkDistance = link.getLength(); - - // weigh this "buffer" not with the walk time disutility, but with the wait time disutility: - // (note that this is the same "additional disutl of wait" as in the scoring function. Its default is zero. - // only if you are "including the opportunity cost of time into the router", then the disutility of waiting will - // be the same as the marginal opprotunity cost of time). kai, nov'11 - cost = - walktime * this.config.getMarginalUtilityOfTravelTimeWalk_utl_s() - - walkDistance * this.config.getMarginalUtilityOfTravelDistanceWalk_utl_m() - - waittime * this.config.getMarginalUtilityOfWaitingPt_utl_s() - - this.config.getUtilityOfLineSwitch_utl(); - return cost; - } - - @Override - public double getLinkTravelTime(final Link link, final double time, Person person, Vehicle vehicle) { - if ((link == this.previousLink) && (time == this.previousTime)) { - return this.cachedTravelTime; - } - this.previousLink = link; - this.previousTime = time; - - TransitRouterNetworkLink wrapped = (TransitRouterNetworkLink) link; - TransitRouteStop fromStop = wrapped.fromNode.stop; - TransitRouteStop toStop = wrapped.toNode.stop; - if (wrapped.route != null) { - // (agent stays on the same route, so use transit line travel time) - - // get the next departure time: - double bestDepartureTime = preparedTransitSchedule.getNextDepartureTime(wrapped.route, fromStop, time); - - // the travel time on the link is - // the time until the departure (``dpTime - now'') - // + the travel time on the link (there.arrivalTime - here.departureTime) - // But quite often, we only have the departure time at the next stop. Then we use that: - double arrivalOffset = toStop.getArrivalOffset().or(toStop::getDepartureOffset).seconds(); - double time2 = (bestDepartureTime - time) + (arrivalOffset - fromStop.getDepartureOffset().seconds()); - if (time2 < 0) { - // ( this can only happen, I think, when ``bestDepartureTime'' is after midnight but ``time'' was before ) - time2 += MIDNIGHT; - } - this.cachedTravelTime = time2; - return time2; - } - // different transit routes, so it must be a line switch - double distance = wrapped.getLength(); - double time2 = distance / this.config.getBeelineWalkSpeed() + this.config.getAdditionalTransferTime(); - this.cachedTravelTime = time2; - return time2; - } - - //variables for caching offVehWaitTime - Link previousWaitLink; - double previousWaitTime; - double cachedVehArrivalTime; - - public double getVehArrivalTime(final Link link, final double now){ - if ((link == this.previousWaitLink) && (now == this.previousWaitTime)) { - return this.cachedVehArrivalTime; - } - this.previousWaitLink = link; - this.previousWaitTime = now; - - //first find out vehicle arrival time to fromStop according to transit schedule - TransitRouterNetworkLink wrapped = (TransitRouterNetworkLink) link; - if (wrapped.getRoute() == null) { - throw new RuntimeException("should not happen") ; - } - TransitRouteStop fromStop = wrapped.fromNode.stop; - - double nextDepartureTime = preparedTransitSchedule.getNextDepartureTime(wrapped.getRoute(), fromStop, now); - - double fromStopDepartureOffset = fromStop.getDepartureOffset().seconds(); - double fromStopArrivalOffset = fromStop.getArrivalOffset().orElse(fromStopDepartureOffset); - double vehWaitAtStopTime = fromStopDepartureOffset - fromStopArrivalOffset; //time in which the veh stops at station - double vehArrivalTime = nextDepartureTime - vehWaitAtStopTime; - cachedVehArrivalTime = vehArrivalTime ; - return vehArrivalTime ; - } - - @Override - public double getWalkTravelDisutility(Person person, Coord coord, Coord toCoord) { - // getMarginalUtilityOfTravelTimeWalk INCLUDES the opportunity cost of time. kai, dec'12 - double timeCost = - getWalkTravelTime(person, coord, toCoord) * config.getMarginalUtilityOfTravelTimeWalk_utl_s() ; - // (sign: margUtl is negative; overall it should be positive because it is a cost.) - - double distanceCost = - CoordUtils.calcEuclideanDistance(coord,toCoord) * - config.getBeelineDistanceFactor() * config.getMarginalUtilityOfTravelDistanceWalk_utl_m(); - // (sign: same as above) - - return timeCost + distanceCost ; - } - - @Override - public double getWalkTravelTime(Person person, Coord coord, Coord toCoord) { - double distance = CoordUtils.calcEuclideanDistance(coord, toCoord); - double initialTime = distance / config.getBeelineWalkSpeed(); - return initialTime; - } - -} diff --git a/matsim/src/main/java/org/matsim/pt/router/TransitTravelDisutility.java b/matsim/src/main/java/org/matsim/pt/router/TransitTravelDisutility.java deleted file mode 100644 index e069df124b4..00000000000 --- a/matsim/src/main/java/org/matsim/pt/router/TransitTravelDisutility.java +++ /dev/null @@ -1,54 +0,0 @@ -/* *********************************************************************** * - * project: org.matsim.* - * * - * *********************************************************************** * - * * - * copyright : (C) 2012 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - -package org.matsim.pt.router; - -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.population.Person; -import org.matsim.vehicles.Vehicle; - -/** - * @author mrieser / senozon - */ -public interface TransitTravelDisutility { - - /** - * Returns the disutility to travel on the specified link at the specified time. - * - * @param link The link for which the travel disutility is calculated. - * @param time The departure time (in seconds since 00:00) at the beginning of the link for which the disutility is calculated. - * @param person The person that wants to travel along the link. Note that this parameter can be null! - * @param vehicle The vehicle with which the person wants to travel along the link. Note that this parameter can be null! - * @param dataManager A helper class to enable the cost calculator store arbitrary data during one routing request. - * @return The disutility to travel over the link link, departing at time time. - */ - public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, final CustomDataManager dataManager); - - /** - * This is used for walking to and from the nearest transit stop from the start and end location, - * as well as for the "direct" walk from start to finish without using a pt line at all. - * It is not used for transfer links (these are handled by the transitTravelDisutility). - */ - double getWalkTravelTime(Person person, Coord coord, Coord toCoord); - - double getWalkTravelDisutility(Person person, Coord coord, Coord toCoord); - - -} diff --git a/matsim/src/test/java/org/matsim/pt/router/TransitLeastCostPathTreeTest.java b/matsim/src/test/java/org/matsim/pt/router/TransitLeastCostPathTreeTest.java deleted file mode 100644 index b168007ee70..00000000000 --- a/matsim/src/test/java/org/matsim/pt/router/TransitLeastCostPathTreeTest.java +++ /dev/null @@ -1,239 +0,0 @@ - -/* *********************************************************************** * - * project: org.matsim.* - * TransitLeastCostPathTreeTest.java - * * - * *********************************************************************** * - * * - * copyright : (C) 2019 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ - - package org.matsim.pt.router; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.assertj.core.api.Assertions; -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; -import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.Id; -import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.network.Link; -import org.matsim.api.core.v01.network.Network; -import org.matsim.api.core.v01.network.Node; -import org.matsim.api.core.v01.population.Person; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.network.NetworkUtils; -import org.matsim.core.router.InitialNode; -import org.matsim.core.router.util.LeastCostPathCalculator.Path; -import org.matsim.core.router.util.TravelTime; -import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.pt.transitSchedule.api.TransitSchedule; -import org.matsim.pt.transitSchedule.api.TransitScheduleReader; -import org.matsim.testcases.MatsimTestUtils; -import org.matsim.vehicles.Vehicle; - -/** - * Junit Test for the TransitLeastCostPathTree. - * - * @author gabriel.thunig on 23.05.2016. - */ -public class TransitLeastCostPathTreeTest { - - private TransitRouterNetwork network; - private TransitRouterNetworkTravelTimeAndDisutility travelDisutility; - - /** - * Instantiates a new TransitLeastCostPathTree object with a sample transitSchedule and default configuration. - */ - public void instantiateNetworkAndTravelDisutility() { - String transitScheduleFile = "test/scenarios/pt-tutorial/transitschedule.xml"; - - Config config = ConfigUtils.createConfig(); - Scenario scenario = ScenarioUtils.loadScenario(config); - scenario.getConfig().transit().setUseTransit(true); - TransitScheduleReader reader = new TransitScheduleReader(scenario); - TransitRouterConfig transitRouterConfig = new TransitRouterConfig(scenario.getConfig()); - reader.readFile(transitScheduleFile); - TransitSchedule transitSchedule = scenario.getTransitSchedule(); - network = TransitRouterNetwork.createFromSchedule(transitSchedule, transitRouterConfig.getBeelineWalkConnectionDistance()); - - PreparedTransitSchedule preparedTransitSchedule = new PreparedTransitSchedule(transitSchedule); - travelDisutility = new TransitRouterNetworkTravelTimeAndDisutility(transitRouterConfig, preparedTransitSchedule); - } - - /** - * Check whether the @Before-instantiation is instantiating a network and a travelDisutility. - */ - @Test - public void TestNetworkAndTravelDisutilityInstantiated() { - instantiateNetworkAndTravelDisutility(); - Assert.assertNotNull(network); - Assert.assertNotNull(travelDisutility); - } - - /** - * Get the very next transitNode. - * @param person Which person we are routing for. For default leave null. - * @param coord The origin of the tree. - * @param departureTime The time the person departures at the origin. - * @return the next transitNode. - */ - private Map locateWrappedNearestTransitNode(Person person, Coord coord, double departureTime) { - TransitRouterNetwork.TransitRouterNetworkNode nearestNode = network.getNearestNode(coord); - Map wrappedNearestNodes = new LinkedHashMap<>(); - Coord toCoord = nearestNode.stop.getStopFacility().getCoord(); - double initialTime = travelDisutility.getWalkTravelTime(person, coord, toCoord); - double initialCost = travelDisutility.getWalkTravelDisutility(person, coord, toCoord); - wrappedNearestNodes.put(nearestNode, new InitialNode(initialCost, initialTime + departureTime)); - return wrappedNearestNodes; - } - - /** - * Try to route a standard connection. - */ - @Test - public void TestValidRouting() { - instantiateNetworkAndTravelDisutility(); - Coord fromCoord = new Coord(1050d, 1050d); - Map wrappedFromNodes = this.locateWrappedNearestTransitNode(null, fromCoord, 28800); - TransitLeastCostPathTree tree = new TransitLeastCostPathTree(network, travelDisutility, travelDisutility, wrappedFromNodes, null); - Coord toCoord = new Coord(3950d, 1050d); - Map wrappedToNodes = this.locateWrappedNearestTransitNode(null, toCoord, 28800); - Path path = tree.getPath(wrappedToNodes); - Assert.assertNotNull(path); - double pathCost = path.travelCost; - Assert.assertEquals(1.8d, pathCost, MatsimTestUtils.EPSILON); - double pathTime = path.travelTime; - Assert.assertEquals(540d, pathTime, MatsimTestUtils.EPSILON); - } - - /** - * Try to route a connection with interchange. - */ - @Test - public void TestValidRoutingWithInterchange() { - instantiateNetworkAndTravelDisutility(); - Coord fromCoord = new Coord(1050d, 1050d); - Map wrappedFromNodes = this.locateWrappedNearestTransitNode(null, fromCoord, 28800); - TransitLeastCostPathTree tree = new TransitLeastCostPathTree(network, travelDisutility, travelDisutility, wrappedFromNodes, null); - Coord toCoord = new Coord(2050d, 2960d); - Map wrappedToNodes = this.locateWrappedNearestTransitNode(null, toCoord, 28800); - Path path = tree.getPath(wrappedToNodes); - Assert.assertNotNull(path); - double pathCost = path.travelCost; - Assert.assertEquals(1.7706666666666668d, pathCost, MatsimTestUtils.EPSILON); - double pathTime = path.travelTime; - Assert.assertEquals(231.20000000000073d, pathTime, MatsimTestUtils.EPSILON); - } - - @Ignore - @Test - public void TestSpeedImprovementOnStopCriterion() { - Fixture f = new Fixture(); - TestTimeCost tc = new TestTimeCost(); - for (int i = 0; i < f.count-1; i++) { - tc.setData(Id.create(i, Link.class), 1.0, 1.0); - } - Map fromNodes = new HashMap<>(); - fromNodes.put(f.network.getNodes().get(Id.create(0, Node.class)), new InitialNode(0.0, 0.0)); - Map toNodes = new HashMap<>(); - toNodes.put(f.network.getNodes().get(Id.create(1, Node.class)), new InitialNode(0.0, 0.0)); - for (Node node : fromNodes.keySet()) { - System.out.println("From Node = " + node.getCoord()); - } - for (Node node : toNodes.keySet()) { - System.out.println("To Node = " + node.getCoord()); - } - long startTime = System.currentTimeMillis(); - new TransitLeastCostPathTree(f.network, tc, tc, fromNodes, null); - long endTime = System.currentTimeMillis(); - long elapsedTimeWithoutStopCreterion = (endTime - startTime); - startTime = System.currentTimeMillis(); - new TransitLeastCostPathTree(f.network, tc, tc, fromNodes, toNodes, null); - endTime = System.currentTimeMillis(); - long elapsedTimeWithStopCreterion = (endTime - startTime); - Double bareRatio = (double)elapsedTimeWithoutStopCreterion / (double)elapsedTimeWithStopCreterion; - System.out.println("bareRatio = " + bareRatio); - int ratio = (int) ((bareRatio) * 10); - System.out.println("Time without stop criterion = " + elapsedTimeWithoutStopCreterion); - System.out.println("Time with stop criterion = " + elapsedTimeWithStopCreterion); - System.out.println("ratio = " + ratio); - Assertions.assertThat(ratio).isGreaterThan(15); - } - - /** - * Creates a simple network to be used in TestSpeedImprovementOnStopCriterion. - * - *
-     *   (0)--(1)--(2)--...--(9997)--(9998)--(9999)
-     * 
- * - * @author gthunig - */ - /*package*/ static class Fixture { - /*package*/ Network network; - - int count = 10000; - - public Fixture() { - this.network = NetworkUtils.createNetwork(); - Node linkStartNode = NetworkUtils.createAndAddNode(this.network, Id.create(0, Node.class), new Coord((double) 0, (double) 0)); - for (int i = 1; i < count; i++) { - Node linkEndNode = NetworkUtils.createAndAddNode(this.network, Id.create(i, Node.class), new Coord((double) i, (double) 0)); - final Node fromNode = linkStartNode; - final Node toNode = linkEndNode; - NetworkUtils.createAndAddLink(this.network,Id.create(i-1, Link.class), fromNode, toNode, 1000.0, 10.0, 2000.0, (double) 1 ); - linkStartNode = linkEndNode; - } - - } - } - - /*package*/ static class TestTimeCost implements TravelTime, TransitTravelDisutility { - - private final Map, Double> travelTimes = new HashMap<>(); - private final Map, Double> travelCosts = new HashMap<>(); - - public void setData(final Id id, final double travelTime, final double travelCost) { - this.travelTimes.put(id, travelTime); - this.travelCosts.put(id, travelCost); - } - - @Override - public double getLinkTravelTime(final Link link, final double time, Person person, Vehicle vehicle) { - return this.travelTimes.get(link.getId()); - } - - @Override - public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, final CustomDataManager dataManager) { - return this.travelCosts.get(link.getId()); - } - - @Override - public double getWalkTravelTime(Person person, Coord coord, Coord toCoord) { - return 0; - } - - @Override - public double getWalkTravelDisutility(Person person, Coord coord, Coord toCoord) { - return 0; - } - - } -}