diff --git a/jastadd-mquat-benchmark/build.gradle b/jastadd-mquat-benchmark/build.gradle index 19d628181a8178da5c7fac022832a56cfa824e4b..945310193b6bb88de3fef9a266ed74a72d9d5436 100644 --- a/jastadd-mquat-benchmark/build.gradle +++ b/jastadd-mquat-benchmark/build.gradle @@ -16,6 +16,7 @@ dependencies { compile project(':jastadd-mquat-solver-ilp') compile project(':jastadd-mquat-solver-emfer') compile project(':jastadd-mquat-solver-genetic') + compile project(':jastadd-mquat-solver-random') compile project(':jastadd-mquat-solver-simple') compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1' compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0' diff --git a/jastadd-mquat-solver-random/.gitignore b/jastadd-mquat-solver-random/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..567609b1234a9b8806c5a05da6c866e480aa148d --- /dev/null +++ b/jastadd-mquat-solver-random/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/jastadd-mquat-solver-random/build.gradle b/jastadd-mquat-solver-random/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..3e180690f12cb0f3da70298777a3ac432156ebc8 --- /dev/null +++ b/jastadd-mquat-solver-random/build.gradle @@ -0,0 +1,17 @@ + +apply plugin: 'java' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0' + compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0' + compile project(':jastadd-mquat-base') + compile project(':jastadd-mquat-solver') + testCompile group: 'junit', name: 'junit', version: '4.12' + testCompile project(path: ':jastadd-mquat-solver', configuration: 'testArtifacts') +} diff --git a/jastadd-mquat-solver-random/src/main/java/de/tudresden/inf/st/mquat/solving/random/RandomSolver.java b/jastadd-mquat-solver-random/src/main/java/de/tudresden/inf/st/mquat/solving/random/RandomSolver.java new file mode 100644 index 0000000000000000000000000000000000000000..476d6b5698ac174bbd8c2e2895f521f9913b2bd1 --- /dev/null +++ b/jastadd-mquat-solver-random/src/main/java/de/tudresden/inf/st/mquat/solving/random/RandomSolver.java @@ -0,0 +1,131 @@ +package de.tudresden.inf.st.mquat.solving.random; + +import de.tudresden.inf.st.mquat.jastadd.model.*; +import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver; +import de.tudresden.inf.st.mquat.solving.Solver; +import de.tudresden.inf.st.mquat.solving.SolverUtils; +import de.tudresden.inf.st.mquat.solving.SolvingException; +import de.tudresden.inf.st.mquat.utils.StopWatch; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.*; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class RandomSolver implements BenchmarkableSolver { + + private static final Logger logger = LogManager.getLogger(RandomSolver.class); + + private Solution lastSolution; + private long lastSolvingTime; + + private int solutionCounter; + + private StopWatch stopWatch; + + private long maxSolvingTime; + private boolean timedOut; + + public RandomSolver() { + this(Long.MAX_VALUE); + } + + public RandomSolver(long maxSolvingTime) { + this.maxSolvingTime = maxSolvingTime; + reset(); + } + + + @Override + public Solution solve(Root model) throws SolvingException { + reset(); + if (model.getNumRequest() == 0) { + return Solution.emptySolutionOf(model); + } + int numAssignments = 0; + int numTotalSoftwareSolutions = 0; + + stopWatch = StopWatch.start(); + + List<Solution> solutions = new ArrayList<>(); + + Random random = new Random(); + + do { + + numTotalSoftwareSolutions++; + + Solution solution = model.createRandomSolution(random); +// logger.debug("\n" + solution.print(new MquatWriteSettings(" ")).toString()); + + + if (solution.isValid()) { + solutionCounter++; + if (solutions.isEmpty() || solution.computeObjective() < solutions.get(solutions.size() - 1).computeObjective()) { + solutions.add(solution); + logger.info("found a better solution with an objective of {}.", solution.computeObjective()); + } + } + + if (stopWatch.time(TimeUnit.MILLISECONDS) > maxSolvingTime) { + this.timedOut = true; + logger.warn("Timeout! Solving terminated!"); + break; + } + + } while (true); + + logger.info("Number of iterated solutions: {}", numTotalSoftwareSolutions); + logger.info("Number of correct solutions: {}", solutionCounter); + + if (solutions.size() > 0) { + lastSolution = solutions.get(solutions.size() - 1); + } else { + lastSolution = Solution.emptySolutionOf(model); + logger.warn("Found no solution!"); + } + + lastSolvingTime = stopWatch.time(TimeUnit.MILLISECONDS); + + return lastSolution; + } + + private void reset() { + this.lastSolution = null; + this.solutionCounter = 0; + this.lastSolvingTime = 0; + this.timedOut = false; + } + + @Override + public String getName() { + return "random"; + } + + @Override + public long getLastSolvingTime() { + return lastSolvingTime; + } + + @Override + public double getLastObjective() { + if (lastSolution != null) { + return lastSolution.computeObjective(); + } else { + // TODO throw exception or do something reasonable + return 0d; + } + } + + @Override + public Solver setTimeout(long timeoutValue, TimeUnit timeoutUnit) { + this.maxSolvingTime = timeoutUnit.toMillis(timeoutValue); + return this; + } + + @Override + public boolean hadTimeout() { + return this.timedOut; + } +} diff --git a/jastadd-mquat-solver-random/src/test/java/de/tudresden/inf/st/mquat/solving/RandomHandwrittenTest.java b/jastadd-mquat-solver-random/src/test/java/de/tudresden/inf/st/mquat/solving/RandomHandwrittenTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6641db6740f23a5f97863198a9016c4d2314455b --- /dev/null +++ b/jastadd-mquat-solver-random/src/test/java/de/tudresden/inf/st/mquat/solving/RandomHandwrittenTest.java @@ -0,0 +1,11 @@ +package de.tudresden.inf.st.mquat.solving; + +import de.tudresden.inf.st.mquat.solving.random.RandomSolver; + +public class RandomHandwrittenTest extends HandwrittenTestSuite { + + @Override + protected Solver getSolver() { + return new RandomSolver(60000); + } +} diff --git a/jastadd-mquat-solver-random/src/test/java/de/tudresden/inf/st/mquat/solving/RandomSolverTest.java b/jastadd-mquat-solver-random/src/test/java/de/tudresden/inf/st/mquat/solving/RandomSolverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..32c5722a2cf3489e603cd6c828fad4ca3d037d16 --- /dev/null +++ b/jastadd-mquat-solver-random/src/test/java/de/tudresden/inf/st/mquat/solving/RandomSolverTest.java @@ -0,0 +1,54 @@ +package de.tudresden.inf.st.mquat.solving; + +import de.tudresden.inf.st.mquat.generator.ScenarioDescription; +import de.tudresden.inf.st.mquat.generator.ScenarioGenerator; +import de.tudresden.inf.st.mquat.jastadd.model.Root; +import de.tudresden.inf.st.mquat.jastadd.model.Solution; +import de.tudresden.inf.st.mquat.solving.random.RandomSolver; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class RandomSolverTest { + + private static Logger logger; + + @BeforeClass + public static void initLogger() { + logger = LogManager.getLogger(RandomSolverTest.class); + } + + /** + * tests the simple solver with one very simple use case + */ + @Test + public void testRandomSolver() throws SolvingException { + int tlc = 1; + int iac = 2; + int isd = 0; + int cac = 0; + int csd = 0; + int dep = 2; + int imp = 1; + int mod = 3; + double res = 1.5d; + int nfp = 0; + int req = 3; + int cpu = 1; + int seed = 0; + + ScenarioGenerator generator = new ScenarioGenerator(new ScenarioDescription(tlc, iac, isd, cac, csd, dep, imp, res, req, cpu, seed)); + + Root model = generator.generate(); + RandomSolver solver = new RandomSolver(5000); + + Solution solution = solver.solve(model); + + Assert.assertNotNull(solution); + + logger.info("the best solution is {} and has an objective of {}.", (solution.isValid() ? "valid" : "invalid"), solution.computeObjective()); + + } +} diff --git a/settings.gradle b/settings.gradle index 68483c92ddef68cc8ecb5ff6a4f004827b3ebd91..eeaefce2d0ad22ca928b920befe3e38d5a21aa2d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,6 +6,7 @@ include ':jastadd-mquat-solver' include ':jastadd-mquat-solver-ilp' include ':jastadd-mquat-solver-emfer' include ':jastadd-mquat-solver-genetic' +include ':jastadd-mquat-solver-random' include ':jastadd-mquat-solver-simple' include 'jastadd-mquat-solver-aco'