Skip to content

Commit

Permalink
fixes some issues with batch exploration (avoid repetition of tested …
Browse files Browse the repository at this point in the history
…solutions)
  • Loading branch information
ptaillandier committed Feb 4, 2022
1 parent b2c58a3 commit 2c141f8
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 31 deletions.
Expand Up @@ -313,14 +313,16 @@ public void computePopFitness(final IScope scope, final List<Chromosome> populat
* @throws GamaRuntimeException the gama runtime exception
*/
public void computePopFitnessAll(final IScope scope, final List<Chromosome> population) throws GamaRuntimeException {
List<ParametersSet> sets = new ArrayList<>();
List<ParametersSet> solTotest = new ArrayList<>();
Map<Chromosome,ParametersSet> paramToCh = GamaMapFactory.create();
for (final Chromosome chromosome : population) {
ParametersSet sol = chromosome.convertToSolution(scope, currentExperiment.getParametersToExplore());
sets.add(sol );
paramToCh.put( chromosome, sol);
if (!testedSolutions.containsKey(sol)) {
solTotest.add(sol);
}
}
Map<ParametersSet, Double> fitnessRes = currentExperiment.launchSimulationsWithSolution(sets).entrySet().stream()
Map<ParametersSet, Double> fitnessRes = currentExperiment.launchSimulationsWithSolution(solTotest).entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey(),
e -> (Double) e.getValue().get(IKeyword.FITNESS).get(0)
Expand All @@ -331,10 +333,21 @@ public void computePopFitnessAll(final IScope scope, final List<Chromosome> popu
if (ps != null) {
Double fitness = fitnessRes.get(ps);
if (fitness != null) chromosome.setFitness(fitness);
else chromosome.setFitness(testedSolutions.get(ps));
}

}

if (this.improveSolution != null && improveSolution) {
for (final Chromosome chromosome : population) {
ParametersSet sol = chromosome.convertToSolution(scope, currentExperiment.getParametersToExplore());
sol = improveSolution(scope, sol, chromosome.getFitness());
chromosome.update(scope, sol);
final double fitness = testedSolutions.get(sol);
chromosome.setFitness(fitness);
}
}


}

Expand Down Expand Up @@ -402,6 +415,28 @@ public Object value() {

});
}

public Map<ParametersSet, Double> testSolutions(List<ParametersSet> solutions) {
Map<ParametersSet, Double> results = GamaMapFactory.create();
solutions.removeIf(a -> a == null);
List<ParametersSet> solTotest = new ArrayList<>();
for (ParametersSet sol : solutions) {
if (testedSolutions.containsKey(sol)) {
results.put(sol, testedSolutions.get(sol));
} else {
solTotest.add(sol);
}
}
Map<ParametersSet, Double> res = currentExperiment.launchSimulationsWithSolution(solTotest)
.entrySet().stream().collect(Collectors.toMap(
e -> e.getKey(),
e -> (Double) e.getValue().get(IKeyword.FITNESS).get(0))
);
testedSolutions.putAll(res);
results.putAll(res);

return results;
}

