diff --git a/core-java/pom.xml b/core-java/pom.xml index 0c14da2245..f5a800d508 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -85,6 +85,12 @@ log4j-over-slf4j ${org.slf4j.version} + + org.projectlombok + lombok + 1.16.12 + provided + diff --git a/core-java/src/main/java/com/baeldung/algorithms/City.java b/core-java/src/main/java/com/baeldung/algorithms/City.java new file mode 100644 index 0000000000..1a96dc759d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/algorithms/City.java @@ -0,0 +1,22 @@ +package com.baeldung.algorithms; + +import lombok.Data; + +@Data +public class City { + + private int x; + private int y; + + public City() { + this.x = (int) (Math.random() * 500); + this.y = (int) (Math.random() * 500); + } + + public double distanceToCity(City city) { + int x = Math.abs(getX() - city.getX()); + int y = Math.abs(getY() - city.getY()); + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java b/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java new file mode 100644 index 0000000000..b62e861399 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/algorithms/SimulatedAnnealing.java @@ -0,0 +1,41 @@ +package com.baeldung.algorithms; + +public class SimulatedAnnealing { + + private static Travel travel = new Travel(10); + + public static double simulateAnnealing(double startingTemperature, int numberOfIterations, double coolingRate) { + System.out.println("Starting SA with temperature: " + startingTemperature + ", # of iterations: " + + numberOfIterations + " and colling rate: " + coolingRate); + double t = startingTemperature; + travel.generateInitialTravel(); + double bestDistance = travel.getDistance(); + System.out.println("Initial distance of travel: " + bestDistance); + Travel bestSolution = travel; + Travel currentSolution = bestSolution; + + for (int i = 0; i < numberOfIterations; i++) { + if (t > 0.1) { + currentSolution.swapCities(); + double currentDistance = currentSolution.getDistance(); + if (currentDistance == 0) + continue; + if (currentDistance < bestDistance) { + bestDistance = currentDistance; + } else if (Math.exp((currentDistance - bestDistance) / t) < Math.random()) { + currentSolution.revertSwap(); + } + t *= coolingRate; + } + if (i % 100 == 0) { + System.out.println("Iteration #" + i); + } + } + return bestDistance; + } + + public static void main(String[] args) { + System.out.println("Optimized distance for travel: " + simulateAnnealing(10, 10000, 0.9)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/algorithms/Travel.java b/core-java/src/main/java/com/baeldung/algorithms/Travel.java new file mode 100644 index 0000000000..9921b2516e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/algorithms/Travel.java @@ -0,0 +1,60 @@ +package com.baeldung.algorithms; + +import java.util.ArrayList; +import java.util.Collections; + +import lombok.Data; + +@Data +public class Travel { + + private ArrayList travel = new ArrayList<>(); + private ArrayList previousTravel = new ArrayList<>(); + + public Travel(int numberOfCities) { + for (int i = 0; i < numberOfCities; i++) { + travel.add(new City()); + } + } + + public void generateInitialTravel() { + if (travel.isEmpty()) + new Travel(10); + Collections.shuffle(travel); + } + + public void swapCities() { + int a = generateRandomIndex(); + int b = generateRandomIndex(); + previousTravel = travel; + travel.set(a, travel.get(b)); + } + + public void revertSwap() { + travel = previousTravel; + } + + private int generateRandomIndex() { + return (int) (Math.random() * travel.size()); + } + + public City getCity(int index) { + return travel.get(index); + } + + public int getDistance() { + int distance = 0; + for (int index = 0; index < travel.size(); index++) { + City starting = getCity(index); + City destination; + if (index + 1 < travel.size()) { + destination = getCity(index + 1); + } else { + destination = getCity(0); + } + distance += starting.distanceToCity(destination); + } + return distance; + } + +}