[BAEL-9551] - Clean up code
This commit is contained in:
@@ -5,7 +5,6 @@ import java.util.Scanner;
|
||||
import com.baeldung.algorithms.ga.annealing.SimulatedAnnealing;
|
||||
import com.baeldung.algorithms.ga.ant_colony.AntColonyOptimization;
|
||||
import com.baeldung.algorithms.ga.binary.SimpleGeneticAlgorithm;
|
||||
import com.baeldung.algorithms.slope_one.SlopeOne;
|
||||
|
||||
public class RunAlgorithm {
|
||||
|
||||
@@ -13,11 +12,8 @@ public class RunAlgorithm {
|
||||
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");
|
||||
System.out.println("6 - All pairs in an array that add up to a given sum");
|
||||
System.out.println("2 - Simple Genetic Algorithm");
|
||||
System.out.println("3 - Ant Colony");
|
||||
int decision = in.nextInt();
|
||||
switch (decision) {
|
||||
case 1:
|
||||
@@ -25,19 +21,13 @@ public class RunAlgorithm {
|
||||
"Optimized distance for travel: " + SimulatedAnnealing.simulateAnnealing(10, 10000, 0.9995));
|
||||
break;
|
||||
case 2:
|
||||
SlopeOne.slopeOne(3);
|
||||
break;
|
||||
case 3:
|
||||
SimpleGeneticAlgorithm ga = new SimpleGeneticAlgorithm();
|
||||
ga.runAlgorithm(50, "1011000100000100010000100000100111001000000100000100000000001111");
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
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;
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.baeldung.algorithms.ga.dijkstra;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class Dijkstra {
|
||||
|
||||
public static Graph calculateShortestPathFromSource(Graph graph, Node source) {
|
||||
|
||||
source.setDistance(0);
|
||||
|
||||
Set<Node> settledNodes = new HashSet<>();
|
||||
Set<Node> unsettledNodes = new HashSet<>();
|
||||
unsettledNodes.add(source);
|
||||
|
||||
while (unsettledNodes.size() != 0) {
|
||||
Node currentNode = getLowestDistanceNode(unsettledNodes);
|
||||
unsettledNodes.remove(currentNode);
|
||||
for (Entry<Node, Integer> adjacencyPair : currentNode.getAdjacentNodes().entrySet()) {
|
||||
Node adjacentNode = adjacencyPair.getKey();
|
||||
Integer edgeWeigh = adjacencyPair.getValue();
|
||||
|
||||
if (!settledNodes.contains(adjacentNode)) {
|
||||
CalculateMinimumDistance(adjacentNode, edgeWeigh, currentNode);
|
||||
unsettledNodes.add(adjacentNode);
|
||||
}
|
||||
}
|
||||
settledNodes.add(currentNode);
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
private static void CalculateMinimumDistance(Node evaluationNode, Integer edgeWeigh, Node sourceNode) {
|
||||
Integer sourceDistance = sourceNode.getDistance();
|
||||
if (sourceDistance + edgeWeigh < evaluationNode.getDistance()) {
|
||||
evaluationNode.setDistance(sourceDistance + edgeWeigh);
|
||||
LinkedList<Node> shortestPath = new LinkedList<>(sourceNode.getShortestPath());
|
||||
shortestPath.add(sourceNode);
|
||||
evaluationNode.setShortestPath(shortestPath);
|
||||
}
|
||||
}
|
||||
|
||||
private static Node getLowestDistanceNode(Set<Node> unsettledNodes) {
|
||||
Node lowestDistanceNode = null;
|
||||
int lowestDistance = Integer.MAX_VALUE;
|
||||
for (Node node : unsettledNodes) {
|
||||
int nodeDistance = node.getDistance();
|
||||
if (nodeDistance < lowestDistance) {
|
||||
lowestDistance = nodeDistance;
|
||||
lowestDistanceNode = node;
|
||||
}
|
||||
}
|
||||
return lowestDistanceNode;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.baeldung.algorithms.ga.dijkstra;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Graph {
|
||||
|
||||
private Set<Node> nodes = new HashSet<>();
|
||||
|
||||
public void addNode(Node nodeA) {
|
||||
nodes.add(nodeA);
|
||||
}
|
||||
|
||||
public Set<Node> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public void setNodes(Set<Node> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package com.baeldung.algorithms.ga.dijkstra;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Node {
|
||||
|
||||
private String name;
|
||||
|
||||
private LinkedList<Node> shortestPath = new LinkedList<>();
|
||||
|
||||
private Integer distance = Integer.MAX_VALUE;
|
||||
|
||||
private Map<Node, Integer> adjacentNodes = new HashMap<>();
|
||||
|
||||
public Node(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void addDestination(Node destination, int distance) {
|
||||
adjacentNodes.put(destination, distance);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<Node, Integer> getAdjacentNodes() {
|
||||
return adjacentNodes;
|
||||
}
|
||||
|
||||
public void setAdjacentNodes(Map<Node, Integer> adjacentNodes) {
|
||||
this.adjacentNodes = adjacentNodes;
|
||||
}
|
||||
|
||||
public Integer getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(Integer distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public List<Node> getShortestPath() {
|
||||
return shortestPath;
|
||||
}
|
||||
|
||||
public void setShortestPath(LinkedList<Node> shortestPath) {
|
||||
this.shortestPath = shortestPath;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.baeldung.algorithms.slope_one;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class InputData {
|
||||
|
||||
protected static List<Item> items = Arrays.asList(new Item("Candy"), new Item("Drink"), new Item("Soda"), new Item("Popcorn"), new Item("Snacks"));
|
||||
|
||||
public static Map<User, HashMap<Item, Double>> initializeData(int numberOfUsers) {
|
||||
Map<User, HashMap<Item, Double>> data = new HashMap<>();
|
||||
HashMap<Item, Double> newUser;
|
||||
Set<Item> newRecommendationSet;
|
||||
for (int i = 0; i < numberOfUsers; i++) {
|
||||
newUser = new HashMap<Item, Double>();
|
||||
newRecommendationSet = new HashSet<>();
|
||||
for (int j = 0; j < 3; j++) {
|
||||
newRecommendationSet.add(items.get((int) (Math.random() * 5)));
|
||||
}
|
||||
for (Item item : newRecommendationSet) {
|
||||
newUser.put(item, Math.random());
|
||||
}
|
||||
data.put(new User("User " + i), newUser);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.baeldung.algorithms.slope_one;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Item {
|
||||
|
||||
private String itemName;
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package com.baeldung.algorithms.slope_one;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Slope One algorithm implementation
|
||||
*/
|
||||
public class SlopeOne {
|
||||
|
||||
private static Map<Item, Map<Item, Double>> diff = new HashMap<>();
|
||||
private static Map<Item, Map<Item, Integer>> freq = new HashMap<>();
|
||||
private static Map<User, HashMap<Item, Double>> inputData;
|
||||
private static Map<User, HashMap<Item, Double>> outputData = new HashMap<>();
|
||||
|
||||
public static void slopeOne(int numberOfUsers) {
|
||||
inputData = InputData.initializeData(numberOfUsers);
|
||||
System.out.println("Slope One - Before the Prediction\n");
|
||||
buildDifferencesMatrix(inputData);
|
||||
System.out.println("\nSlope One - With Predictions\n");
|
||||
predict(inputData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the available data, calculate the relationships between the
|
||||
* items and number of occurences
|
||||
*
|
||||
* @param data
|
||||
* existing user data and their items' ratings
|
||||
*/
|
||||
private static void buildDifferencesMatrix(Map<User, HashMap<Item, Double>> data) {
|
||||
for (HashMap<Item, Double> user : data.values()) {
|
||||
for (Entry<Item, Double> e : user.entrySet()) {
|
||||
if (!diff.containsKey(e.getKey())) {
|
||||
diff.put(e.getKey(), new HashMap<Item, Double>());
|
||||
freq.put(e.getKey(), new HashMap<Item, Integer>());
|
||||
}
|
||||
for (Entry<Item, Double> e2 : user.entrySet()) {
|
||||
int oldCount = 0;
|
||||
if (freq.get(e.getKey()).containsKey(e2.getKey())) {
|
||||
oldCount = freq.get(e.getKey()).get(e2.getKey()).intValue();
|
||||
}
|
||||
double oldDiff = 0.0;
|
||||
if (diff.get(e.getKey()).containsKey(e2.getKey())) {
|
||||
oldDiff = diff.get(e.getKey()).get(e2.getKey()).doubleValue();
|
||||
}
|
||||
double observedDiff = e.getValue() - e2.getValue();
|
||||
freq.get(e.getKey()).put(e2.getKey(), oldCount + 1);
|
||||
diff.get(e.getKey()).put(e2.getKey(), oldDiff + observedDiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Item j : diff.keySet()) {
|
||||
for (Item i : diff.get(j).keySet()) {
|
||||
double oldValue = diff.get(j).get(i).doubleValue();
|
||||
int count = freq.get(j).get(i).intValue();
|
||||
diff.get(j).put(i, oldValue / count);
|
||||
}
|
||||
}
|
||||
printData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on existing data predict all missing ratings. If prediction is not
|
||||
* possible, the value will be equal to -1
|
||||
*
|
||||
* @param data
|
||||
* existing user data and their items' ratings
|
||||
*/
|
||||
private static void predict(Map<User, HashMap<Item, Double>> data) {
|
||||
HashMap<Item, Double> uPred = new HashMap<Item, Double>();
|
||||
HashMap<Item, Integer> uFreq = new HashMap<Item, Integer>();
|
||||
for (Item j : diff.keySet()) {
|
||||
uFreq.put(j, 0);
|
||||
uPred.put(j, 0.0);
|
||||
}
|
||||
for (Entry<User, HashMap<Item, Double>> e : data.entrySet()) {
|
||||
for (Item j : e.getValue().keySet()) {
|
||||
for (Item k : diff.keySet()) {
|
||||
try {
|
||||
double predictedValue = diff.get(k).get(j).doubleValue() + e.getValue().get(j).doubleValue();
|
||||
double finalValue = predictedValue * freq.get(k).get(j).intValue();
|
||||
uPred.put(k, uPred.get(k) + finalValue);
|
||||
uFreq.put(k, uFreq.get(k) + freq.get(k).get(j).intValue());
|
||||
} catch (NullPointerException e1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
HashMap<Item, Double> clean = new HashMap<Item, Double>();
|
||||
for (Item j : uPred.keySet()) {
|
||||
if (uFreq.get(j) > 0) {
|
||||
clean.put(j, uPred.get(j).doubleValue() / uFreq.get(j).intValue());
|
||||
}
|
||||
}
|
||||
for (Item j : InputData.items) {
|
||||
if (e.getValue().containsKey(j)) {
|
||||
clean.put(j, e.getValue().get(j));
|
||||
} else {
|
||||
clean.put(j, -1.0);
|
||||
}
|
||||
}
|
||||
outputData.put(e.getKey(), clean);
|
||||
}
|
||||
printData(outputData);
|
||||
}
|
||||
|
||||
private static void printData(Map<User, HashMap<Item, Double>> data) {
|
||||
for (User user : data.keySet()) {
|
||||
System.out.println(user.getUsername() + ":");
|
||||
print(data.get(user));
|
||||
}
|
||||
}
|
||||
|
||||
private static void print(HashMap<Item, Double> hashMap) {
|
||||
NumberFormat formatter = new DecimalFormat("#0.000");
|
||||
for (Item j : hashMap.keySet()) {
|
||||
System.out.println(" " + j.getItemName() + " --> " + formatter.format(hashMap.get(j).doubleValue()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.baeldung.algorithms.slope_one;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class User {
|
||||
|
||||
private String username;
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package com.baeldung.algorithms;
|
||||
|
||||
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;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class DijkstraAlgorithmLongRunningUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenSPPSolved_thenCorrect() {
|
||||
|
||||
Node nodeA = new Node("A");
|
||||
Node nodeB = new Node("B");
|
||||
Node nodeC = new Node("C");
|
||||
Node nodeD = new Node("D");
|
||||
Node nodeE = new Node("E");
|
||||
Node nodeF = new Node("F");
|
||||
|
||||
nodeA.addDestination(nodeB, 10);
|
||||
nodeA.addDestination(nodeC, 15);
|
||||
|
||||
nodeB.addDestination(nodeD, 12);
|
||||
nodeB.addDestination(nodeF, 15);
|
||||
|
||||
nodeC.addDestination(nodeE, 10);
|
||||
|
||||
nodeD.addDestination(nodeE, 2);
|
||||
nodeD.addDestination(nodeF, 1);
|
||||
|
||||
nodeF.addDestination(nodeE, 5);
|
||||
|
||||
Graph graph = new Graph();
|
||||
|
||||
graph.addNode(nodeA);
|
||||
graph.addNode(nodeB);
|
||||
graph.addNode(nodeC);
|
||||
graph.addNode(nodeD);
|
||||
graph.addNode(nodeE);
|
||||
graph.addNode(nodeF);
|
||||
|
||||
graph = Dijkstra.calculateShortestPathFromSource(graph, nodeA);
|
||||
|
||||
List<Node> shortestPathForNodeB = Arrays.asList(nodeA);
|
||||
List<Node> shortestPathForNodeC = Arrays.asList(nodeA);
|
||||
List<Node> shortestPathForNodeD = Arrays.asList(nodeA, nodeB);
|
||||
List<Node> shortestPathForNodeE = Arrays.asList(nodeA, nodeB, nodeD);
|
||||
List<Node> shortestPathForNodeF = Arrays.asList(nodeA, nodeB, nodeD);
|
||||
|
||||
for (Node node : graph.getNodes()) {
|
||||
switch (node.getName()) {
|
||||
case "B":
|
||||
assertTrue(node
|
||||
.getShortestPath()
|
||||
.equals(shortestPathForNodeB));
|
||||
break;
|
||||
case "C":
|
||||
assertTrue(node
|
||||
.getShortestPath()
|
||||
.equals(shortestPathForNodeC));
|
||||
break;
|
||||
case "D":
|
||||
assertTrue(node
|
||||
.getShortestPath()
|
||||
.equals(shortestPathForNodeD));
|
||||
break;
|
||||
case "E":
|
||||
assertTrue(node
|
||||
.getShortestPath()
|
||||
.equals(shortestPathForNodeE));
|
||||
break;
|
||||
case "F":
|
||||
assertTrue(node
|
||||
.getShortestPath()
|
||||
.equals(shortestPathForNodeF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user