/**
* Improve solution.
Expand All @@ -416,36 +451,47 @@ private ParametersSet improveSolution(final IScope scope, final ParametersSet so
ParametersSet bestSol = solution;
double bestFitness = currentFitness;
while (true) {
final List<ParametersSet> neighbors = neighborhood.neighbor(scope, solution);
final List<ParametersSet> neighbors = neighborhood.neighbor(scope,solution);
if (neighbors.isEmpty()) {
break;
}
ParametersSet bestNeighbor = null;

for (final ParametersSet neighborSol : neighbors) {
if (neighborSol == null) {
continue;

if (GamaExecutorService.CONCURRENCY_SIMULATIONS_ALL.getValue() && ! currentExperiment.getParametersToExplore().isEmpty()) {
Map<ParametersSet,Double> result = testSolutions(neighbors);
for (ParametersSet p : result.keySet()) {
Double neighborFitness = result.get(p);
if (isMaximize() && neighborFitness > bestFitness || !isMaximize() && neighborFitness < bestFitness) {
bestNeighbor = p;
bestFitness = neighborFitness;
bestSol = bestNeighbor;
}
}
final double neighborFitness;
if (!testedSolutions.containsKey(neighborSol)) {
neighborFitness = (Double) currentExperiment.launchSimulationsWithSolution(neighborSol)
.get(IKeyword.FITNESS).get(0);
testedSolutions.put(neighborSol, neighborFitness);
} else {
neighborFitness = testedSolutions.get(neighborSol);
}

if (isMaximize() && neighborFitness > bestFitness || !isMaximize() && neighborFitness < bestFitness) {
bestNeighbor = neighborSol;
bestFitness = neighborFitness;
bestSol = bestNeighbor;
} else {
for (final ParametersSet neighborSol : neighbors) {
if (neighborSol == null) {
continue;
}
Double neighborFitness = testedSolutions.get(neighborSol);
if (neighborFitness == null) {
neighborFitness = (Double) currentExperiment.launchSimulationsWithSolution(neighborSol).get(IKeyword.FITNESS).get(0);
testedSolutions.put(neighborSol, neighborFitness);
}

if (isMaximize() && neighborFitness > bestFitness || !isMaximize() && neighborFitness < bestFitness) {
bestNeighbor = neighborSol;
bestFitness = neighborFitness;
bestSol = bestNeighbor;
}

}
}
if (bestNeighbor != null) {
bestSol = bestNeighbor;
} else {
break;
}

}

return bestSol;
Expand Down
Expand Up @@ -38,6 +38,8 @@ public List<Chromosome> select(final IScope scope, final List<Chromosome> popula
if (maximize) {
Collections.reverse(nextGen);
}
return nextGen.subList(0, populationDim - 1);
if (nextGen.size() > populationDim)
return nextGen.subList(0, populationDim - 1);
return nextGen;
}
}
4 changes: 3 additions & 1 deletion msi.gama.core/src/msi/gama/kernel/experiment/BatchAgent.java
Expand Up @@ -16,6 +16,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Vector;
Expand Down Expand Up @@ -306,7 +307,8 @@ public IMap<ParametersSet, Map<String, List<Object>>> launchSimulationsWithSolut

// The values present in the solution are passed to the parameters of
// the experiment
for (ParametersSet sol : sols) {
LinkedHashSet<ParametersSet> sols_u = new LinkedHashSet<>(sols);
for (ParametersSet sol : sols_u) {
for (int i = 0; i < getSeeds().length; i++) {
Map<String, Object> sim = new HashMap<>();
sim.put("parameters", sol);
Expand Down
Expand Up @@ -355,7 +355,7 @@ public SimulationAgent createSimulation(final ParametersSet parameters, final bo
final ParametersSet ps = getParameterValues();
ps.putAll(parameters);
final IList<Map<String, Object>> list = GamaListFactory.create(Types.MAP);
list.add(ps);
list.add(ps.getElements());
final IList<? extends IAgent> c = pop.createAgents(ownScope, 1, list, false, scheduleIt);
return (SimulationAgent) c.get(0);
}
Expand All @@ -368,7 +368,7 @@ public SimulationAgent createSimulation(final ParametersSet parameters, final bo
public ParametersSet getParameterValues() {
final Map<String, IParameter> parameters = getSpecies().getParameters();
final ParametersSet ps = new ParametersSet(ownScope, parameters, false);
ps.putAll(extraParametersMap);
ps.getElements().putAll(extraParametersMap);
return ps;
}

Expand Down
63 changes: 58 additions & 5 deletions msi.gama.core/src/msi/gama/kernel/experiment/ParametersSet.java
Expand Up @@ -11,31 +11,38 @@
package msi.gama.kernel.experiment;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import msi.gama.runtime.IScope;
import msi.gama.runtime.exceptions.GamaRuntimeException;
import msi.gama.util.GamaMap;
import msi.gama.util.GamaMapFactory;
import msi.gama.util.file.GamaFile;

/**
* The Class ParametersSet.
*/
@SuppressWarnings({ "rawtypes" })
public class ParametersSet extends HashMap<String, Object> {
public class ParametersSet {

/** The fitness. */
private Double fitness;

/** The current index. */
private int currentIndex;

private GamaMap<String, Object> elements;


/**
* Instantiates a new parameters set.
*/
public ParametersSet() {
fitness = Double.NaN;
currentIndex = 0;
elements = (GamaMap<String, Object>) GamaMapFactory.create();
}

/**
Expand All @@ -44,7 +51,8 @@ public ParametersSet() {
* @param solution the solution
*/
public ParametersSet(final ParametersSet solution) {
this.putAll(solution);
elements = (GamaMap<String, Object>) GamaMapFactory.create();
elements.putAll(solution.getElements());
fitness = solution.fitness;
currentIndex = solution.currentIndex;
}
Expand All @@ -60,6 +68,7 @@ public ParametersSet(final ParametersSet solution) {
public ParametersSet(final IScope scope, final Map<String, IParameter> variables, final boolean reinit)
throws GamaRuntimeException {

elements = (GamaMap<String, Object>) GamaMapFactory.create();
for (final String var : variables.keySet()) {
final IParameter varBat = variables.get(var);
if (reinit && varBat instanceof IParameter.Batch) {
Expand All @@ -82,6 +91,7 @@ public ParametersSet(final IScope scope, final Map<String, IParameter> variables
*/
public ParametersSet(final IScope scope, final Collection<? extends IParameter> parameters, final boolean reinit)
throws GamaRuntimeException {
elements = (GamaMap<String, Object>) GamaMapFactory.create();
for (final IParameter p : parameters) {
if (reinit && p instanceof IParameter.Batch) {
((IParameter.Batch) p).reinitRandomly(scope);
Expand All @@ -92,17 +102,60 @@ public ParametersSet(final IScope scope, final Collection<? extends IParameter>
currentIndex = 0;
}

@Override
public Object put(final String s, final Object o) {
// Special case for files as they are not invariant. Their contents must
// be invalidated before they are loaded
// again in a simulation. See Issue 812.
if (o instanceof GamaFile) {
((GamaFile) o).invalidateContents();
}
return super.put(s, o);
return elements.put(s, o);
}

public void putAll(final ParametersSet sol) {
elements.putAll(sol.elements);
}

public Object get(final String s) {
return elements.get(s);
}
public GamaMap<String, Object> getElements() {
return elements;
}

public Set<Map.Entry<String, Object>> entrySet() {
return elements.entrySet();
}

public Set<String> keySet() {
return elements.keySet();
}

public boolean containsKey(String k ) {
return elements.containsKey(k);
}

public int size() {
return elements.size();
}


@Override
public int hashCode() {
return Objects.hash(elements);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ParametersSet other = (ParametersSet) obj;
return Objects.equals(elements, other.elements);
}


}
Expand Up @@ -132,7 +132,7 @@ public long step() {

@Override
public void setParameter(final String parameterName, final Object value) {
if (this.params.containsKey(parameterName)) { this.params.remove(parameterName); }
// if (this.params.containsKey(parameterName)) { this.params.remove(parameterName); }
this.params.put(parameterName, value);
}

Expand Down

0 comments on commit 2c141f8

Please sign in to comment.