Skip to content
Snippets Groups Projects
Commit accfea33 authored by Johannes Mey's avatar Johannes Mey
Browse files

implement timeout. improve gnetic solver.

parent 1b09fe6a
No related branches found
No related tags found
No related merge requests found
Showing
with 216 additions and 31 deletions
...@@ -32,7 +32,8 @@ public class SolverFactory { ...@@ -32,7 +32,8 @@ public class SolverFactory {
new ILPDirectSolver(), new ILPDirectSolver(),
new SimpleSolver(), new SimpleSolver(),
new RandomSolver(0, 0), new RandomSolver(0, 0),
new GeneticSolver() new GeneticSolver(GeneticSolver.SelectorType.NSGA2, 200000, 1000),
new GeneticSolver(GeneticSolver.SelectorType.SPEA2, 200000, 1000)
).collect(Collectors.toMap(BenchmarkableSolver::getName, Function.identity())); ).collect(Collectors.toMap(BenchmarkableSolver::getName, Function.identity()));
} }
return availableSolvers; return availableSolvers;
......
package de.tudresden.inf.st.mquat.solving.genetic; package de.tudresden.inf.st.mquat.solving.genetic;
import de.tudresden.inf.st.mquat.generator.ScenarioDescription;
import de.tudresden.inf.st.mquat.jastadd.model.Root; import de.tudresden.inf.st.mquat.jastadd.model.Root;
import de.tudresden.inf.st.mquat.jastadd.model.Solution; import de.tudresden.inf.st.mquat.jastadd.model.Solution;
import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver; import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver;
...@@ -10,8 +9,7 @@ import de.tudresden.inf.st.mquat.solving.genetic.opt4j.Opt4jModule; ...@@ -10,8 +9,7 @@ import de.tudresden.inf.st.mquat.solving.genetic.opt4j.Opt4jModule;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.operator.copy.TreeCopyOperatorModule; import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.operator.copy.TreeCopyOperatorModule;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.operator.crossover.TreeCrossoverOperatorModule; import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.operator.crossover.TreeCrossoverOperatorModule;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.operator.mutate.TreeMutateOperatorModule; import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.operator.mutate.TreeMutateOperatorModule;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.operators.diversity.TreeDiversityOperator; import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.optimizer.TimeOutOptimizerModule;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.operators.diversity.TreeDiversityOperatorModule;
import de.tudresden.inf.st.mquat.utils.StopWatch; import de.tudresden.inf.st.mquat.utils.StopWatch;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
...@@ -20,12 +18,12 @@ import org.opt4j.core.optimizer.Archive; ...@@ -20,12 +18,12 @@ import org.opt4j.core.optimizer.Archive;
import org.opt4j.core.start.Opt4JTask; import org.opt4j.core.start.Opt4JTask;
import org.opt4j.optimizers.ea.EvolutionaryAlgorithmModule; import org.opt4j.optimizers.ea.EvolutionaryAlgorithmModule;
import org.opt4j.optimizers.ea.Nsga2Module; import org.opt4j.optimizers.ea.Nsga2Module;
import org.opt4j.viewer.ViewerModule; import org.opt4j.optimizers.ea.Spea2Module;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
//import org.opt4j.viewer.ViewerModule;
public class GeneticSolver implements BenchmarkableSolver { public class GeneticSolver implements BenchmarkableSolver {
private static final Logger logger = LogManager.getLogger(GeneticSolver.class); private static final Logger logger = LogManager.getLogger(GeneticSolver.class);
...@@ -38,25 +36,30 @@ public class GeneticSolver implements BenchmarkableSolver { ...@@ -38,25 +36,30 @@ public class GeneticSolver implements BenchmarkableSolver {
private StopWatch stopWatch; private StopWatch stopWatch;
private long maxSolvingTime; private long maxSolvingTime;
private int generations;
private int populationSize;
private SelectorType selectorType;
private boolean timedOut; private boolean timedOut;
public GeneticSolver() { public GeneticSolver() {
this(Long.MAX_VALUE); this(SelectorType.NSGA2, 100, 100);
} }
public GeneticSolver(long maxSolvingTime) { public GeneticSolver(SelectorType evaluatorType, int generations, int populationSize) {
this.maxSolvingTime = maxSolvingTime; this.selectorType = evaluatorType;
this.generations = generations;
this.populationSize = populationSize;
reset(); reset();
} }
@Override @Override
public Solution solve(Root model) throws SolvingException { public Solution solve(Root model) throws SolvingException {
reset(); reset();
stopWatch = StopWatch.start(); stopWatch = StopWatch.start();
List<Solution> solutions = new ArrayList<>();
if (model.getNumRequest() == 0) { if (model.getNumRequest() == 0) {
return Solution.emptySolutionOf(model); return Solution.emptySolutionOf(model);
} }
...@@ -65,39 +68,48 @@ public class GeneticSolver implements BenchmarkableSolver { ...@@ -65,39 +68,48 @@ public class GeneticSolver implements BenchmarkableSolver {
Opt4jModule.setModel(model); Opt4jModule.setModel(model);
EvolutionaryAlgorithmModule ea = new EvolutionaryAlgorithmModule(); EvolutionaryAlgorithmModule ea = new EvolutionaryAlgorithmModule();
ea.setGenerations(20000); ea.setGenerations(this.generations);
// set population size // set population size
ea.setAlpha(100); ea.setAlpha(this.populationSize);
Opt4jModule mquatModule = new Opt4jModule(); Opt4jModule mquatModule = new Opt4jModule();
mquatModule.setMaxSolvingTime(this.maxSolvingTime);
TreeCrossoverOperatorModule crossover = new TreeCrossoverOperatorModule(); TreeCrossoverOperatorModule crossover = new TreeCrossoverOperatorModule();
TreeMutateOperatorModule mutate = new TreeMutateOperatorModule(); TreeMutateOperatorModule mutate = new TreeMutateOperatorModule();
TreeCopyOperatorModule copy = new TreeCopyOperatorModule(); TreeCopyOperatorModule copy = new TreeCopyOperatorModule();
TimeOutOptimizerModule optimizerModule = new TimeOutOptimizerModule();
// ViewerModule viewer = new ViewerModule(); // ViewerModule viewer = new ViewerModule();
// viewer.setCloseOnStop(false); // viewer.setCloseOnStop(false);
Opt4JTask task = new Opt4JTask(false); Opt4JTask task = new Opt4JTask(false);
task.init(ea, mquatModule, crossover, mutate, copy); switch (this.selectorType) {
// task.init(diversity, ea, nsga2, mquatModule, viewer, crossover, mutate, copy); case NSGA2:
Nsga2Module nsga2 = new Nsga2Module();
task.init(optimizerModule, ea, nsga2, mquatModule, crossover, mutate, copy);
// task.init(optimizerModule, ea, nsga2, mquatModule, crossover, mutate, copy, viewer);
break;
case SPEA2:
Spea2Module spea2 = new Spea2Module();
task.init(optimizerModule, ea, spea2, mquatModule, crossover, mutate, copy);
// task.init(optimizerModule, ea, spea2, mquatModule, crossover, mutate, copy, viewer);
}
try { try {
task.execute(); task.execute();
Archive archive = task.getInstance(Archive.class); Archive archive = task.getInstance(Archive.class);
for (Individual individual : archive) { for (Individual individual : archive) {
// obtain the phenotype and objective, etc. of each individual // obtain the phenotype and objective, etc. of each individual
Solution solution = (Solution) individual.getPhenotype(); Solution solution = (Solution) individual.getPhenotype();
if (solution.isValid()) { int validity = solution.evaluateValidity();
if (solutions.isEmpty() || solution.computeObjective() < solutions.get(solutions.size() - 1).computeObjective()) { double objective = solution.computeObjective();
Solution clone = solution.deepCopy(); // TODO only works with minimized objective
solutions.add(clone); if (lastSolution == null || validity < lastSolution.evaluateValidity() || (validity == lastSolution.evaluateValidity() && objective < lastSolution.computeObjective())) {
logger.info("found a better solution with an objective of {}.", solution.computeObjective()); lastSolution = solution.deepCopy();
logger.info("found a better solution with {} errors and an objective of {}.", validity, objective);
} }
} else {
logger.warn("Found an invalid solution with " + solution.evaluateValidity() + " errors.");
}
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
...@@ -105,9 +117,7 @@ public class GeneticSolver implements BenchmarkableSolver { ...@@ -105,9 +117,7 @@ public class GeneticSolver implements BenchmarkableSolver {
task.close(); task.close();
} }
if (solutions.size() > 0) { if (lastSolution == null) {
lastSolution = solutions.get(solutions.size() - 1);
} else {
lastSolution = Solution.emptySolutionOf(model); lastSolution = Solution.emptySolutionOf(model);
logger.warn("Found no solution!"); logger.warn("Found no solution!");
} }
...@@ -126,7 +136,7 @@ public class GeneticSolver implements BenchmarkableSolver { ...@@ -126,7 +136,7 @@ public class GeneticSolver implements BenchmarkableSolver {
@Override @Override
public String getName() { public String getName() {
return "genetic"; return "genetic_" + this.selectorType.name();
} }
@Override @Override
...@@ -154,4 +164,9 @@ public class GeneticSolver implements BenchmarkableSolver { ...@@ -154,4 +164,9 @@ public class GeneticSolver implements BenchmarkableSolver {
public boolean hadTimeout() { public boolean hadTimeout() {
return this.timedOut; return this.timedOut;
} }
public enum SelectorType {
NSGA2,
SPEA2
}
} }
package de.tudresden.inf.st.mquat.solving.genetic.opt4j; package de.tudresden.inf.st.mquat.solving.genetic.opt4j;
import de.tudresden.inf.st.mquat.jastadd.model.Root; import de.tudresden.inf.st.mquat.jastadd.model.Root;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.optimizer.MaxSolvingTime;
import org.opt4j.core.problem.ProblemModule; import org.opt4j.core.problem.ProblemModule;
public class Opt4jModule extends ProblemModule { public class Opt4jModule extends ProblemModule {
@MaxSolvingTime
public Long maxSolvingTime = Long.MAX_VALUE;
private static Root model; private static Root model;
public static Root getModel() { public static Root getModel() {
...@@ -15,9 +18,14 @@ public class Opt4jModule extends ProblemModule { ...@@ -15,9 +18,14 @@ public class Opt4jModule extends ProblemModule {
Opt4jModule.model = model; Opt4jModule.model = model;
} }
public void setMaxSolvingTime(long maxSolvingTime) {
this.maxSolvingTime = maxSolvingTime;
}
@Override @Override
protected void configure() { protected void configure() {
bindProblem(Opt4jCreator.class, Opt4jDecoder.class, Opt4jEvaluator.class); bindProblem(Opt4jCreator.class, Opt4jDecoder.class, Opt4jEvaluator.class);
bindConstant(MaxSolvingTime.class).to(maxSolvingTime);
} }
@Override @Override
......
package de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.optimizer;
import com.google.inject.BindingAnnotation;
import org.opt4j.core.optimizer.Optimizer;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* The {@link MaxSolvingTime} is the default binding annotation for the maximum
* solving time for an {@link Optimizer}.
*
* @author johannes.mey
*/
@Retention(RUNTIME)
@BindingAnnotation
public @interface MaxSolvingTime {
}
/*******************************************************************************
* Copyright (c) 2014 Opt4J
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.optimizer;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.opt4j.core.optimizer.Iteration;
import org.opt4j.core.optimizer.MaxIterations;
/**
* The {@link Iteration} object is used as iteration counter for the
* optimization.
*
* @author lukasiewycz
*
*/
@Singleton
public class TimeOutIteration extends Iteration {
protected final Long maxSolvingTime;
/**
* Constructs a {@link Iteration} object.
*
* @param maxIterations
* the maximal number of iterations
*/
@Inject
public TimeOutIteration(@MaxIterations int maxIterations, @MaxSolvingTime Long maxSolvingTime) {
super(maxIterations);
this.maxSolvingTime = maxSolvingTime;
}
/**
* Returns the maximal number of iterations.
*
* @return the maximal number of iterations
*/
public long maxTime() {
return maxSolvingTime;
}
}
package de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.optimizer;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import de.tudresden.inf.st.mquat.solving.genetic.GeneticSolver;
import de.tudresden.inf.st.mquat.utils.StopWatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opt4j.core.optimizer.*;
import java.util.concurrent.TimeUnit;
/**
* The {@link org.opt4j.core.optimizer.OptimizationMediator} performs the overall optimization process
* for the {@link IterativeOptimizer}.
*
* @author reimann, glass, lukasiewycz
*
*/
@Singleton
public class TimeOutOptimizer extends AbstractOptimizer {
private static final Logger logger = LogManager.getLogger(TimeOutOptimizer.class);
protected final IterativeOptimizer iterativeOptimizer;
/**
* Creates a new {@link org.opt4j.core.optimizer.OptimizationMediator}.
*
* @param iterativeOptimizer
* the iterative optimizer to use
* @param population
* the specified population
* @param archive
* the specified archive
* @param completer
* the specified completer
* @param control
* the control
* @param iteration
* the iteration counter
*/
@Inject
public TimeOutOptimizer(IterativeOptimizer iterativeOptimizer, Population population, Archive archive,
IndividualCompleter completer, Control control, TimeOutIteration iteration) {
super(population, archive, completer, control, iteration);
this.iterativeOptimizer = iterativeOptimizer;
}
/*
* (non-Javadoc)
*
* @see org.opt4j.core.optimizer.Optimizer#optimize()
*/
@Override
public void optimize() throws StopException, TerminationException {
iterativeOptimizer.initialize();
StopWatch watch = StopWatch.start();
while (iteration.value() < iteration.max() && watch.time(TimeUnit.MILLISECONDS) < ((TimeOutIteration)iteration).maxTime()) {
iterativeOptimizer.next();
nextIteration();
}
logger.info("Stopped after {} iterations.", iteration.value());
}
}
package de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.optimizer;
import org.opt4j.core.optimizer.OptimizerModule;
public class TimeOutOptimizerModule extends OptimizerModule {
@Override
protected void config() {
bindOptimizer(TimeOutOptimizer.class);
}
}
...@@ -6,6 +6,6 @@ public class GeneticHandwrittenTest extends HandwrittenTestSuite { ...@@ -6,6 +6,6 @@ public class GeneticHandwrittenTest extends HandwrittenTestSuite {
@Override @Override
protected Solver getSolver() { protected Solver getSolver() {
return new GeneticSolver(10000); return new GeneticSolver(GeneticSolver.SelectorType.NSGA2, 10000, 1000);
} }
} }
...@@ -42,7 +42,7 @@ public class GeneticSolverTest { ...@@ -42,7 +42,7 @@ public class GeneticSolverTest {
ScenarioGenerator generator = new ScenarioGenerator(new ScenarioDescription(tlc, iac, isd, cac, csd, dep, imp, res, req, cpu, seed)); ScenarioGenerator generator = new ScenarioGenerator(new ScenarioDescription(tlc, iac, isd, cac, csd, dep, imp, res, req, cpu, seed));
Root model = generator.generate(); Root model = generator.generate();
GeneticSolver solver = new GeneticSolver(20000); GeneticSolver solver = new GeneticSolver(GeneticSolver.SelectorType.NSGA2, 20000, 1000);
Solution solution = solver.solve(model); Solution solution = solver.solve(model);
......
...@@ -11,6 +11,7 @@ import org.junit.rules.ErrorCollector; ...@@ -11,6 +11,7 @@ import org.junit.rules.ErrorCollector;
import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.core.IsEqual.equalTo; import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
...@@ -31,6 +32,7 @@ public abstract class HandwrittenTestSuite { ...@@ -31,6 +32,7 @@ public abstract class HandwrittenTestSuite {
@Before @Before
public void setupSolverForTest() { public void setupSolverForTest() {
this.solver = getSolver(); this.solver = getSolver();
solver.setTimeout(30, TimeUnit.SECONDS);
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment