diff --git a/algorithms/pom.xml b/algorithms/pom.xml index f72457650a..46a2b9d897 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -9,6 +9,7 @@ 4.12 3.6.0 1.5.0 + 1.16.12 @@ -18,6 +19,12 @@ ${junit.version} test + + org.projectlombok + lombok + ${lombok.version} + provided + diff --git a/core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java similarity index 84% rename from core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java rename to algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java index 22c5776293..6ab7dbb4e5 100644 --- a/core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java @@ -9,13 +9,14 @@ import com.baeldung.algorithms.slope_one.SlopeOne; public class RunAlgorithm { - public static void main(String[] args) { + public static void main(String[] args) throws InstantiationException, IllegalAccessException { Scanner in = new Scanner(System.in); System.out.println("Run algorithm:"); System.out.println("1 - Simulated Annealing"); System.out.println("2 - Slope One"); System.out.println("3 - Simple Genetic Algorithm"); System.out.println("4 - Ant Colony"); + System.out.println("5 - Dijkstra"); int decision = in.nextInt(); switch (decision) { case 1: @@ -33,6 +34,9 @@ public class RunAlgorithm { AntColonyOptimization antColony = new AntColonyOptimization(21); antColony.startAntOptimization(); break; + case 5: + System.out.println("Please run the DijkstraAlgorithmTest."); + break; default: System.out.println("Unknown option"); break; diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/annealing/City.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/annealing/City.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/annealing/City.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/annealing/City.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/annealing/SimulatedAnnealing.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/annealing/Travel.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/ant_colony/Ant.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java new file mode 100644 index 0000000000..62e124d3f3 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java @@ -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 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); + }); + } + +} diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Population.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/binary/Population.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/binary/Population.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/binary/Population.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Dijkstra.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java similarity index 95% rename from algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Dijkstra.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java index 1d41f46adb..046f13983d 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Dijkstra.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Dijkstra.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.dijkstra; +package com.baeldung.algorithms.ga.dijkstra; import java.util.HashSet; import java.util.LinkedList; diff --git a/algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Graph.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java similarity index 83% rename from algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Graph.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java index f24d6ae60e..00db4b01e4 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Graph.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Graph.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.dijkstra; +package com.baeldung.algorithms.ga.dijkstra; import java.util.HashSet; import java.util.Set; diff --git a/algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Node.java b/algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java similarity index 92% rename from algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Node.java rename to algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java index b00127a259..256f12e204 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/dijkstra/Node.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/ga/dijkstra/Node.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.dijkstra; +package com.baeldung.algorithms.ga.dijkstra; import java.util.HashMap; import java.util.LinkedList; diff --git a/core-java/src/main/java/com/baeldung/algorithms/slope_one/InputData.java b/algorithms/src/main/java/com/baeldung/algorithms/slope_one/InputData.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/slope_one/InputData.java rename to algorithms/src/main/java/com/baeldung/algorithms/slope_one/InputData.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/slope_one/Item.java b/algorithms/src/main/java/com/baeldung/algorithms/slope_one/Item.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/slope_one/Item.java rename to algorithms/src/main/java/com/baeldung/algorithms/slope_one/Item.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java b/algorithms/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java rename to algorithms/src/main/java/com/baeldung/algorithms/slope_one/SlopeOne.java diff --git a/core-java/src/main/java/com/baeldung/algorithms/slope_one/User.java b/algorithms/src/main/java/com/baeldung/algorithms/slope_one/User.java similarity index 100% rename from core-java/src/main/java/com/baeldung/algorithms/slope_one/User.java rename to algorithms/src/main/java/com/baeldung/algorithms/slope_one/User.java diff --git a/core-java/src/test/java/com/baeldung/algorithms/AntColonyOptimizationTest.java b/algorithms/src/test/java/algorithms/AntColonyOptimizationTest.java similarity index 93% rename from core-java/src/test/java/com/baeldung/algorithms/AntColonyOptimizationTest.java rename to algorithms/src/test/java/algorithms/AntColonyOptimizationTest.java index 40d2464ab6..a11f5db698 100644 --- a/core-java/src/test/java/com/baeldung/algorithms/AntColonyOptimizationTest.java +++ b/algorithms/src/test/java/algorithms/AntColonyOptimizationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms; +package algorithms; import org.junit.Assert; import org.junit.Test; diff --git a/core-java/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmUnitTest.java b/algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmUnitTest.java similarity index 91% rename from core-java/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmUnitTest.java rename to algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmUnitTest.java index 2e92177c8c..2ba516d310 100644 --- a/core-java/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmUnitTest.java +++ b/algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms; +package algorithms; import org.junit.Assert; import org.junit.Test; diff --git a/algorithms/src/test/java/algorithms/DijkstraAlgorithmTest.java b/algorithms/src/test/java/algorithms/DijkstraAlgorithmTest.java index 07606bde4b..4d8cebed25 100644 --- a/algorithms/src/test/java/algorithms/DijkstraAlgorithmTest.java +++ b/algorithms/src/test/java/algorithms/DijkstraAlgorithmTest.java @@ -1,10 +1,11 @@ package algorithms; -import com.baeldung.algorithms.dijkstra.Dijkstra; -import com.baeldung.algorithms.dijkstra.Graph; -import com.baeldung.algorithms.dijkstra.Node; import org.junit.Test; +import com.baeldung.algorithms.ga.dijkstra.Dijkstra; +import com.baeldung.algorithms.ga.dijkstra.Graph; +import com.baeldung.algorithms.ga.dijkstra.Node; + import java.util.Arrays; import java.util.List; diff --git a/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java b/algorithms/src/test/java/algorithms/SimulatedAnnealingTest.java similarity index 90% rename from core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java rename to algorithms/src/test/java/algorithms/SimulatedAnnealingTest.java index 6822bae990..f716b9ffb4 100644 --- a/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java +++ b/algorithms/src/test/java/algorithms/SimulatedAnnealingTest.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms; +package algorithms; import org.junit.Assert; import org.junit.Test; diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java b/core-java/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java deleted file mode 100644 index 09c2c109f6..0000000000 --- a/core-java/src/main/java/com/baeldung/algorithms/ga/ant_colony/AntColonyOptimization.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.baeldung.algorithms.ga.ant_colony; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -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 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) { - IntStream.range(0, numberOfCities).filter(i -> i == t && !ant.visited(i)).findFirst(); //TODO unused - } - 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); - }); - } - -} diff --git a/core-java/src/test/java/com/baeldung/PrimitiveConversionsJUnitTest.java b/core-java/src/test/java/com/baeldung/PrimitiveConversionsJUnitTest.java index 4137b5af00..10ceaf85a4 100644 --- a/core-java/src/test/java/com/baeldung/PrimitiveConversionsJUnitTest.java +++ b/core-java/src/test/java/com/baeldung/PrimitiveConversionsJUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.primitiveconversions; +package com.baeldung; import org.junit.Test; import static org.junit.Assert.*;