forked from eugenp/tutorials
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Ant Colony Optimization * Updated code for Ant Colony
- Loading branch information
1 parent
1871023
commit 3abb98e
Showing
23 changed files
with
226 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
203 changes: 203 additions & 0 deletions
203
algorithms/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
package com.baeldung.algorithms.ga.ant_colony; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.OptionalInt; | ||
import java.util.Random; | ||
import java.util.stream.IntStream; | ||
|
||
public class AntColonyOptimization { | ||
|
||
private double c = 1.0; | ||
private double alpha = 1; | ||
private double beta = 5; | ||
private double evaporation = 0.5; | ||
private double Q = 500; | ||
private double antFactor = 0.8; | ||
private double randomFactor = 0.01; | ||
|
||
private int maxIterations = 1000; | ||
|
||
private int numberOfCities; | ||
private int numberOfAnts; | ||
private double graph[][]; | ||
private double trails[][]; | ||
private List<Ant> ants = new ArrayList<>(); | ||
private Random random = new Random(); | ||
private double probabilities[]; | ||
|
||
private int currentIndex; | ||
|
||
private int[] bestTourOrder; | ||
private double bestTourLength; | ||
|
||
public AntColonyOptimization(int noOfCities) { | ||
graph = generateRandomMatrix(noOfCities); | ||
numberOfCities = graph.length; | ||
numberOfAnts = (int) (numberOfCities * antFactor); | ||
|
||
trails = new double[numberOfCities][numberOfCities]; | ||
probabilities = new double[numberOfCities]; | ||
IntStream.range(0, numberOfAnts) | ||
.forEach(i -> ants.add(new Ant(numberOfCities))); | ||
} | ||
|
||
/** | ||
* Generate initial solution | ||
*/ | ||
public double[][] generateRandomMatrix(int n) { | ||
double[][] randomMatrix = new double[n][n]; | ||
IntStream.range(0, n) | ||
.forEach(i -> IntStream.range(0, n) | ||
.forEach(j -> randomMatrix[i][j] = Math.abs(random.nextInt(100) + 1))); | ||
return randomMatrix; | ||
} | ||
|
||
/** | ||
* Perform ant optimization | ||
*/ | ||
public void startAntOptimization() { | ||
IntStream.rangeClosed(1, 3) | ||
.forEach(i -> { | ||
System.out.println("Attempt #" + i); | ||
solve(); | ||
}); | ||
} | ||
|
||
/** | ||
* Use this method to run the main logic | ||
*/ | ||
public int[] solve() { | ||
setupAnts(); | ||
clearTrails(); | ||
IntStream.range(0, maxIterations) | ||
.forEach(i -> { | ||
moveAnts(); | ||
updateTrails(); | ||
updateBest(); | ||
}); | ||
System.out.println("Best tour length: " + (bestTourLength - numberOfCities)); | ||
System.out.println("Best tour order: " + Arrays.toString(bestTourOrder)); | ||
return bestTourOrder.clone(); | ||
} | ||
|
||
/** | ||
* Prepare ants for the simulation | ||
*/ | ||
private void setupAnts() { | ||
IntStream.range(0, numberOfAnts) | ||
.forEach(i -> { | ||
ants.forEach(ant -> { | ||
ant.clear(); | ||
ant.visitCity(-1, random.nextInt(numberOfCities)); | ||
}); | ||
}); | ||
currentIndex = 0; | ||
} | ||
|
||
/** | ||
* At each iteration, move ants | ||
*/ | ||
private void moveAnts() { | ||
IntStream.range(currentIndex, numberOfCities - 1) | ||
.forEach(i -> { | ||
ants.forEach(ant -> ant.visitCity(currentIndex, selectNextCity(ant))); | ||
currentIndex++; | ||
}); | ||
} | ||
|
||
/** | ||
* Select next city for each ant | ||
*/ | ||
private int selectNextCity(Ant ant) { | ||
int t = random.nextInt(numberOfCities - currentIndex); | ||
if (random.nextDouble() < randomFactor) { | ||
OptionalInt cityIndex = IntStream.range(0, numberOfCities) | ||
.filter(i -> i == t && !ant.visited(i)) | ||
.findFirst(); | ||
if (cityIndex.isPresent()) { | ||
return cityIndex.getAsInt(); | ||
} | ||
} | ||
calculateProbabilities(ant); | ||
double r = random.nextDouble(); | ||
double total = 0; | ||
for (int i = 0; i < numberOfCities; i++) { | ||
total += probabilities[i]; | ||
if (total >= r) { | ||
return i; | ||
} | ||
} | ||
|
||
throw new RuntimeException("There are no other cities"); | ||
} | ||
|
||
/** | ||
* Calculate the next city picks probabilites | ||
*/ | ||
public void calculateProbabilities(Ant ant) { | ||
int i = ant.trail[currentIndex]; | ||
double pheromone = 0.0; | ||
for (int l = 0; l < numberOfCities; l++) { | ||
if (!ant.visited(l)) { | ||
pheromone += Math.pow(trails[i][l], alpha) * Math.pow(1.0 / graph[i][l], beta); | ||
} | ||
} | ||
for (int j = 0; j < numberOfCities; j++) { | ||
if (ant.visited(j)) { | ||
probabilities[j] = 0.0; | ||
} else { | ||
double numerator = Math.pow(trails[i][j], alpha) * Math.pow(1.0 / graph[i][j], beta); | ||
probabilities[j] = numerator / pheromone; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Update trails that ants used | ||
*/ | ||
private void updateTrails() { | ||
for (int i = 0; i < numberOfCities; i++) { | ||
for (int j = 0; j < numberOfCities; j++) { | ||
trails[i][j] *= evaporation; | ||
} | ||
} | ||
for (Ant a : ants) { | ||
double contribution = Q / a.trailLength(graph); | ||
for (int i = 0; i < numberOfCities - 1; i++) { | ||
trails[a.trail[i]][a.trail[i + 1]] += contribution; | ||
} | ||
trails[a.trail[numberOfCities - 1]][a.trail[0]] += contribution; | ||
} | ||
} | ||
|
||
/** | ||
* Update the best solution | ||
*/ | ||
private void updateBest() { | ||
if (bestTourOrder == null) { | ||
bestTourOrder = ants.get(0).trail; | ||
bestTourLength = ants.get(0) | ||
.trailLength(graph); | ||
} | ||
for (Ant a : ants) { | ||
if (a.trailLength(graph) < bestTourLength) { | ||
bestTourLength = a.trailLength(graph); | ||
bestTourOrder = a.trail.clone(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Clear trails after simulation | ||
*/ | ||
private void clearTrails() { | ||
IntStream.range(0, numberOfCities) | ||
.forEach(i -> { | ||
IntStream.range(0, numberOfCities) | ||
.forEach(j -> trails[i][j] = c); | ||
}); | ||
} | ||
|
||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...aeldung/algorithms/dijkstra/Dijkstra.java → ...dung/algorithms/ga/dijkstra/Dijkstra.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...m/baeldung/algorithms/dijkstra/Graph.java → ...aeldung/algorithms/ga/dijkstra/Graph.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...om/baeldung/algorithms/dijkstra/Node.java → ...baeldung/algorithms/ga/dijkstra/Node.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...algorithms/AntColonyOptimizationTest.java → ...algorithms/AntColonyOptimizationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package com.baeldung.algorithms; | ||
package algorithms; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
2 changes: 1 addition & 1 deletion
2
...ithms/BinaryGeneticAlgorithmUnitTest.java → ...ithms/BinaryGeneticAlgorithmUnitTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package com.baeldung.algorithms; | ||
package algorithms; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
7 changes: 4 additions & 3 deletions
7
algorithms/src/test/java/algorithms/DijkstraAlgorithmTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ng/algorithms/SimulatedAnnealingTest.java → ...va/algorithms/SimulatedAnnealingTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package com.baeldung.algorithms; | ||
package algorithms; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
Oops, something went wrong.