diff --git a/09_dijkstras_algorithm/java/01_dijkstras_algorithm/src/DijkstrasAlgorithmPriorityQueue.java b/09_dijkstras_algorithm/java/01_dijkstras_algorithm/src/DijkstrasAlgorithmPriorityQueue.java new file mode 100644 index 00000000..24cf6ffa --- /dev/null +++ b/09_dijkstras_algorithm/java/01_dijkstras_algorithm/src/DijkstrasAlgorithmPriorityQueue.java @@ -0,0 +1,51 @@ +import java.util.*; +// Suggested to be run with Java 17+ +public class DijkstrasAlgorithmPriorityQueue { + // the graph + private static final Map> GRAPH = new HashMap<>(4); + static { + Set start = new HashSet<>(2); + start.add(new Tuple("a", 6)); + start.add(new Tuple("b", 2)); + GRAPH.put("start", start); + + GRAPH.put("a", new HashSet<>(1)); + GRAPH.get("a").add(new Tuple("fin", 1)); + + Set b = new HashSet<>(2); + b.add(new Tuple("a", 3)); + b.add(new Tuple("fin", 5)); + GRAPH.put("b", b); + GRAPH.put("fin", new HashSet<>(1)); + } + + public static void main(String[] args) { + System.out.println("Cost from the start to each node:"); + System.out.println(calculateDistances("start")); // { a: 5, b: 2, fin: 6 } + } + + private static Map calculateDistances(final String startVertex) { + // The costs table + Map costs = new HashMap<>(); + PriorityQueue pq = new PriorityQueue<>(Comparator.comparing(Tuple::cost)); + pq.add(new Tuple(startVertex, 0)); + Tuple node; + while ((node = pq.poll())!=null && node.cost <= costs.getOrDefault(node.vertex, Double.POSITIVE_INFINITY)) { + // Go through all the neighbors of this node + Set neighbors = GRAPH.getOrDefault(node.vertex, Collections.emptySet()); + for (Tuple n : neighbors) { + double newCost = node.cost + n.cost; + // If it's cheaper to get to this neighbor by going through this node + if (node.cost < newCost) { + // ... update the cost for this node + costs.put(n.vertex, newCost); + pq.add(new Tuple(n.vertex, newCost)); + } + } + } + return costs; + } + + private record Tuple(String vertex, double cost) { + } +} \ No newline at end of file diff --git a/09_dijkstras_algorithm/python/01_dijkstras_algorithm_pq.py b/09_dijkstras_algorithm/python/01_dijkstras_algorithm_pq.py new file mode 100644 index 00000000..b27b0251 --- /dev/null +++ b/09_dijkstras_algorithm/python/01_dijkstras_algorithm_pq.py @@ -0,0 +1,33 @@ +import heapq +# algorithm using priority queue +# this code is a direct copy from https://bradfieldcs.com/algos/graphs/dijkstras-algorithm/ +# with only minor changes +def calculate_distances(graph, starting_vertex): + distances = {vertex: float('infinity') for vertex in graph} + + pq = [(0, starting_vertex)] + while len(pq) > 0: + current_distance, current_vertex = heapq.heappop(pq) + # Nodes can get added to the priority queue multiple times. We only + # process a vertex the first time we remove it from the priority queue. + if current_distance > distances[current_vertex]: + continue + + for neighbor, weight in graph[current_vertex].items(): + distance = current_distance + weight + + # Only consider this new path if it's better than any path we've + # already found. + if distance < distances[neighbor]: + distances[neighbor] = distance + heapq.heappush(pq, (distance, neighbor)) + distances.pop(starting_vertex) + return distances + +example_graph = { + 'start': {'a': 6, 'b': 2}, + 'a': {'fin': 1}, + 'b': {'a': 3, 'fin': 5}, + 'fin': {} +} +print(calculate_distances(example_graph, 'start')) \ No newline at end of file