MATSIM
RandomizingTimeDistanceTravelDisutility.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * TravelTimeDistanceCostCalculator.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 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.core.router.costcalculators;
22 
28 import org.matsim.vehicles.Vehicle;
29 
30 import java.util.Random;
31 
35 final class RandomizingTimeDistanceTravelDisutility implements TravelDisutility {
36 
37  private final TravelTime timeCalculator;
38  private final double marginalCostOfTime;
39  private final double marginalCostOfDistance;
40 
41  private final double normalization ;
42  private final double sigma ;
43 
44  private final Random random;
45 
46  // "cache" of the random value
47  private double logNormalRnd;
48  private Person prevPerson;
49 
50  RandomizingTimeDistanceTravelDisutility(
51  final TravelTime timeCalculator,
52  final double marginalCostOfTime_s,
53  final double marginalCostOfDistance_m,
54  final double normalization,
55  final double sigma) {
56  this.timeCalculator = timeCalculator;
57  this.marginalCostOfTime = marginalCostOfTime_s;
58  this.marginalCostOfDistance = marginalCostOfDistance_m;
59  this.normalization = normalization;
60  this.sigma = sigma;
61  this.random = sigma != 0 ? MatsimRandom.getLocalInstance() : null;
62  }
63 
64  @Override
65  public double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle) {
66  // randomize if applicable:
67  if ( sigma != 0. ) {
68  if ( person==null ) {
69  throw new RuntimeException("you cannot use the randomzing travel disutility without person. If you need this without a person, set"
70  + " sigma to zero. If you are loading a scenario from a config, set the routingRandomness in the plansCalcRoute config group to zero.") ;
71  }
72  if ( person != prevPerson ) {
73  prevPerson = person ;
74 
75  logNormalRnd = Math.exp( sigma * random.nextGaussian() ) ;
76  logNormalRnd *= normalization ;
77  // this should be a log-normal distribution with sigma as the "width" parameter. Instead of figuring out the "location"
78  // parameter mu, I rather just normalize (which should be the same, see next). kai, nov'13
79 
80  /* The argument is something like this:<ul>
81  * <li> exp( mu + sigma * Z) with Z = Gaussian generates lognormal with mu and sigma.
82  * <li> The mean of this is exp( mu + sigma^2/2 ) .
83  * <li> If we set mu=0, the expectation value is exp( sigma^2/2 ) .
84  * <li> So in order to set the expectation value to one (which is what we want), we need to divide by exp( sigma^2/2 ) .
85  * </ul>
86  * Should be tested. kai, jan'14 */
87  }
88  // do not use custom attributes in core?? but what would be a better solution here?? kai, mar'15
89  // Is this actually used anywhere? As far as I can see, this is at least no used in this class... td, Oct'15
90  person.getCustomAttributes().put("logNormalRnd", logNormalRnd ) ;
91  } else {
92  logNormalRnd = 1. ;
93  }
94 
95  // end randomize
96 
97  double travelTime = this.timeCalculator.getLinkTravelTime(link, time, person, vehicle);
98  return this.marginalCostOfTime * travelTime + logNormalRnd * this.marginalCostOfDistance * link.getLength();
99  }
100 
101  @Override
102  public double getLinkMinimumTravelDisutility(final Link link) {
103  return (link.getLength() / link.getFreespeed()) * this.marginalCostOfTime + this.marginalCostOfDistance * link.getLength();
104  }
105 
106 }