From fb71a3b21c8c70e8470ef16442384ca78c84c696 Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Tue, 10 Mar 2026 11:43:52 +0000
Subject: [PATCH 1/7] add eclipse-collections
---
pom.xml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/pom.xml b/pom.xml
index 9bef27f..d19f134 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,6 +36,19 @@
junit-jupiter
test
+
+
+ org.eclipse.collections
+ eclipse-collections-api
+ 13.0.0
+ test
+
+
+ org.eclipse.collections
+ eclipse-collections
+ 13.0.0
+ test
+
From 416aefbd2b89e71cf6c722896ce7526a4157702b Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Wed, 11 Mar 2026 10:28:22 +0000
Subject: [PATCH 2/7] simplify
---
src/test/java/com/github/bibenga/alns/tsp/Tsp.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
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 67372ae..65e1895 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
@@ -7,9 +7,11 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.Set;
import java.util.random.RandomGenerator;
import java.util.stream.IntStream;
@@ -281,9 +283,9 @@ public static State worstRemoval(State state, RandomGenerator rng) {
static State greedyRepair(State state, RandomGenerator rng) {
TspState cur = (TspState) state;
- boolean[] visited = new boolean[cur.nodes.length];
+ Set visited = new HashSet<>();
for (int v : cur.edges.values())
- visited[v] = true;
+ visited.add(v);
int[] idx = IntStream.range(0, cur.nodes.length).toArray();
shuffleArray(idx, rng);
@@ -305,7 +307,7 @@ static State greedyRepair(State state, RandomGenerator rng) {
final int finalNode = node;
List unvisited = new ArrayList<>();
for (int other : cur.nodes) {
- if (other != finalNode && !visited[other] && !wouldFormSubcycle(finalNode, other, cur))
+ if (other != finalNode && !visited.contains(other) && !wouldFormSubcycle(finalNode, other, cur))
unvisited.add(other);
}
if (unvisited.isEmpty())
@@ -316,7 +318,7 @@ static State greedyRepair(State state, RandomGenerator rng) {
.orElseThrow();
cur.edges.put(node, nearest);
- visited[nearest] = true;
+ visited.add(nearest);
}
return cur;
}
From 95885f002a4200ab893badce6486f76daba41e05 Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Wed, 11 Mar 2026 10:29:42 +0000
Subject: [PATCH 3/7] cleanup
---
src/test/java/com/github/bibenga/alns/tsp/Tsp.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
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 65e1895..b08c14c 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
@@ -304,17 +304,17 @@ 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.contains(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);
From 31010fda93343c4e0c6361fe2469833f2cab217b Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Wed, 11 Mar 2026 10:32:47 +0000
Subject: [PATCH 4/7] simplify
---
src/test/java/com/github/bibenga/alns/tsp/Tsp.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
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 b08c14c..be5c86c 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
@@ -283,9 +283,7 @@ public static State worstRemoval(State state, RandomGenerator rng) {
static State greedyRepair(State state, RandomGenerator rng) {
TspState cur = (TspState) state;
- Set visited = new HashSet<>();
- for (int v : cur.edges.values())
- visited.add(v);
+ Set visited = new HashSet<>(cur.edges.values());
int[] idx = IntStream.range(0, cur.nodes.length).toArray();
shuffleArray(idx, rng);
From 9cbd1ffdb127861f92a82f402628f8987f016391 Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Wed, 11 Mar 2026 10:37:44 +0000
Subject: [PATCH 5/7] use native collections
---
.../java/com/github/bibenga/alns/tsp/Tsp.java | 20 +++++++++++--------
.../com/github/bibenga/alns/tsp/TspState.java | 9 ++++++---
2 files changed, 18 insertions(+), 11 deletions(-)
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 be5c86c..0987b92 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
@@ -6,15 +6,15 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
-import java.util.Set;
import java.util.random.RandomGenerator;
import java.util.stream.IntStream;
+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.Operator;
import com.github.bibenga.alns.State;
@@ -32,7 +32,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");
@@ -246,7 +246,7 @@ public 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++;
}
}
@@ -283,7 +283,11 @@ public static State worstRemoval(State state, RandomGenerator rng) {
static State greedyRepair(State state, RandomGenerator rng) {
TspState cur = (TspState) state;
- Set visited = new HashSet<>(cur.edges.values());
+ 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);
@@ -332,8 +336,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)
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..0a91831 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/TspState.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/TspState.java
@@ -3,15 +3,18 @@
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 +22,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
From 09aa1ac71121e543fdfe064c8d2ba3934832a79d Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Wed, 11 Mar 2026 10:37:53 +0000
Subject: [PATCH 6/7] cleanup
---
src/test/java/com/github/bibenga/alns/tsp/TspState.java | 3 ---
1 file changed, 3 deletions(-)
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 0a91831..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,8 +1,5 @@
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;
From e07f3e7d87fb81bb8e4e31998b26849eb8c25c61 Mon Sep 17 00:00:00 2001
From: bibenga <{ID}+{username}@users.noreply.github.com>
Date: Fri, 13 Mar 2026 20:56:49 +0000
Subject: [PATCH 7/7] fix
---
src/test/java/com/github/bibenga/alns/tsp/Tsp.java | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
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 c80ae7d..568cb11 100644
--- a/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
+++ b/src/test/java/com/github/bibenga/alns/tsp/Tsp.java
@@ -7,11 +7,11 @@
import java.util.Arrays;
import java.util.Comparator;
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;
@@ -350,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;
@@ -371,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("}");
}
}