MATSIM
TransitRouterNetworkTravelTimeAndDisutility.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * TransitRouterNetworkCost.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2009 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.pt.router;
22 
23 import org.matsim.api.core.v01.Coord;
30 import org.matsim.vehicles.Vehicle;
31 
40 
41  final static double MIDNIGHT = 24.0*3600;
42 
43  protected final TransitRouterConfig config;
44  private Link previousLink = null;
45  private double previousTime = Double.NaN;
46  private double cachedTravelTime = Double.NaN;
47 
49 
50  /*
51  * If this constructor is used, every instance use its own PreparedTransitSchedule which might
52  * consume a lot of memory.
53  *
54  * cdobler, nov'12
55  */
56  @Deprecated
58  this(config, new PreparedTransitSchedule());
59  }
60 
62  this.config = config;
63  this.preparedTransitSchedule = preparedTransitSchedule;
64  }
65 
66  @Override
67  public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, final CustomDataManager dataManager) {
68  double cost;
69  if (((TransitRouterNetworkLink) link).getRoute() == null) {
70  // "route" here means "pt route". If no pt route is attached, it means that it is a transfer link.
71 
72  cost = defaultTransferCost(link, time, person, vehicle);
73 
74  } else {
75  double offVehWaitTime = offVehicleWaitTime(link, time);
76  double inVehTime = getLinkTravelTime(link,time, person, vehicle) - offVehWaitTime;
77  cost = - inVehTime * this.config.getMarginalUtilityOfTravelTimePt_utl_s()
78  -offVehWaitTime * this.config.getMarginalUtilityOfWaitingPt_utl_s()
80 
81  }
82  return cost;
83  }
84 
92  protected double offVehicleWaitTime(final Link link, final double time) {
93  double offVehWaitTime=0;
94  double nextVehArrivalTime = getVehArrivalTime(link, time);
95  if (time < nextVehArrivalTime){ // it means the agent waits outside the veh
96  offVehWaitTime = nextVehArrivalTime-time;
97  }
98  return offVehWaitTime;
99 
100  }
101 
106  protected final double defaultTransferCost(final Link link, final double time,
107  final Person person, final Vehicle vehicle) {
108  double cost;
109  double transfertime = getLinkTravelTime(link, time, person, vehicle);
110  double waittime = this.config.getAdditionalTransferTime();
111 
112  // say that the effective walk time is the transfer time minus some "buffer"
113  double walktime = transfertime - waittime;
114  // (this looks like walktime might become negative. But at least in the default version, the additional transfer time is always
115  // _added_ to the walk time (see getLinkTravelTime below) so at least in that case this cannot happen. kai, triggered by cd, may'16)
116  if ( walktime < 0. ) {
117  throw new RuntimeException( "negative walk time; should not happen; needs to be repaired" ) ;
118  }
119 
120  double walkDistance = link.getLength();
121 
122  // weigh this "buffer" not with the walk time disutility, but with the wait time disutility:
123  // (note that this is the same "additional disutl of wait" as in the scoring function. Its default is zero.
124  // only if you are "including the opportunity cost of time into the router", then the disutility of waiting will
125  // be the same as the marginal opprotunity cost of time). kai, nov'11
126  cost = - walktime * this.config.getMarginalUtilityOfTravelTimeWalk_utl_s()
127  - walkDistance * this.config.getMarginalUtilityOfTravelDistanceWalk_utl_m()
128  - waittime * this.config.getMarginalUtilityOfWaitingPt_utl_s()
129  - this.config.getUtilityOfLineSwitch_utl();
130  return cost;
131  }
132 
133  @Override
134  public double getLinkTravelTime(final Link link, final double time, Person person, Vehicle vehicle) {
135  if ((link == this.previousLink) && (time == this.previousTime)) {
136  return this.cachedTravelTime;
137  }
138  this.previousLink = link;
139  this.previousTime = time;
140 
142  TransitRouteStop fromStop = wrapped.fromNode.stop;
143  TransitRouteStop toStop = wrapped.toNode.stop;
144  if (wrapped.route != null) {
145  // (agent stays on the same route, so use transit line travel time)
146 
147  // get the next departure time:
148  double bestDepartureTime = preparedTransitSchedule.getNextDepartureTime(wrapped.route, fromStop, time);
149 
150  // the travel time on the link is
151  // the time until the departure (``dpTime - now'')
152  // + the travel time on the link (there.arrivalTime - here.departureTime)
153  // But quite often, we only have the departure time at the next stop. Then we use that:
154  double arrivalOffset = toStop.getArrivalOffset().or(toStop::getDepartureOffset).seconds();
155  double time2 = (bestDepartureTime - time) + (arrivalOffset - fromStop.getDepartureOffset().seconds());
156  if (time2 < 0) {
157  // ( this can only happen, I think, when ``bestDepartureTime'' is after midnight but ``time'' was before )
158  time2 += MIDNIGHT;
159  }
160  this.cachedTravelTime = time2;
161  return time2;
162  }
163  // different transit routes, so it must be a line switch
164  double distance = wrapped.getLength();
165  double time2 = distance / this.config.getBeelineWalkSpeed() + this.config.getAdditionalTransferTime();
166  this.cachedTravelTime = time2;
167  return time2;
168  }
169 
170  //variables for caching offVehWaitTime
171  Link previousWaitLink;
172  double previousWaitTime;
173  double cachedVehArrivalTime;
174 
175  public double getVehArrivalTime(final Link link, final double now){
176  if ((link == this.previousWaitLink) && (now == this.previousWaitTime)) {
177  return this.cachedVehArrivalTime;
178  }
179  this.previousWaitLink = link;
180  this.previousWaitTime = now;
181 
182  //first find out vehicle arrival time to fromStop according to transit schedule
184  if (wrapped.getRoute() == null) {
185  throw new RuntimeException("should not happen") ;
186  }
187  TransitRouteStop fromStop = wrapped.fromNode.stop;
188 
189  double nextDepartureTime = preparedTransitSchedule.getNextDepartureTime(wrapped.getRoute(), fromStop, now);
190 
191  double fromStopDepartureOffset = fromStop.getDepartureOffset().seconds();
192  double fromStopArrivalOffset = fromStop.getArrivalOffset().orElse(fromStopDepartureOffset);
193  double vehWaitAtStopTime = fromStopDepartureOffset - fromStopArrivalOffset; //time in which the veh stops at station
194  double vehArrivalTime = nextDepartureTime - vehWaitAtStopTime;
195  cachedVehArrivalTime = vehArrivalTime ;
196  return vehArrivalTime ;
197  }
198 
199  @Override
200  public double getWalkTravelDisutility(Person person, Coord coord, Coord toCoord) {
201  // getMarginalUtilityOfTravelTimeWalk INCLUDES the opportunity cost of time. kai, dec'12
202  double timeCost = - getWalkTravelTime(person, coord, toCoord) * config.getMarginalUtilityOfTravelTimeWalk_utl_s() ;
203  // (sign: margUtl is negative; overall it should be positive because it is a cost.)
204 
205  double distanceCost = - CoordUtils.calcEuclideanDistance(coord,toCoord) *
207  // (sign: same as above)
208 
209  return timeCost + distanceCost ;
210  }
211 
212  @Override
213  public double getWalkTravelTime(Person person, Coord coord, Coord toCoord) {
214  double distance = CoordUtils.calcEuclideanDistance(coord, toCoord);
215  double initialTime = distance / config.getBeelineWalkSpeed();
216  return initialTime;
217  }
218 
219 }
double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle, final CustomDataManager dataManager)
static double calcEuclideanDistance(Coord coord, Coord other)
double getNextDepartureTime(final TransitRoute route, final TransitRouteStop stop, final double depTime)
final double defaultTransferCost(final Link link, final double time, final Person person, final Vehicle vehicle)
TransitRouterNetworkTravelTimeAndDisutility(final TransitRouterConfig config, PreparedTransitSchedule preparedTransitSchedule)
double getLinkTravelTime(final Link link, final double time, Person person, Vehicle vehicle)
OptionalTime or(OptionalTime optionalTime)