MATSIM
ActivityUtilityParameters.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * ActUtilityParameters.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.scoring.functions;
22 
26 
40 public final class ActivityUtilityParameters implements MatsimParameters {
41 
42  public interface ZeroUtilityComputation {
43  double computeZeroUtilityDuration_s( final double priority, final double typicalDuration_s ) ;
44  }
45  public static final class SameAbsoluteScore implements ZeroUtilityComputation {
46  @Override
47  public double computeZeroUtilityDuration_s(double priority, double typicalDuration_s) {
48  final double priority1 = priority;
49  final double typicalDuration_s1 = typicalDuration_s;
50  final double zeroUtilityDuration = typicalDuration_s1 * Math.exp( -10.0 / (typicalDuration_s1 / 3600.0) / priority1 );
51  // ( the 3600s are in there because the original formulation was in "hours". So the values in seconds are first
52  // translated into hours. kai, sep'12 )
53 
54  return zeroUtilityDuration;
55  }
56  }
57  public static final class SameRelativeScore implements ZeroUtilityComputation {
58  @Override
59  public double computeZeroUtilityDuration_s(double priority, double typicalDuration_s) {
60  final double priority1 = priority;
61  final double typicalDuration_s1 = typicalDuration_s;
62  final double zeroUtilityDuration = typicalDuration_s1 * Math.exp( -1.0 / priority1 );
63 
64  return zeroUtilityDuration;
65  }
66  }
67 
68 
75  public final static class Builder {
76  private String type;
77  private double priority = 1. ;
84  private boolean scoreAtAll = true;
85  private ZeroUtilityComputation zeroUtilityComputation = new SameRelativeScore();
86 
90  public Builder() {
91  }
92 
96  public Builder(ActivityParams ppp ) {
97  this.type = ppp.getActivityType() ;
98  this.priority = ppp.getPriority() ;
99  this.typicalDuration_s = ppp.getTypicalDuration();
100  this.closingTime = ppp.getClosingTime();
101  this.earliestEndTime = ppp.getEarliestEndTime();
102  this.latestStartTime = ppp.getLatestStartTime();
103  this.minimalDuration = ppp.getMinimalDuration();
104  this.openingTime = ppp.getOpeningTime();
105  this.scoreAtAll = ppp.isScoringThisActivityAtAll() ;
106  switch( ppp.getTypicalDurationScoreComputation() ) {
107  case relative:
108  this.zeroUtilityComputation = new SameRelativeScore() ;
109  break;
110  case uniform:
111  this.zeroUtilityComputation = new SameAbsoluteScore() ;
112  break;
113  default:
114  throw new RuntimeException("not defined");
115  }
116  // seems to be somewhat overkill to set a computation method that is only used in the builder ... but the builder has a method to
117  // (re)set the
118  }
119 
120 
121  public Builder setType(String type) {
122  this.type = type;
123  return this;
124  }
125 
126  public Builder setPriority(double priority) {
127  this.priority = priority;
128  return this;
129  }
130 
131  public Builder setTypicalDuration_s(double typicalDurationS) {
132  typicalDuration_s = OptionalTime.defined(typicalDurationS);
133  return this;
134  }
135 
136  public Builder setClosingTime(double closingTime) {
137  this.closingTime = OptionalTime.defined(closingTime);
138  return this;
139  }
140 
141  public Builder setEarliestEndTime(double earliestEndTime) {
142  this.earliestEndTime = OptionalTime.defined(earliestEndTime);
143  return this;
144  }
145 
146  public Builder setLatestStartTime(double latestStartTime) {
147  this.latestStartTime = OptionalTime.defined(latestStartTime);
148  return this;
149  }
150 
151  public Builder setMinimalDuration(double minimalDuration) {
152  this.minimalDuration = OptionalTime.defined(minimalDuration);
153  return this;
154  }
155 
156  public Builder setOpeningTime(double openingTime) {
157  this.openingTime = OptionalTime.defined(openingTime);
158  return this;
159  }
160 
161  public Builder setScoreAtAll(boolean scoreAtAll) {
162  this.scoreAtAll = scoreAtAll;
163  return this;
164  }
165 
167  ActivityUtilityParameters params = new ActivityUtilityParameters(this.type) ;
168  params.scoreAtAll = this.scoreAtAll;
169  this.typicalDuration_s.ifDefined( duration -> params.typicalDuration_s = duration ) ;
170  this.typicalDuration_s.ifDefined( duration -> params.zeroUtilityDuration_h = this.zeroUtilityComputation.computeZeroUtilityDuration_s(priority, duration ) / 3600. );
171  // (I think that the only way in which the typical duration can be undefined is if the activity is not scored at all. Maybe change the condition. kai, may'22)
172  params.closingTime = this.closingTime;
173  params.earliestEndTime = this.earliestEndTime;
174  params.latestStartTime = this.latestStartTime;
175  params.minimalDuration = this.minimalDuration;
176  params.openingTime = this.openingTime;
177  params.checkConsistency();
178  return params ;
179  }
180 
181  public Builder setZeroUtilityComputation( ZeroUtilityComputation zeroUtilityComputation ) {
182  this.zeroUtilityComputation = zeroUtilityComputation;
183  return this;
184  }
185  }
186 
187  private final String type;
188  private double typicalDuration_s = 0;
189 
195  private double zeroUtilityDuration_h = 0; // in hours!
196  private OptionalTime minimalDuration = OptionalTime.undefined();
197  private OptionalTime openingTime = OptionalTime.undefined();
198  private OptionalTime closingTime = OptionalTime.undefined();
199  private OptionalTime latestStartTime = OptionalTime.undefined();
200  private OptionalTime earliestEndTime = OptionalTime.undefined();
201  private boolean scoreAtAll=true;
202 
203  private ActivityUtilityParameters(final String type) {
204  this.type = type;
205  }
206 
207  private void checkConsistency() {
208  //if typical duration is <=48 seconds (and priority=1) then zeroUtilityDuration becomes 0.0 because of the double precision. This means it is not possible
209  // to have activities with a typical duration <=48 seconds (GL/June2011)
210  if (this.scoreAtAll && this.zeroUtilityDuration_h == 0.0) {
211  throw new RuntimeException("zeroUtilityDuration of type " + type + " must be greater than 0.0. Did you forget to specify the typicalDuration?");
212  }
213  }
214 
215  public final String getType() {
216  return this.type;
217  }
218 
219  public final double getTypicalDuration() {
220  return this.typicalDuration_s;
221  }
222 
223  public final double getZeroUtilityDuration_h() {
224  return this.zeroUtilityDuration_h;
225  }
226 
228  return this.minimalDuration;
229  }
230 
231  public final OptionalTime getOpeningTime() {
232  return this.openingTime;
233  }
234 
235  public final OptionalTime getClosingTime() {
236  return this.closingTime;
237  }
238 
240  return this.latestStartTime;
241  }
242 
244  return this.earliestEndTime;
245  }
246 
247  public final boolean isScoreAtAll() {
248  return scoreAtAll;
249  }
250 
251 }
void ifDefined(DoubleConsumer action)
double computeZeroUtilityDuration_s(final double priority, final double typicalDuration_s)
Builder setZeroUtilityComputation(ZeroUtilityComputation zeroUtilityComputation)
static OptionalTime defined(double seconds)