Ant Colony Optimization updates (#1306)
* Ant Colony Optimization * Updated code for Ant Colony
This commit is contained in:
		
							parent
							
								
									492b21caa0
								
							
						
					
					
						commit
						f0c4486cb1
					
				| @ -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,56 +38,52 @@ 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(); | ||||||
| @ -94,42 +93,37 @@ public class AntColonyOptimization { | |||||||
| 	 * 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; | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -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()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user