diff --git a/pom.xml b/pom.xml
index 0765296..0cba845 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,6 +59,19 @@
junit-jupiter
test
+
+
+ org.eclipse.collections
+ eclipse-collections-api
+ 13.0.0
+ test
+
+
+ org.eclipse.collections
+ eclipse-collections
+ 13.0.0
+ test
+
diff --git a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
index 9840741..568cb11 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
@@ -6,13 +6,15 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Random;
import java.util.random.RandomGenerator;
import java.util.stream.IntStream;
+import org.eclipse.collections.api.map.primitive.IntIntMap;
+import org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap;
+import org.eclipse.collections.impl.set.mutable.primitive.IntHashSet;
+
import com.github.bibenga.alns.ALNS;
import com.github.bibenga.alns.State;
import com.github.bibenga.alns.accept.HillClimbing;
@@ -29,7 +31,7 @@ public static void main(String[] args) throws Exception {
Random rng = new Random(42);
- TspState initSol = new TspState(nodes, new HashMap<>(), dists);
+ TspState initSol = new TspState(nodes, new IntIntHashMap(), dists);
initSol = (TspState) greedyRepair(initSol, rng);
System.out.println("optimal solution: 564");
@@ -248,7 +250,7 @@ private static State randomRemoval(State state, RandomGenerator rng) {
int removed = 0;
while (removed < toRemove) {
int node = destroyed.nodes[rng.nextInt(destroyed.nodes.length)];
- if (destroyed.edges.remove(node) != null) {
+ if (destroyed.edges.removeKeyIfAbsent(node, -1) != -1) {
removed++;
}
}
@@ -285,9 +287,11 @@ private static State worstRemoval(State state, RandomGenerator rng) {
private static State greedyRepair(State state, RandomGenerator rng) {
TspState cur = (TspState) state;
- boolean[] visited = new boolean[cur.nodes.length];
- for (int v : cur.edges.values())
- visited[v] = true;
+ var visited = new IntHashSet();
+ for (var it = cur.edges.values().intIterator(); it.hasNext();) {
+ var v = it.next();
+ visited.add(v);
+ }
int[] idx = IntStream.range(0, cur.nodes.length).toArray();
shuffleArray(idx, rng);
@@ -306,21 +310,21 @@ private static State greedyRepair(State state, RandomGenerator rng) {
if (node == -1)
throw new RuntimeException("node not found");
- final int finalNode = node;
+ final int fNode = node;
List unvisited = new ArrayList<>();
for (int other : cur.nodes) {
- if (other != finalNode && !visited[other] && !wouldFormSubcycle(finalNode, other, cur))
+ if (other != fNode && !visited.contains(other) && !wouldFormSubcycle(fNode, other, cur))
unvisited.add(other);
}
if (unvisited.isEmpty())
throw new RuntimeException("unvisited is empty");
int nearest = unvisited.stream()
- .min(Comparator.comparingDouble(a -> cur.dists[finalNode][a]))
+ .min(Comparator.comparingDouble(a -> cur.dists[fNode][a]))
.orElseThrow();
cur.edges.put(node, nearest);
- visited[nearest] = true;
+ visited.add(nearest);
}
return cur;
}
@@ -336,8 +340,8 @@ static void shuffleArray(int[] arr, RandomGenerator rnd) {
private static boolean wouldFormSubcycle(int fromNode, int toNode, TspState state) {
for (int step = 1; step < state.nodes.length; step++) {
- Integer next = state.edges.get(toNode);
- if (next == null)
+ int next = state.edges.getIfAbsent(toNode, -1);
+ if (next == -1)
return false;
toNode = next;
if (fromNode == toNode && step != state.nodes.length - 1)
@@ -346,7 +350,7 @@ private static boolean wouldFormSubcycle(int fromNode, int toNode, TspState stat
return false;
}
- static void writeDotFile(String filename, double[][] coords, Map edges) throws IOException {
+ static void writeDotFile(String filename, double[][] coords, IntIntMap edges) throws IOException {
final double k = 3;
double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
@@ -367,8 +371,9 @@ static void writeDotFile(String filename, double[][] coords, Map e : edges.entrySet())
- w.printf(" %d -> %d [arrowsize=4, penwidth=3];%n", e.getKey(), e.getValue());
+ edges.forEachKeyValue((key, value) -> {
+ w.printf(" %d -> %d [arrowsize=4, penwidth=3];%n", key, value);
+ });
w.println("}");
}
}
diff --git a/src/test/java/com/github/bibenga/alns/tsp/TspState.java b/src/test/java/com/github/bibenga/alns/tsp/TspState.java
index a1f7e4b..b7b5b55 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/TspState.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/TspState.java
@@ -1,17 +1,17 @@
package com.github.bibenga.alns.tsp;
-import java.util.HashMap;
-import java.util.Map;
+import org.eclipse.collections.api.map.primitive.MutableIntIntMap;
+import org.eclipse.collections.impl.map.mutable.primitive.IntIntHashMap;
import com.github.bibenga.alns.State;
class TspState implements State {
final int[] nodes;
- final Map edges;
+ final MutableIntIntMap edges;
final double[][] dists;
private double objective = Double.NaN;
- TspState(int[] nodes, Map edges, double[][] dists) {
+ TspState(int[] nodes, MutableIntIntMap edges, double[][] dists) {
this.nodes = nodes;
this.edges = edges;
this.dists = dists;
@@ -19,7 +19,7 @@ class TspState implements State {
@Override
public TspState clone() {
- return new TspState(nodes, new HashMap<>(edges), dists);
+ return new TspState(nodes, new IntIntHashMap(edges), dists);
}
@Override