MATSIM
ReplanningAnnealerConfigGroup.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.* *
3  * *
4  * *********************************************************************** *
5  * *
6  * copyright : (C) 2008 by the members listed in the COPYING, *
7  * LICENSE and WARRANTY file. *
8  * email : info at matsim dot org *
9  * *
10  * *********************************************************************** *
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * See also COPYING, LICENSE and WARRANTY file *
17  * *
18  * *********************************************************************** */
19 
20 package org.matsim.core.replanning.annealing;
21 
22 import java.util.EnumMap;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.stream.Collectors;
27 
30 
36 
37  public static final String GROUP_NAME = "replanningAnnealer";
38  private static final String ACTIVATE_ANNEALING_MODULE = "activateAnnealingModule";
39  private boolean activateAnnealingModule = false;
40 
42  super(GROUP_NAME);
43  }
44 
45  @StringGetter(ACTIVATE_ANNEALING_MODULE)
46  public boolean isActivateAnnealingModule() {
48  }
49 
52  this.activateAnnealingModule = activateAnnealingModule;
53  }
54 
55  @Override
56  public Map<String, String> getComments() {
57  final Map<String, String> comments = super.getComments();
58  comments.put(ACTIVATE_ANNEALING_MODULE, "Activate the scaling of replanning modules using an annealing approach rather than fixed rates.");
59  return comments;
60  }
61 
62  @Override
63  public ConfigGroup createParameterSet(final String type) {
64  if (AnnealingVariable.GROUP_NAME.equals(type)) {
65  return new AnnealingVariable();
66  }
67  throw new IllegalArgumentException(type);
68  }
69 
70  @Override
71  protected void checkParameterSet(final ConfigGroup module) {
72  if (!AnnealingVariable.GROUP_NAME.equals(module.getName())) {
73  throw new IllegalArgumentException(module.getName());
74  }
75  if (!(module instanceof AnnealingVariable)) {
76  throw new RuntimeException("unexpected class for module " + module);
77  }
78  }
79 
80  @Override
81  public void addParameterSet(final ConfigGroup set) {
82  if (!AnnealingVariable.GROUP_NAME.equals(set.getName())) {
83  throw new IllegalArgumentException(set.getName());
84  }
86  }
87 
88  public List<AnnealingVariable> getAllAnnealingVariables(){
89  return getAnnealingVariablesPerSubpopulation().values().stream().flatMap(a->a.values().stream()).collect(Collectors.toList());
90  }
91  public Map<AnnealParameterOption, Map<String,AnnealingVariable>> getAnnealingVariablesPerSubpopulation() {
92  final EnumMap<AnnealParameterOption, Map<String,AnnealingVariable>> map =
93  new EnumMap<>(AnnealParameterOption.class);
95  AnnealParameterOption name = ((AnnealingVariable) pars).getAnnealParameter();
96  String subpopulation = ((AnnealingVariable) pars).getSubpopulation();
97  var paramsPerSubpopulation = map.computeIfAbsent(name,a->new HashMap<>());
98  final AnnealingVariable old = paramsPerSubpopulation.put(subpopulation, (AnnealingVariable) pars);
99  if (old != null) {
100  throw new IllegalStateException("several parameter sets for variable " + name + " and subpopulation "+subpopulation);
101  }
102  }
103  return map;
104  }
105 
107  var previousMap = this.getAnnealingVariablesPerSubpopulation().get(params.getAnnealParameter());
108  if (previousMap!=null){
109  AnnealingVariable previous = previousMap.get(params.getSubpopulation());
110  if (previous != null) {
111  final boolean removed = removeParameterSet(previous);
112  if (!removed) {
113  throw new RuntimeException("problem replacing annealing variable");
114  }
115  }
116  }
117  super.addParameterSet(params);
118  }
119 
120  public enum AnnealOption {linear, geometric, exponential, msa, sigmoid, disabled}
121 
122  public enum AnnealParameterOption {
123  globalInnovationRate, BrainExpBeta, PathSizeLogitBeta, learningRate
124  }
125 
126  public static class AnnealingVariable extends ReflectiveConfigGroup {
127 
128  public static final String GROUP_NAME = "AnnealingVariable";
129  private static final String START_VALUE = "startValue";
130  private static final String END_VALUE = "endValue";
131  private static final String ANNEAL_TYPE = "annealType";
132  private static final String SUBPOPULATION = "subpopulation";
133  private static final String ANNEAL_PARAM = "annealParameter";
134  private static final String HALFLIFE = "halfLife";
135  private static final String SHAPE_FACTOR = "shapeFactor";
136  private String subpopulation = null;
137  private Double startValue = null;
138  private double endValue = 0.0001;
139  private double shapeFactor = 0.9;
140  private double halfLife = 100.0;
143 
144  public AnnealingVariable() {
145  super(GROUP_NAME);
146  }
147 
148  @StringGetter(START_VALUE)
149  public Double getStartValue() {
150  return this.startValue;
151  }
152 
154  public void setStartValue(Double startValue) {
155  this.startValue = startValue;
156  }
157 
159  public double getEndValue() {
160  return this.endValue;
161  }
162 
164  public void setEndValue(double endValue) {
165  this.endValue = endValue;
166  }
167 
170  return this.annealType;
171  }
172 
174  public void setAnnealType(String annealType) {
175  this.annealType = AnnealOption.valueOf(annealType);
176  }
177 
179  this.annealType = annealType;
180  }
181 
183  public String getSubpopulation() {
184  return this.subpopulation;
185  }
186 
188  public void setDefaultSubpopulation(String defaultSubpop) {
189  this.subpopulation = defaultSubpop;
190  }
191 
194  return this.annealParameter;
195  }
196 
198  public void setAnnealParameter(String annealParameter) {
200  }
201 
203  this.annealParameter = annealParameter;
204  }
205 
207  public double getHalfLife() {
208  return this.halfLife;
209  }
210 
212  public void setHalfLife(double halfLife) {
213  this.halfLife = halfLife;
214  }
215 
217  public double getShapeFactor() {
218  return this.shapeFactor;
219  }
220 
222  public void setShapeFactor(double shapeFactor) {
223  this.shapeFactor = shapeFactor;
224  }
225 
226  @Override
227  public Map<String, String> getComments() {
228  Map<String, String> map = super.getComments();
229  map.put(HALFLIFE,
230  "this parameter enters the exponential and sigmoid formulas. May be an iteration or a share, i.e. 0.5 for halfLife at 50% of iterations.");
231  map.put(SHAPE_FACTOR, "see comment of parameter annealType.");
232  map.put(ANNEAL_TYPE, "options: linear, exponential, geometric, msa, sigmoid and disabled (no annealing). sigmoid: 1/(1+e^(shapeFactor*(it - halfLife))); geometric: startValue * shapeFactor^it; msa: startValue / it^shapeFactor. Exponential: startValue / exp(it/halfLife)");
233  map.put(ANNEAL_PARAM,
234  "list of config parameters that shall be annealed. Currently supported: globalInnovationRate, BrainExpBeta, PathSizeLogitBeta, learningRate. Default is globalInnovationRate");
235  map.put(SUBPOPULATION, "subpopulation to have the global innovation rate adjusted. Not applicable when annealing with other parameters.");
236  map.put(START_VALUE, "start value for annealing.");
237  map.put(END_VALUE, "final annealing value. When the annealing function reaches this value, further results remain constant.");
238  return map;
239  }
240  }
241 
242 }
final Map< String, ? extends Collection<? extends ConfigGroup > > getParameterSets()
Map< AnnealParameterOption, Map< String, AnnealingVariable > > getAnnealingVariablesPerSubpopulation()
final TreeMap< String, String > params
boolean removeParameterSet(final ConfigGroup set)