diff --git a/README.md b/README.md
index 94e0b7e..b71d8a9 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.40` is the current version of `aitoa-code`.
+Here, `0.8.41` 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.40
+ 0.8.41
```
diff --git a/pom.xml b/pom.xml
index d309cc5..c90c0ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
aitoa
aitoa-code
- 0.8.40
+ 0.8.41
jar
aitoa-code
Example Source Codes from the Book "Introduction to Optimization Algorithms"
@@ -203,7 +203,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.2.2
+ 3.2.1
package
diff --git a/src/main/java/aitoa/algorithms/EAWithPruning.java b/src/main/java/aitoa/algorithms/EAWithPruning.java
index 2358fb9..74640a8 100644
--- a/src/main/java/aitoa/algorithms/EAWithPruning.java
+++ b/src/main/java/aitoa/algorithms/EAWithPruning.java
@@ -160,8 +160,8 @@ public final void solve(final IBlackBoxProcess process) {
// we switch the two arrays here so the rest is the same as EA
makeUnique: for (final Individual ind : P2) {
++done;
- if ((unique <= 0)
- || (ind.quality > P[unique - 1].quality)) {
+ if ((unique <= 0) || //
+ (ind.quality > P[unique - 1].quality)) {
P[unique] = ind;
if ((++unique) >= this.mu) { // we are done and can
System.arraycopy(P2, done, P, unique, // copy the
@@ -184,7 +184,8 @@ public final void solve(final IBlackBoxProcess process) {
}
final Individual dest = P[index];
- final Individual sel = P[(++p1) % unique];
+ p1 = (p1 + 1) % unique;
+ final Individual sel = P[p1];
if ((unique >= 2) && (random.nextDouble() <= this.cr)) {
int p2; // to hold index of second selected record
do { // find a second, different record
diff --git a/src/main/java/aitoa/algorithms/MA.java b/src/main/java/aitoa/algorithms/MA.java
index 0db227e..46635f2 100644
--- a/src/main/java/aitoa/algorithms/MA.java
+++ b/src/main/java/aitoa/algorithms/MA.java
@@ -156,7 +156,7 @@ public final void solve(final IBlackBoxProcess process) {
if (newQuality < ind.quality) { // better?
ind.quality = newQuality; // store quality
searchSpace.copy(point, ind.x); // store point
- return (true); // exit to next loop
+ return true; // exit to next loop
} // if we get here, point is not better
return process.shouldTerminate();
}); // repeat this until no improvement or time is
diff --git a/src/main/java/aitoa/algorithms/MAWithPruning.java b/src/main/java/aitoa/algorithms/MAWithPruning.java
index 043fcc7..99301fd 100644
--- a/src/main/java/aitoa/algorithms/MAWithPruning.java
+++ b/src/main/java/aitoa/algorithms/MAWithPruning.java
@@ -176,11 +176,10 @@ public final void solve(final IBlackBoxProcess process) {
if (newQuality < ind.quality) { // better?
ind.quality = newQuality; // store quality
searchSpace.copy(point, ind.x); // store
- return (true); // exit to next loop
+ return true; // exit to next loop
} // if we get here, point is not better
return process.shouldTerminate();
- }); // repeat this until no improvement or time
- // is up
+ }); // repeat until no improvement or time up
if (process.shouldTerminate()) { // we return
return; // best solution is stored in process
}
@@ -198,8 +197,8 @@ public final void solve(final IBlackBoxProcess process) {
// we switch the two arrays here so the rest is the same as EA
makeUnique: for (final Individual ind : P2) {
++done;
- if ((unique <= 0)
- || (ind.quality > P[unique - 1].quality)) {
+ if ((unique <= 0) || //
+ (ind.quality > P[unique - 1].quality)) {
P[unique] = ind;
if ((++unique) >= this.mu) { // we are done and can
System.arraycopy(P2, done, P, unique, // copy the
@@ -224,7 +223,8 @@ public final void solve(final IBlackBoxProcess process) {
return; // best solution is stored in process
}
final Individual dest = P[index];
- final Individual sel = P[(++p1) % unique];
+ p1 = (p1 + 1) % unique;
+ final Individual sel = P[p1];
// to hold index of second selected record
do { // find a second, different record
p2 = random.nextInt(unique);
diff --git a/src/main/java/aitoa/examples/jssp/EJSSPExperimentStage.java b/src/main/java/aitoa/examples/jssp/EJSSPExperimentStage.java
index a7186fb..3cf3f87 100644
--- a/src/main/java/aitoa/examples/jssp/EJSSPExperimentStage.java
+++ b/src/main/java/aitoa/examples/jssp/EJSSPExperimentStage.java
@@ -638,6 +638,20 @@ public void configureBuilderForProblem(
() -> new MA<>(64, 64, 100), //
() -> new MAWithPruning<>(64, 64, 100), //
//
+ () -> new MA<>(256, 256, Integer.MAX_VALUE), //
+ () -> new MAWithPruning<>(256, 256, Integer.MAX_VALUE), //
+ () -> new MA<>(256, 256, 10), //
+ () -> new MAWithPruning<>(256, 256, 10), //
+ () -> new MA<>(256, 256, 100), //
+ () -> new MAWithPruning<>(64, 64, 100), //
+ //
+ () -> new MA<>(1024, 1024, Integer.MAX_VALUE), //
+ () -> new MAWithPruning<>(1024, 1024, Integer.MAX_VALUE), //
+ () -> new MA<>(1024, 1024, 10), //
+ () -> new MAWithPruning<>(1024, 1024, 10), //
+ () -> new MA<>(1024, 1024, 100), //
+ () -> new MAWithPruning<>(1024, 1024, 100), //
+ //
() -> new MA<>(4096, 4096, Integer.MAX_VALUE), //
() -> new MAWithPruning<>(4096, 4096, Integer.MAX_VALUE), //
() -> new MA<>(4096, 4096, 10), //
diff --git a/src/main/java/aitoa/examples/jssp/JSSPUnaryOperator1SwapU.java b/src/main/java/aitoa/examples/jssp/JSSPUnaryOperator1SwapU.java
index d7b39c0..549065e 100644
--- a/src/main/java/aitoa/examples/jssp/JSSPUnaryOperator1SwapU.java
+++ b/src/main/java/aitoa/examples/jssp/JSSPUnaryOperator1SwapU.java
@@ -28,7 +28,7 @@ public final class JSSPUnaryOperator1SwapU
implements IUnarySearchOperator {
// end relevant
/** the indexes */
- private final int[] m_indexes;
+ final int[] m_indexes;
/**
* create the representation
@@ -127,13 +127,13 @@ public final boolean enumerate(final Random random,
// start relevant
System.arraycopy(x, 0, dest, 0, dest.length); // copy x
- // We move along the index-pair array and shuffle the indices
- // on the way
+// We move along the index-pair array and shuffle the indices on
+// the way
for (int i = 0, start = -1; i < pairCount; i++) {
- // Get "a" and "b": the next, randomly chosen index pair.
- // What we do here is basically an iterative version of the
- // Fisher-Yates shuffle.
+// Get "a" and "b": the next, randomly chosen index pair.
+// What we do here is basically an iterative version of the
+// Fisher-Yates shuffle.
int swapWith = (i + random.nextInt(pairCount - i)) << 1;
final int a = indexes[swapWith];
indexes[swapWith] = indexes[++start];
@@ -146,8 +146,8 @@ public final boolean enumerate(final Random random,
final int job_j = dest[b];// the job at second index
if (job_i != job_j) {
- dest[b] = job_j; // then we swap the values
- dest[a] = job_i; // and will then call the visitor
+ dest[a] = job_j; // then we swap the values
+ dest[b] = job_i; // and will then call the visitor
if (visitor.test(dest)) {
return true; // visitor says: stop -> return true
} // visitor did not say stop, so we need to
diff --git a/src/test/java/aitoa/examples/jssp/TestJSSPUnaryOperator1SwapU.java b/src/test/java/aitoa/examples/jssp/TestJSSPUnaryOperator1SwapU.java
new file mode 100644
index 0000000..ba3cdf2
--- /dev/null
+++ b/src/test/java/aitoa/examples/jssp/TestJSSPUnaryOperator1SwapU.java
@@ -0,0 +1,184 @@
+package aitoa.examples.jssp;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import aitoa.structure.ISpace;
+import aitoa.structure.IUnarySearchOperator;
+import aitoa.structure.IUnarySearchOperatorTest;
+
+/** test the unary 1-swap search operator */
+public class TestJSSPUnaryOperator1SwapU
+ extends IUnarySearchOperatorTest {
+
+ /** the space we use */
+ private static final JSSPInstance PROBLEM =
+ new JSSPInstance("yn2"); //$NON-NLS-1$
+
+ /** the space we use */
+ private static final JSSPSearchSpace SPACE =
+ new JSSPSearchSpace(TestJSSPUnaryOperator1SwapU.PROBLEM);
+
+ /** the operator we use */
+ private static final JSSPUnaryOperator1SwapU OP =
+ new JSSPUnaryOperator1SwapU(
+ TestJSSPUnaryOperator1SwapU.PROBLEM);
+
+ /** {@inheritDoc} */
+ @Override
+ protected ISpace getSpace() {
+ return TestJSSPUnaryOperator1SwapU.SPACE;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected IUnarySearchOperator
+ getOperator(final ISpace space) {
+ return TestJSSPUnaryOperator1SwapU.OP;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean equals(final int[] a, final int[] b) {
+ return Arrays.equals(a, b);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected int[] createValid() {
+ return JSSPTestUtils
+ .createValidX(TestJSSPUnaryOperator1SwapU.PROBLEM);
+ }
+
+ /**
+ * check that all index pairs are unique
+ *
+ * @param op
+ * the operator
+ * @param test
+ * the test set
+ */
+ private static final void __checkUnique(
+ final JSSPUnaryOperator1SwapU op,
+ final HashSet test) {
+ test.clear();
+ for (int k = 0; k < op.m_indexes.length;) {
+ final long v = op.m_indexes[k++];
+ final long w = op.m_indexes[k++];
+ final long key =
+ (v < w) ? ((v << 32L) | w) : ((w << 32L) | v);
+ Assert.assertTrue(test.add(Long.valueOf(key)));
+ }
+ }
+
+ /** test the application to the canonical instance */
+ @SuppressWarnings("static-method")
+ @Test(timeout = 3600000)
+ public final void testCanonical() {
+ final Random random = ThreadLocalRandom.current();
+ new HashSet<>();
+ for (final JSSPInstance inst : JSSPTestUtils.INSTANCS) {
+ final JSSPUnaryOperator1SwapU op =
+ new JSSPUnaryOperator1SwapU(inst);
+ TestJSSPUnaryOperator1SwapU.__checkUnique(op,
+ new HashSet<>());
+ final int[] x = new int[inst.m * inst.n];
+ final int[] c = new int[inst.m * inst.n];
+ JSSPTestUtils.canonicalX(c, inst);
+ final int[] c2 = c.clone();
+ JSSPTestUtils.assertX(c2, inst);
+ for (int i = 1000; (--i) >= 0;) {
+ op.apply(c, x, random);
+ JSSPTestUtils.assertX(x, inst);
+ Assert.assertArrayEquals(c, c2);
+ }
+ }
+ }
+
+ /** test the application to random instances */
+ @SuppressWarnings("static-method")
+ @Test(timeout = 3600000)
+ public final void testRandom() {
+ final Random random = ThreadLocalRandom.current();
+ for (final JSSPInstance inst : JSSPTestUtils.INSTANCS) {
+ final int[] x = new int[inst.m * inst.n];
+ final int[] c = new int[inst.m * inst.n];
+ final JSSPUnaryOperator1SwapU op =
+ new JSSPUnaryOperator1SwapU(inst);
+ TestJSSPUnaryOperator1SwapU.__checkUnique(op,
+ new HashSet<>());
+
+ for (int i = 1000; (--i) >= 0;) {
+ JSSPTestUtils.randomX(c, inst);
+ JSSPTestUtils.assertX(c, inst);
+ op.apply(c, x, random);
+ JSSPTestUtils.assertX(x, inst);
+ }
+ }
+ }
+
+ /** test the number of unique outcomes */
+ @SuppressWarnings("static-method")
+ @Test(timeout = 3600000)
+ public void testNumberOfUniqueOutcomes() {
+ final Random random = ThreadLocalRandom.current();
+ final JSSPInstance inst = new JSSPInstance("demo"); //$NON-NLS-1$
+ final int[] in = new int[inst.n * inst.m];
+ final int[] out = new int[in.length];
+ final int[][] unique = new int[(inst.n * inst.m
+ * (inst.n - 1) * inst.m) >>> 1][out.length];
+
+ new JSSPNullaryOperator(inst).apply(in, random);
+ final JSSPUnaryOperator1SwapU op =
+ new JSSPUnaryOperator1SwapU(inst);
+ int count = 0;
+ outer: for (int i = (50 * unique.length * unique.length);
+ (--i) >= 0;) {
+ op.apply(in, out, random);
+ for (int j = count; (--j) >= 0;) {
+ if (Arrays.equals(unique[j], out)) {
+ continue outer;
+ }
+ }
+ System.arraycopy(out, 0, unique[count++], 0, out.length);
+ }
+
+ Assert.assertEquals(unique.length, count);
+ }
+
+ /**
+ * test that the
+ * {@link IUnarySearchOperator#enumerate(java.util.Random, Object, Object, java.util.function.Predicate)}
+ * method works correctly and respects the return values of the
+ * visitor
+ */
+ @SuppressWarnings({ "static-method", "unchecked" })
+ @Test(timeout = 3600000)
+ public void testEnumerate2() {
+ final JSSPSearchSpace space =
+ TestJSSPUnaryOperator1SwapU.SPACE;
+
+ final JSSPUnaryOperator1SwapU op =
+ TestJSSPUnaryOperator1SwapU.OP;
+ final Random random = ThreadLocalRandom.current();
+
+ final int[] src = this.createValid();
+ final int[] dest = space.create();
+
+ final int[] copy = space.create();
+ space.copy(src, copy);
+
+ for (int i = 10; (--i) >= 0;) {
+ Assert.assertFalse(
+ op.enumerate(random, src, dest, (x) -> false));
+ final HashSet set = new HashSet<>();
+ TestJSSPUnaryOperator1SwapU.__checkUnique(op, set);
+ Assert.assertTrue(this.equals(src, copy));
+ }
+ }
+}