/
ParamSpaceExploAlgorithm.java
191 lines (161 loc) · 6.12 KB
/
ParamSpaceExploAlgorithm.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*******************************************************************************************************
*
* msi.gama.kernel.batch.ParamSpaceExploAlgorithm.java, in plugin msi.gama.core,
* is part of the source code of the GAMA modeling and simulation platform (v. 1.8.1)
*
* (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners
*
* Visit https://github.com/gama-platform/gama for license information and contacts.
*
********************************************************************************************************/
package msi.gama.kernel.batch;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import msi.gama.common.interfaces.IKeyword;
import msi.gama.kernel.experiment.BatchAgent;
import msi.gama.kernel.experiment.IExperimentPlan;
import msi.gama.kernel.experiment.IParameter;
import msi.gama.kernel.experiment.ParameterAdapter;
import msi.gama.kernel.experiment.ParametersSet;
import msi.gama.precompiler.GamlAnnotations.inside;
import msi.gama.precompiler.ISymbolKind;
import msi.gama.runtime.GAMA;
import msi.gama.runtime.GAMA.InScope;
import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gaml.compilation.AbstractGamlAdditions;
import msi.gaml.compilation.ISymbol;
import msi.gaml.compilation.Symbol;
import msi.gaml.descriptions.IDescription;
import msi.gaml.expressions.IExpression;
import msi.gaml.types.IType;
/**
* The Class ParamSpaceExploAlgorithm.
*/
@inside (
kinds = { ISymbolKind.EXPERIMENT })
public abstract class ParamSpaceExploAlgorithm extends Symbol implements IExploration {
public final static String[] COMBINATIONS = new String[] { "maximum", "minimum", "average" };
@SuppressWarnings ("rawtypes") public static final Class[] CLASSES =
{ GeneticAlgorithm.class, SimulatedAnnealing.class, HillClimbing.class, TabuSearch.class,
TabuSearchReactive.class, ExhaustiveSearch.class, Swarm.class, ExplicitExploration.class};
static {
AbstractGamlAdditions._constants(COMBINATIONS);
}
// private ContinuousUniformGenerator randUniform;
protected HashMap<ParametersSet, Double> testedSolutions;
protected IExpression fitnessExpression;
protected boolean isMaximize;
protected BatchAgent currentExperiment;
// protected IScope scope;
protected ParametersSet bestSolution = null;
protected Double bestFitness = null;
protected short combination;
protected abstract ParametersSet findBestSolution(IScope scope) throws GamaRuntimeException;
@Override
public void initializeFor(final IScope scope, final BatchAgent agent) throws GamaRuntimeException {
currentExperiment = agent;
// this.scope = scope;
}
// protected ContinuousUniformGenerator getRandUniform() {
// if ( randUniform == null ) {
// randUniform = scope.getRandom().createUniform(0., 1.);
// }
// return randUniform;
// }
protected void initializeTestedSolutions() {
testedSolutions = new HashMap<ParametersSet, Double>();
}
protected void initParams() {
GAMA.run(new InScope.Void() {
@Override
public void process(final IScope scope) {
initParams(scope);
}
});
}
protected void initParams(final IScope scope) {}
public ParamSpaceExploAlgorithm(final IDescription desc) {
super(desc);
initializeTestedSolutions();
fitnessExpression = getFacet(IKeyword.MAXIMIZE, IKeyword.MINIMIZE);
isMaximize = hasFacet(IKeyword.MAXIMIZE);
final String ag = getLiteral(IKeyword.AGGREGATION);
combination = IKeyword.MAX.equals(ag) ? C_MAX : IKeyword.MIN.equals(ag) ? C_MIN : C_MEAN;
bestFitness = isMaximize ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
}
@Override
public String getCombinationName() {
return COMBINATIONS[combination];
}
@Override
public void run(final IScope scope) {
try {
findBestSolution(scope);
} catch (final GamaRuntimeException e) {
GAMA.reportError(scope, e, false);
}
}
// @Override
// public void start() {
// new Thread(this, getName() + " thread").start();
// }
@Override
public void setChildren(final Iterable<? extends ISymbol> commands) {}
public boolean isMaximize() {
return isMaximize;
}
@Override
public void addParametersTo(final List<IParameter.Batch> params, final BatchAgent agent) {
params.add(new ParameterAdapter("Exploration method", IExperimentPlan.BATCH_CATEGORY_NAME, IType.STRING) {
@Override
public Object value() {
@SuppressWarnings ("rawtypes") final List<Class> classes = Arrays.asList(CLASSES);
final String methodName = IKeyword.METHODS[classes.indexOf(ParamSpaceExploAlgorithm.this.getClass())];
final String fit = fitnessExpression == null ? "" : "fitness = "
+ (isMaximize ? " maximize " : " minimize ") + fitnessExpression.serialize(false);
final String sim = fitnessExpression == null ? ""
: (combination == C_MAX ? " max " : combination == C_MIN ? " min " : " average ") + "of "
+ agent.getSeeds().length + " simulations";
return "Method " + methodName + " | " + fit + " | " + "compute the" + sim + " for each solution";
}
});
}
@Override
public Double getBestFitness() {
return bestFitness;
}
@Override
public IExpression getFitnessExpression() {
return fitnessExpression;
}
@Override
public ParametersSet getBestSolution() {
return bestSolution;
}
@Override
public short getCombination() {
return combination;
}
protected void setBestSolution(final ParametersSet bestSolution) {
// scope.getGui().debug("ParamSpaceExploAlgorithm.setBestSolution : " +
// bestSolution);
this.bestSolution = new ParametersSet(bestSolution);
}
protected void setBestFitness(final Double bestFitness) {
// scope.getGui().debug("ParamSpaceExploAlgorithm.setBestFitness : " +
// bestFitness);
this.bestFitness = bestFitness;
}
@Override
public void updateBestFitness(final ParametersSet solution, final Double fitness) {
if (fitness == null)
return;
Double best = getBestFitness();
if (bestSolution == null || (isMaximize() ? fitness > best : fitness < best)) {
setBestFitness(fitness);
setBestSolution(solution);
}
}
}