MATSIM
ReplanningConfigGroup.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * StrategyConfigGroup.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2008 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.config.groups;
22 
23 import org.matsim.api.core.v01.Id;
25 import org.matsim.core.config.Config;
32 
33 import java.util.Collection;
34 import java.util.Map;
35 
44 public final class ReplanningConfigGroup extends ConfigGroup {
45 
46  public static final String GROUP_NAME = "replanning";
47 
48  // in the following, it is still named "module", for the following reason:
49  // the "right" side is the outside interface, used in the config files, which is left with the old keys for backwards compatibility.
50  // kai/mz, dec'14
51  private static final String MODULE = "Module_";
52  private static final String MODULE_PROBABILITY = "ModuleProbability_";
53  private static final String MODULE_DISABLE_AFTER_ITERATION = "ModuleDisableAfterIteration_";
54  private static final String MODULE_EXE_PATH = "ModuleExePath_";
55  private static final String MODULE_SUBPOPULATION = "ModuleSubpopulation_";
56 
58  // yy could you please describe why this indirect design was done? Was ist just because it made refactoring easier, or does it provide
59  // an advantage or is even necessary? Thanks ... kai, oct'14
60  // To maintain backwards compatibility (underscored parameters), one needs to override the "getValue" and "add_param" methods,
61  // which are final in ReflectiveModule. However, using reflective module for the
62  // rest of the parameters still made refactoring much easier. So let's call
63  // this "necessary". td, apr'15
64 
65  public static class StrategySettings extends ReflectiveConfigGroup implements MatsimParameters {
66  public static final String SET_NAME = "strategysettings";
68  private double probability = -1.0;
69  private String strategyName = null;
70  private int disableAfter = -1;
71  private String exePath = null;
72  private String subpopulation = null;
73 
74  public StrategySettings() {
75  this( Id.create( MatsimRandom.getRandom().nextLong(), StrategySettings.class) );
76  }
77 
78  @Deprecated // use empty constructor. kai/mz, nov'15
80  super( SET_NAME );
81  this.id = id;
82 // this.strategyName = id.toString() ; // safety net, can be overridden by (also deprecated) setStrategyName(...). kai/mz, nov'15
83  // putting the above into the code fails at least one test. We would vote for removing that test ...
84  }
85 
86  @Override
87  public final Map<String, String> getComments() {
88  Map<String,String> map = super.getComments();
89 
90  // put comments only for the first strategy to improve readability
91  // I think that the above comment is a todo, not a description of the code status. kai, feb'15
92 
93  StringBuilder sels = new StringBuilder() ;
94  sels.append( DefaultSelector.SelectRandom ) ;
95  sels.append( ' ' );
96  sels.append( DefaultSelector.BestScore ) ;
97  sels.append( ' ' );
98  sels.append( DefaultSelector.KeepLastSelected ) ;
99  sels.append( ' ' );
100  sels.append( DefaultSelector.ChangeExpBeta ) ;
101  sels.append( ' ' );
102  sels.append( DefaultSelector.SelectExpBeta ) ;
103  sels.append( ' ' );
104  sels.append( DefaultSelector.SelectPathSizeLogit ) ;
105 
106  StringBuilder strats = new StringBuilder() ;
107  strats.append( DefaultStrategy.ReRoute ) ;
108  sels.append( ' ' );
109  strats.append( DefaultStrategy.TimeAllocationMutator ) ;
110  sels.append( ' ' );
112  sels.append( ' ' );
113  strats.append( DefaultStrategy.ChangeSingleTripMode ) ;
114  sels.append( ' ' );
115  strats.append( DefaultStrategy.ChangeTripMode ) ;
116  sels.append( ' ' );
117  strats.append( DefaultStrategy.SubtourModeChoice ) ;
118 
119  map.put( "strategyName",
120  "strategyName of strategy. Possible default names: " + sels + " (selectors), " + strats + " (innovative strategies)." );
121  map.put( "weight",
122  "weight of a strategy: for each agent, a strategy will be selected with a probability proportional to its weight");
123  map.put( "disableAfterIteration",
124  "iteration after which strategy will be disabled. most useful for ``innovative'' strategies (new routes, new times, ...). "
125  + "Normally, better use fractionOfIterationsToDisableInnovation");
126  map.put( "executionPath",
127  "path to external executable (if applicable)" ) ;
128  map.put( "subpopulation",
129  "subpopulation to which the strategy applies. \"null\" refers to the default population, that is, the set of persons for which no explicit subpopulation is defined (ie no subpopulation attribute)" ) ;
130 
131  return map ;
132  }
133 
134  @Override
135  protected void checkConsistency(Config config) {
136  super.checkConsistency(config);
137 
138  if ( getStrategyName() == null || getStrategyName().length() == 0 ) {
139  throw new RuntimeException("Strategy strategyName is not set");
140  }
141  if ( getWeight() < 0.0 ) {
142  throw new RuntimeException("Weight for strategy " + getStrategyName() + " must be >= 0.0" );
143  }
144  }
145 
146  @StringSetter( "weight" )
147  public StrategySettings setWeight(final double probability) {
148  this.probability = probability;
149  return this ;
150  }
151 
152  @StringGetter( "weight" )
153  public double getWeight() {
154  return this.probability;
155  }
156 
157  @StringSetter( "strategyName" )
158  public StrategySettings setStrategyName(final String name) {
159  this.strategyName = name;
160  return this ;
161  }
162 
163  @StringGetter( "strategyName" )
164  public String getStrategyName() {
165  return this.strategyName;
166  }
167 
168  @StringSetter( "disableAfterIteration" )
170  this.disableAfter = disableAfter;
171  return this ;
172  }
173 
174  @StringGetter( "disableAfterIteration" )
175  public int getDisableAfter() {
176  return this.disableAfter;
177  }
178 
179  @StringSetter( "executionPath" )
180  public StrategySettings setExePath(final String exePath) {
181  this.exePath = exePath;
182  return this ;
183  }
184 
185  @StringGetter( "executionPath" )
186  public String getExePath() {
187  return this.exePath;
188  }
189 
190  @Deprecated // not clear if this is only for backwards compatibility (config v1) or should actually be used. kai/mz, nov'15
192  return this.id;
193  }
194 
195  @StringSetter( "subpopulation" )
198  return this ;
199  }
200 
201  @StringGetter( "subpopulation" )
202  public String getSubpopulation() {
203  return subpopulation;
204  }
205  }
206 
208  super(GROUP_NAME);
209  }
210 
211  @Override
212  public String getValue(final String key) {
213  // first check if the parameter is in "underscored" form
214  if ( key.startsWith(MODULE)
215  || key.startsWith(MODULE_PROBABILITY)
216  || key.startsWith(MODULE_DISABLE_AFTER_ITERATION)
217  || key.startsWith(MODULE_EXE_PATH)
218  || key.startsWith(MODULE_SUBPOPULATION) ) {
219  throw new IllegalArgumentException( "getting underscored parameter "+key+" is not allowed anymore. The supported way to get those parameters is via parameter sets." );
220  }
221 
222  return delegate.getValue( key );
223  }
224 
225  @Override
226  public void addParam(final String key, final String value) {
227  // adding underscore parameters is still supported for backward compatibility.
228  if (key != null && key.startsWith(MODULE)) {
229  StrategySettings settings = getStrategySettings(Id.create(key.substring(MODULE.length()), StrategySettings.class), true);
230  settings.addParam( "strategyName" , value);
231  }
232  else if (key != null && key.startsWith(MODULE_PROBABILITY)) {
233  StrategySettings settings = getStrategySettings(Id.create(key.substring(MODULE_PROBABILITY.length()), StrategySettings.class), true);
234  settings.addParam( "weight" , value );
235  }
236  else if (key != null && key.startsWith(MODULE_DISABLE_AFTER_ITERATION)) {
237  StrategySettings settings = getStrategySettings(Id.create(key.substring(MODULE_DISABLE_AFTER_ITERATION.length()), StrategySettings.class), true);
238  settings.setDisableAfter(Integer.parseInt(value));
239  settings.addParam( "disableAfterIteration" , value );
240  }
241  else if (key != null && key.startsWith(MODULE_EXE_PATH)) {
242  StrategySettings settings = getStrategySettings(Id.create(key.substring(MODULE_EXE_PATH.length()), StrategySettings.class), true);
243  settings.addParam( "executionPath" , value );
244  }
245  else if (key != null && key.startsWith(MODULE_SUBPOPULATION)) {
246  StrategySettings settings = getStrategySettings(Id.create(key.substring(MODULE_SUBPOPULATION.length()), StrategySettings.class), true);
247  settings.addParam( "subpopulation" , value );
248  }
249  else {
250  delegate.addParam( key , value );
251  }
252  }
253 
254  private StrategySettings getStrategySettings(final Id<StrategySettings> index, final boolean createIfMissing) {
255  StrategySettings settings = null;
256 
257  // should be in a map, but it is difficult to keep consistency with the
258  // delegate...
259  for ( StrategySettings s : getStrategySettings() ) {
260  if ( !s.getId().equals( index ) ) continue;
261  if ( settings != null ) throw new IllegalStateException( "several settings with id "+index );
262  settings = s;
263  }
264 
265  if (settings == null && createIfMissing) {
266  settings = new StrategySettings(index);
267  addStrategySettings( settings );
268  }
269 
270  return settings;
271  }
272 
273 
275  @Override
276  public final Map<String, String> getComments() {
277  Map<String,String> map = super.getComments();
278  map.put(ReflectiveDelegate.ITERATION_FRACTION_TO_DISABLE_INNOVATION, "fraction of iterations where innovative strategies are switched off. Something like 0.8 should be good. E.g. if you run from iteration 400 to iteration 500, innovation is switched off at iteration 480. If the ReplanningAnnealer is used, it will also be switched off." ) ;
279  map.put(ReflectiveDelegate.MAX_AGENT_PLAN_MEMORY_SIZE, "maximum number of plans per agent. ``0'' means ``infinity''. Currently (2010), ``5'' is a good number");
280 
281  StringBuilder strb = new StringBuilder() ;
282  for ( DefaultPlansRemover name : DefaultPlansRemover.values() ) {
283  strb.append( name.toString() + " " ) ;
284  }
285  map.put(ReflectiveDelegate.PLAN_SELECTOR_FOR_REMOVAL,"strategyName of PlanSelector for plans removal. "
286  + "Possible defaults: " + strb.toString() + ". The current default, WorstPlanSelector is not a good " +
287  "choice from a discrete choice theoretical perspective. Alternatives, however, have not been systematically " +
288  "tested. kai, feb'12") ;
289 
290  map.put(ReflectiveDelegate.EXTERNAL_EXE_CONFIG_TEMPLATE,"the external executable will be called with a config file as argument. This is the pathname to a possible "
291  + "skeleton config, to which additional information will be added. Can be null.");
292  map.put(ReflectiveDelegate.EXTERNAL_EXE_TMP_FILE_ROOT_DIR, "root directory for temporary files generated by the external executable. Provided as a service; "
293  + "I don't think this is used by MATSim.") ;
294  map.put(ReflectiveDelegate.EXTERNAL_EXE_TIME_OUT, "time out value (in seconds) after which matsim will consider the external strategy as failed") ;
295  return map ;
296  }
297 
298  @Override
299  protected void checkParameterSet(final ConfigGroup set) {
300  switch ( set.getName() ) {
302  if ( !(set instanceof StrategySettings) ) {
303  throw new RuntimeException( set+" is not an instance of StrategySettings" );
304  }
305  break;
306  default:
307  throw new IllegalArgumentException( "unknown set type "+set.getName() );
308  }
309  }
310 
311  @Override
312  public ConfigGroup createParameterSet(final String type) {
313  switch ( type ) {
315  return new StrategySettings( );
316  default:
317  throw new IllegalArgumentException( "unknown set type "+type );
318  }
319  }
320 
321  // the two next method are just convenience methods
328  public void addStrategySettings(final StrategySettings stratSets) {
329  addParameterSet( stratSets );
330  }
331 
332  public final void clearStrategySettings() {
334  }
335 
336  public Collection<StrategySettings> getStrategySettings() {
337  // This does look pretty wrong, but is actually OK,
338  // as the checkParameterSet method checks that strategy settings
339  // parameter sets which are added have the proper type.
340  // A cleaner solution would be nice, though... td, sep'14
341  return (Collection<StrategySettings>) getParameterSets(StrategySettings.SET_NAME);
342  }
343 
344  @Override
345  protected void checkConsistency(Config config) {
346  // to make available to tests
347  super.checkConsistency(config);
348  }
349 
350  public void setMaxAgentPlanMemorySize(int maxAgentPlanMemorySize) {
351  delegate.setMaxAgentPlanMemorySize(maxAgentPlanMemorySize);
352  }
353 
356  }
357 
358  public void setExternalExeConfigTemplate(String externalExeConfigTemplate) {
359  delegate.setExternalExeConfigTemplate(externalExeConfigTemplate);
360  }
361 
364  }
365 
366  public void setExternalExeTmpFileRootDir(String externalExeTmpFileRootDir) {
367  delegate.setExternalExeTmpFileRootDir(externalExeTmpFileRootDir);
368  }
369 
372  }
373 
374  public void setExternalExeTimeOut(long externalExeTimeOut) {
375  delegate.setExternalExeTimeOut(externalExeTimeOut);
376  }
377 
378  public long getExternalExeTimeOut() {
380  }
381 
382  public String getPlanSelectorForRemoval() {
384  }
385 
386  public void setPlanSelectorForRemoval(String planSelectorForRemoval) {
387  switch ( planSelectorForRemoval ) {
388  case "SelectExpBeta" :
389  throw new RuntimeException("'SelectExpBeta' was replaced by 'SelectExpBetaForRemoval' in the plans removal setting" ) ;
390  case "ChangeExpBeta" :
391  throw new RuntimeException("'ChangeExpBeta' was replaced by 'ChangeExpBetaForRemoval' in the plans removal setting" ) ;
392  case "PathSizeLogitSelector" :
393  throw new RuntimeException("'PathSizeLogitSelector' was replaced by 'PathSizeLogitSelectorForRemoval' in the plans removal setting" ) ;
394  default:
395  delegate.setPlanSelectorForRemoval(planSelectorForRemoval) ;
396  }
397  }
398 
401  }
402 
403  public void setFractionOfIterationsToDisableInnovation(double fraction) {
405  }
406 
407  @Override
408  public final Map<String, String> getParams() {
409  return delegate.getParams();
410  }
411 
412  private static class ReflectiveDelegate extends ReflectiveConfigGroup {
413  static final String MAX_AGENT_PLAN_MEMORY_SIZE = "maxAgentPlanMemorySize";
414  static final String EXTERNAL_EXE_CONFIG_TEMPLATE = "ExternalExeConfigTemplate";
415  static final String EXTERNAL_EXE_TMP_FILE_ROOT_DIR = "ExternalExeTmpFileRootDir";
416  static final String EXTERNAL_EXE_TIME_OUT = "ExternalExeTimeOut";
417  static final String ITERATION_FRACTION_TO_DISABLE_INNOVATION = "fractionOfIterationsToDisableInnovation" ;
418  static final String PLAN_SELECTOR_FOR_REMOVAL = "planSelectorForRemoval" ;
419 
420  private int maxAgentPlanMemorySize = 5;
421  private String externalExeConfigTemplate = null;
422  private String externalExeTmpFileRootDir = null;
423  private long externalExeTimeOut = 3600;
424 
425  private String planSelectorForRemoval = "WorstPlanSelector";
426 
427  //---
428  private double fraction = Double.POSITIVE_INFINITY ;
429  //---
430 
433  }
434 
435 
436  @StringSetter( MAX_AGENT_PLAN_MEMORY_SIZE )
437  public void setMaxAgentPlanMemorySize(final int maxAgentPlanMemorySize) {
438  this.maxAgentPlanMemorySize = maxAgentPlanMemorySize;
439  }
440 
441  @StringGetter( MAX_AGENT_PLAN_MEMORY_SIZE )
443  return this.maxAgentPlanMemorySize;
444  }
445 
446  @StringSetter( EXTERNAL_EXE_CONFIG_TEMPLATE )
447  public void setExternalExeConfigTemplate(final String externalExeConfigTemplate) {
448  this.externalExeConfigTemplate = externalExeConfigTemplate;
449  }
450 
451  @StringGetter( EXTERNAL_EXE_CONFIG_TEMPLATE )
453  return this.externalExeConfigTemplate;
454  }
455 
456  @StringSetter( EXTERNAL_EXE_TMP_FILE_ROOT_DIR )
457  public void setExternalExeTmpFileRootDir(final String externalExeTmpFileRootDir) {
458  this.externalExeTmpFileRootDir = externalExeTmpFileRootDir;
459  }
460 
461  @StringGetter( EXTERNAL_EXE_TMP_FILE_ROOT_DIR )
463  return this.externalExeTmpFileRootDir;
464  }
465 
466  @StringSetter( EXTERNAL_EXE_TIME_OUT )
467  public void setExternalExeTimeOut(final long externalExeTimeOut) {
468  this.externalExeTimeOut = externalExeTimeOut;
469  }
470 
471  @StringGetter( EXTERNAL_EXE_TIME_OUT )
472  public long getExternalExeTimeOut() {
473  return this.externalExeTimeOut;
474  }
475 
476  @StringGetter( PLAN_SELECTOR_FOR_REMOVAL )
477  public String getPlanSelectorForRemoval() {
478  return planSelectorForRemoval;
479  }
480 
481  @StringSetter( PLAN_SELECTOR_FOR_REMOVAL )
482  public void setPlanSelectorForRemoval(String planSelectorForRemoval) {
483  this.planSelectorForRemoval = planSelectorForRemoval;
484  }
485 
486  @StringGetter( ITERATION_FRACTION_TO_DISABLE_INNOVATION )
488  return fraction;
489  }
490 
491  @StringSetter( ITERATION_FRACTION_TO_DISABLE_INNOVATION )
492  public void setFractionOfIterationsToDisableInnovation(double fraction) {
493  this.fraction = fraction;
494  }
495  }
496 }
497 
void setPlanSelectorForRemoval(String planSelectorForRemoval)
void addParameterSet(final ConfigGroup set)
final Collection<? extends ConfigGroup > clearParameterSetsForType(final String type)
void addParam(final String key, final String value)
void setExternalExeTmpFileRootDir(String externalExeTmpFileRootDir)
static< T > Id< T > create(final long key, final Class< T > type)
Definition: Id.java:68
final String getValue(final String param_name)
final Map< String, ? extends Collection<? extends ConfigGroup > > getParameterSets()
final void addParam(final String param_name, final String value)
void setExternalExeConfigTemplate(String externalExeConfigTemplate)
void addStrategySettings(final StrategySettings stratSets)
StrategySettings getStrategySettings(final Id< StrategySettings > index, final boolean createIfMissing)