Ant Colony Optimization updates (#1306)

* Ant Colony Optimization

* Updated code for Ant Colony
This commit is contained in:
maibin 2017-03-05 19:21:35 +01:00 committed by GitHub
parent 492b21caa0
commit f0c4486cb1
2 changed files with 47 additions and 52 deletions

View File

@ -1,7 +1,10 @@
package com.baeldung.algorithms.ga.ant_colony; package com.baeldung.algorithms.ga.ant_colony;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.stream.IntStream;
public class AntColonyOptimization { public class AntColonyOptimization {
@ -19,7 +22,7 @@ public class AntColonyOptimization {
public int numberOfAnts; public int numberOfAnts;
private double graph[][]; private double graph[][];
private double trails[][]; private double trails[][];
private Ant ants[]; private List<Ant> ants = new ArrayList<>();
private Random random = new Random(); private Random random = new Random();
private double probabilities[]; private double probabilities[];
@ -35,101 +38,92 @@ public class AntColonyOptimization {
trails = new double[numberOfCities][numberOfCities]; trails = new double[numberOfCities][numberOfCities];
probabilities = new double[numberOfCities]; probabilities = new double[numberOfCities];
ants = new Ant[numberOfAnts]; IntStream.range(0, numberOfAnts).forEach(i -> ants.add(new Ant(numberOfCities)));
for (int j = 0; j < numberOfAnts; j++) {
ants[j] = new Ant(numberOfCities);
}
} }
/** /**
* Generate initial solution * Generate initial solution
*
* @param n * @param n
* @return * @return
*/ */
public double[][] generateRandomMatrix(int n) { public double[][] generateRandomMatrix(int n) {
double[][] randomMatrix = new double[n][n]; double[][] randomMatrix = new double[n][n];
random.setSeed(System.currentTimeMillis()); random.setSeed(System.currentTimeMillis());
for (int i = 0; i < n; i++) { IntStream.range(0, n).forEach(i -> {
for (int j = 0; j < n; j++) { IntStream.range(0, n).forEach(j -> {
Integer r = random.nextInt(100) + 1; Integer r = random.nextInt(100) + 1;
randomMatrix[i][j] = Math.abs(r); randomMatrix[i][j] = Math.abs(r);
} });
} });
return randomMatrix; return randomMatrix;
} }
/** /**
* Perform ant optimization * Perform ant optimization
*
* @return * @return
*/ */
public int[] startAntOptimization() { public void startAntOptimization() {
int[] finalResult = null; IntStream.rangeClosed(1, 3).forEach(i -> {
for (int i = 1; i <= 3; i++) {
System.out.println("Attempt #" + i); System.out.println("Attempt #" + i);
finalResult = solve(); solve();
} });
return finalResult;
} }
/** /**
* Use this method to run the main logic * Use this method to run the main logic
*
* @return * @return
*/ */
private int[] solve() { public int[] solve() {
setupAnts(); setupAnts();
clearTrails(); clearTrails();
int iteration = 0; IntStream.range(0, maxIterations).forEach(i -> {
while (iteration < maxIterations) {
moveAnts(); moveAnts();
updateTrails(); updateTrails();
updateBest(); updateBest();
iteration++; });
}
System.out.println("Best tour length: " + (bestTourLength - numberOfCities)); System.out.println("Best tour length: " + (bestTourLength - numberOfCities));
System.out.println("Best tour order: " + Arrays.toString(bestTourOrder)); System.out.println("Best tour order: " + Arrays.toString(bestTourOrder));
return bestTourOrder.clone(); return bestTourOrder.clone();
} }
/** /**
* Prepare ants for the simulation * Prepare ants for the simulation
*/ */
private void setupAnts() { private void setupAnts() {
currentIndex = -1; IntStream.range(0, numberOfAnts).forEach(i -> {
for (int i = 0; i < numberOfAnts; i++) { ants.stream().forEach(ant -> {
ants[i].clear(); ant.clear();
ants[i].visitCity(currentIndex, random.nextInt(numberOfCities)); ant.visitCity(-1, random.nextInt(numberOfCities));
} });
currentIndex++; });
currentIndex = 0;
} }
/** /**
* At each iteration, move ants * At each iteration, move ants
*/ */
private void moveAnts() { private void moveAnts() {
while (currentIndex < numberOfCities - 1) { IntStream.range(currentIndex, numberOfCities - 1).forEach(i -> {
for (Ant a : ants) ants.stream().forEach(ant -> {
a.visitCity(currentIndex, selectNextCity(a)); ant.visitCity(currentIndex, selectNextCity(ant));
});
currentIndex++; currentIndex++;
} });
} }
/** /**
* Select next city for each ant * Select next city for each ant
*
* @param ant * @param ant
* @return * @return
*/ */
private int selectNextCity(Ant ant) { private int selectNextCity(Ant ant) {
int t = random.nextInt(numberOfCities - currentIndex);
if (random.nextDouble() < randomFactor) { if (random.nextDouble() < randomFactor) {
int t = random.nextInt(numberOfCities - currentIndex); IntStream.range(0, numberOfCities).filter(i -> i == t && !ant.visited(i)).findFirst();
int j = -1;
for (int i = 0; i < numberOfCities; i++) {
if (!ant.visited(i)) {
j++;
}
if (j == t) {
return i;
}
}
} }
calculateProbabilities(ant); calculateProbabilities(ant);
double r = random.nextDouble(); double r = random.nextDouble();
@ -146,9 +140,10 @@ public class AntColonyOptimization {
/** /**
* Calculate the next city picks probabilites * Calculate the next city picks probabilites
*
* @param ant * @param ant
*/ */
private void calculateProbabilities(Ant ant) { public void calculateProbabilities(Ant ant) {
int i = ant.trail[currentIndex]; int i = ant.trail[currentIndex];
double pheromone = 0.0; double pheromone = 0.0;
for (int l = 0; l < numberOfCities; l++) { for (int l = 0; l < numberOfCities; l++) {
@ -189,8 +184,8 @@ public class AntColonyOptimization {
*/ */
private void updateBest() { private void updateBest() {
if (bestTourOrder == null) { if (bestTourOrder == null) {
bestTourOrder = ants[0].trail; bestTourOrder = ants.get(0).trail;
bestTourLength = ants[0].trailLength(graph); bestTourLength = ants.get(0).trailLength(graph);
} }
for (Ant a : ants) { for (Ant a : ants) {
if (a.trailLength(graph) < bestTourLength) { if (a.trailLength(graph) < bestTourLength) {
@ -204,9 +199,9 @@ public class AntColonyOptimization {
* Clear trails after simulation * Clear trails after simulation
*/ */
private void clearTrails() { private void clearTrails() {
for (int i = 0; i < numberOfCities; i++) IntStream.range(0, numberOfCities).forEach(i -> {
for (int j = 0; j < numberOfCities; j++) IntStream.range(0, numberOfCities).forEach(j -> trails[i][j] = c);
trails[i][j] = c; });
} }
} }

View File

@ -16,7 +16,7 @@ public class AntColonyOptimizationTest {
@Test @Test
public void testStartAntOptimization() { public void testStartAntOptimization() {
AntColonyOptimization antTSP = new AntColonyOptimization(5); AntColonyOptimization antTSP = new AntColonyOptimization(5);
Assert.assertNotNull(antTSP.startAntOptimization()); Assert.assertNotNull(antTSP.solve());
} }
} }