diff --git a/README.md b/README.md index a175170..cfa870c 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ First, you need to add the following repository, which is a repository that can ``` Than you can add the dependency on our `aitoa-code` repository into your `dependencies` section. -Here, `0.8.71` is the current version of `aitoa-code`. +Here, `0.8.72` is the current version of `aitoa-code`. Notice that you may have more dependencies in your `dependencies` section, say on `junit`, but here I just put the one for `aitoa-code` as example. ```xml @@ -52,7 +52,7 @@ Notice that you may have more dependencies in your `dependencies` section, say o com.github.thomasWeise aitoa-code - 0.8.71 + 0.8.72 ``` diff --git a/pom.xml b/pom.xml index 0652510..5da949e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ aitoa aitoa-code - 0.8.71 + 0.8.72 jar aitoa-code Example Source Codes from the Book "Introduction to Optimization Algorithms" diff --git a/src/main/java/aitoa/examples/jssp/JSSPMakespanObjectiveFunction2.java b/src/main/java/aitoa/examples/jssp/JSSPMakespanObjectiveFunction2.java index 72dc649..8f2c7ee 100644 --- a/src/main/java/aitoa/examples/jssp/JSSPMakespanObjectiveFunction2.java +++ b/src/main/java/aitoa/examples/jssp/JSSPMakespanObjectiveFunction2.java @@ -6,8 +6,9 @@ import aitoa.structure.IObjectiveFunction; /** - * The makespan objective function working directly on the - * order-based representation. + * A variant of the {@linkplain JSSPMakespanObjectiveFunction + * makespan objective function} working directly on the + * order-based representation, i.e., {@code int[]}. */ public final class JSSPMakespanObjectiveFunction2 implements IObjectiveFunction { @@ -16,8 +17,6 @@ public final class JSSPMakespanObjectiveFunction2 /** the current time at a given machine */ private final int[] mMachineTime; - /** the current step index at a given machine */ - private final int[] mMachineState; /** the step index of the current job */ private final int[] mJobState; /** the time of the current job */ @@ -32,28 +31,27 @@ public final class JSSPMakespanObjectiveFunction2 /** * create the representation * - * @param _instance + * @param pinstance * the problem instance */ public JSSPMakespanObjectiveFunction2( - final JSSPInstance _instance) { + final JSSPInstance pinstance) { super(); - this.instance = Objects.requireNonNull(_instance); - this.mJobs = _instance.jobs; - this.mJobState = new int[_instance.n]; - this.mJobTime = new int[_instance.n]; - this.mMachineTime = new int[_instance.m]; - this.mMachineState = new int[_instance.m]; + this.instance = Objects.requireNonNull(pinstance); + this.mJobs = pinstance.jobs; + this.mJobState = new int[pinstance.n]; + this.mJobTime = new int[pinstance.n]; + this.mMachineTime = new int[pinstance.m]; } /** * create * - * @param _instance + * @param pinstance * the instance */ - public JSSPMakespanObjectiveFunction2(final String _instance) { - this(new JSSPInstance(_instance)); + public JSSPMakespanObjectiveFunction2(final String pinstance) { + this(new JSSPInstance(pinstance)); } /** {@inheritDoc} */ @@ -65,17 +63,14 @@ public String toString() { /** {@inheritDoc} */ @Override public double evaluate(final int[] y) { - final int[] machineState = this.mMachineState; final int[] machineTime = this.mMachineTime; final int[] jobState = this.mJobState; final int[] jobTime = this.mJobTime; - Arrays.fill(machineState, 0); Arrays.fill(jobState, 0); Arrays.fill(machineTime, 0); Arrays.fill(jobTime, 0); - + // iterate over the jobs in the solution - int end = -1; for (final int nextJob : y) { // jobState tells us the index in this list for the next step to // do, but since the list contains machine/time pairs, we @@ -86,19 +81,19 @@ public double evaluate(final int[] y) { final int[] jobSteps = this.mJobs[nextJob]; // so we know the machine where the job needs to go next final int machine = jobSteps[jobStep]; // get machine -// start time is maximum of the next time when the machine -// becomes idle and the time we have already spent on the job - final int start = - Math.max(machineTime[machine], jobTime[nextJob]); -// the end time is simply the start time plus the time the job -// needs to spend on the machine - end = start + jobSteps[jobStep + 1]; // end time -// it holds for both the machine (it will become idle after end) +// The start time is maximum of the next time when the machine +// becomes idle and the time we have already spent on the job. +// The end time is simply the start time plus the time the job +// needs to spend on the machine. +// It holds for both the machine (it will become idle after end) // and the job (it can go to the next station after end) - jobTime[nextJob] = machineTime[machine] = end; + jobTime[nextJob] = machineTime[machine] = // + Math.max(machineTime[machine], jobTime[nextJob]) // + + jobSteps[jobStep + 1]; // end time } // compute the makespan + int end = -1; for (final int v : (machineTime.length > jobTime.length) ? jobTime : machineTime) { if (v > end) { diff --git a/src/test/java/aitoa/examples/jssp/TestEJSSPExperimentStage.java b/src/test/java/aitoa/examples/jssp/TestEJSSPExperimentStage.java new file mode 100644 index 0000000..79944d1 --- /dev/null +++ b/src/test/java/aitoa/examples/jssp/TestEJSSPExperimentStage.java @@ -0,0 +1,32 @@ +package aitoa.examples.jssp; + +import java.util.stream.Stream; + +import aitoa.structure.IMetaheuristic; +import aitoa.utils.Experiment.IExperimentStage; +import aitoa.utils.TestExperimentStages; + +/** Test the {@link EJSSPExperimentStage} */ +public class TestEJSSPExperimentStage extends + TestExperimentStages, + IExperimentStage>> { + + /** create */ + public TestEJSSPExperimentStage() { + super(); + } + + /** {@inheritDoc} */ + @Override + protected + Stream>> + getInstance() { + return Stream.of(EJSSPExperimentStage.values()); + } +} diff --git a/src/test/java/aitoa/examples/jssp/TestEJSSPExperimentStageACO.java b/src/test/java/aitoa/examples/jssp/TestEJSSPExperimentStageACO.java new file mode 100644 index 0000000..ec87d60 --- /dev/null +++ b/src/test/java/aitoa/examples/jssp/TestEJSSPExperimentStageACO.java @@ -0,0 +1,34 @@ +package aitoa.examples.jssp; + +import java.util.stream.Stream; + +import aitoa.examples.jssp.aco.JSSPACOMakespanObjectiveFunction; +import aitoa.examples.jssp.aco.JSSPACORecord; +import aitoa.structure.IMetaheuristic; +import aitoa.utils.Experiment.IExperimentStage; +import aitoa.utils.TestExperimentStages; + +/** Test the {@link EJSSPExperimentStageACO} */ +public class TestEJSSPExperimentStageACO extends + TestExperimentStages, + IExperimentStage>> { + + /** create */ + public TestEJSSPExperimentStageACO() { + super(); + } + + /** {@inheritDoc} */ + @Override + protected + Stream>> + getInstance() { + return Stream.of(EJSSPExperimentStageACO.values()); + } +} diff --git a/src/test/java/aitoa/utils/TestExperimentStage.java b/src/test/java/aitoa/utils/TestExperimentStage.java new file mode 100644 index 0000000..af60aa0 --- /dev/null +++ b/src/test/java/aitoa/utils/TestExperimentStage.java @@ -0,0 +1,100 @@ +package aitoa.utils; + +import java.io.CharArrayWriter; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import aitoa.ObjectTest; +import aitoa.TestTools; +import aitoa.structure.BlackBoxProcessBuilder; +import aitoa.structure.IMetaheuristic; +import aitoa.structure.IObjectiveFunction; +import aitoa.utils.Experiment.IExperimentStage; + +/** + * Test an experiment stage + * + * @param + * the search space type + * @param + * the solution space type + * @param

+ * the problem type + * @param + * the metaheuristic type + * @param + * the experiment stage type + */ +@Ignore +public abstract class TestExperimentStage, + M extends IMetaheuristic, + S extends IExperimentStage> + extends ObjectTest { + + /** create */ + protected TestExperimentStage() { + super(); + } + + /** + * test the experiment stage via the + * {@link IExperimentStage#getProblems()} method + */ + @Test(timeout = 3600000) + public void testStage() { + final S stage = this.getInstance(); + Assert.assertNotNull(stage); + + final BlackBoxProcessBuilder builder = + new BlackBoxProcessBuilder<>(); + stage.configureBuilder(builder); + + final Stream> problems = stage.getProblems(); + Assert.assertNotNull(problems); + + problems.forEach(supplier -> { + Assert.assertNotNull(supplier); + final P problem = supplier.get(); + Assert.assertNotNull(problem); + + stage.configureBuilderForProblem(builder, problem); + + TestTools.assertGreater( + Experiment.nameFromObjectPrepare(problem).length(), 0); + TestTools.assertGreaterOrEqual(problem.upperBound(), + problem.lowerBound()); + final int runs = stage.getRuns(problem); + TestTools.assertGreaterOrEqual(runs, 0); + if (runs > 0) { + final Stream> algorithms = + stage.getAlgorithms(problem); + Assert.assertNotNull(algorithms); + algorithms.forEach((asupplier) -> { + Assert.assertNotNull(asupplier); + final M algorithm = asupplier.get(); + Assert.assertNotNull(algorithm); + try (final CharArrayWriter caw = + new CharArrayWriter()) { + algorithm.printSetup(caw); + } catch (final Throwable error) { + throw new AssertionError( + "There should be no error here.", //$NON-NLS-1$ + error); + } + }); + } + }); + } + + /** {@inheritDoc} */ + @Override + protected void runAllTests() { + super.runAllTests(); + this.testStage(); + } +} diff --git a/src/test/java/aitoa/utils/TestExperimentStages.java b/src/test/java/aitoa/utils/TestExperimentStages.java new file mode 100644 index 0000000..053b277 --- /dev/null +++ b/src/test/java/aitoa/utils/TestExperimentStages.java @@ -0,0 +1,65 @@ +package aitoa.utils; + +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import aitoa.ObjectTest; +import aitoa.structure.IMetaheuristic; +import aitoa.structure.IObjectiveFunction; +import aitoa.utils.Experiment.IExperimentStage; + +/** + * Test a stream of experiment stages + * + * @param + * the search space type + * @param + * the solution space type + * @param

+ * the problem type + * @param + * the metaheuristic type + * @param + * the experiment stage type + */ +@Ignore +public abstract class TestExperimentStages, + M extends IMetaheuristic, + S extends IExperimentStage> + extends ObjectTest> { + + /** create */ + protected TestExperimentStages() { + super(); + } + + /** + * test the experiment stage via the + * {@link IExperimentStage#getProblems()} method + */ + @Test(timeout = 3600000) + public void testStages() { + final Stream stages = this.getInstance(); + Assert.assertNotNull(stages); + + stages.forEach(stage -> { + new TestExperimentStage() { + @Override + protected S getInstance() { + return stage; + } + }.runAllTests(); + }); + } + + /** {@inheritDoc} */ + @Override + protected void runAllTests() { + super.runAllTests(); + this.testStages(); + } +}