diff --git a/myShortestPath.java b/myShortestPath.java index 0395e7ab2fdd578f58a7d70b3272b2a96825fcf9..3f949ee5e26d682fdfc10e3e814812abf830aacc 100644 --- a/myShortestPath.java +++ b/myShortestPath.java @@ -1,6 +1,4 @@ -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; +import java.util.*; import org.jgrapht.Graph; import org.jgrapht.graph.DefaultWeightedEdge; @@ -21,80 +19,42 @@ public class myShortestPath { predecessors = new HashMap<Integer, Integer>(); } - //Computes distances and predecessors for all nodes //Computes distances and predecessors for all nodes public void computeDistPred() { - for (Integer vertex : graph.vertexSet()) { - distances.put(vertex, Double.MAX_VALUE); - predecessors.put(vertex, null); - } + HashSet<Integer> setVertices = new HashSet<Integer>(); + setVertices.add(startVertex); + distances.put(-1, Double.MAX_VALUE); distances.put(startVertex, 0.); - // Implement your algorithm here - - int act_v = startVertex; - - // Dijkstra - HashSet<Integer> set_vertices = new HashSet<Integer>(); // Würde hier eigentlich lieber über die nicht gesetzen Knoten iterieren ... - set_vertices.add(startVertex); - while(set_vertices.size() < graph.vertexSet().size()) { - - Set<DefaultWeightedEdge> outgoing_edges = graph.outgoingEdgesOf(act_v); - Iterator<DefaultWeightedEdge> out_it = outgoing_edges.iterator(); - - while (out_it.hasNext()) { // Iteriere über alle ausgehenden Kanten des betrachteten Knoten - DefaultWeightedEdge e = out_it.next(); - - int target = graph.getEdgeTarget(e); - if (act_v == target) { // Tausche Richtung der Kanten, wenn nötig! - target = graph.getEdgeSource(e); + int act = startVertex; + // O(|V|^2) + while(act != -1) { + Set<DefaultWeightedEdge> outgoingEdges = graph.outgoingEdgesOf(act); + for (DefaultWeightedEdge e : outgoingEdges) { // Iteriere über alle ausgehenden Kanten des betrachteten Knoten. + int target = graph.getEdgeTarget(e) == act ? graph.getEdgeSource(e) : graph.getEdgeTarget(e); // Drehe Kante nötigenfalls um. + double totalWeight = distances.get(act) + graph.getEdgeWeight(e); + if (!distances.containsKey(target) || totalWeight < distances.get(target)) { // Update Distanz und Vorgänger, wenn ein neuer kürzester Weg vorliegt. + distances.put(target, totalWeight); + predecessors.put(target, act); } - - if (!set_vertices.contains(target)) { // Überprüfe, ob Kante schon fest gesetzt ist. Update die Distanzen falls nicht. - double weight = distances.get(act_v) + graph.getEdgeWeight(e); - - if (weight < distances.get(target)) { // Update Distanz und Vorgänger, wenn ein neuer kürzester Weg vorliegt. - distances.put(target, weight); - predecessors.put(target, act_v); - } - - } - } - - double min_weight = Double.MAX_VALUE; // Initialisiere neuen kürzesten Weg - int min_v = act_v; - - for (Integer v : graph.vertexSet()) { // Finde neuen kürzesten Weg - if (!set_vertices.contains(v)) { - if (distances.get(v) < min_weight) { - min_weight = distances.get(v); - min_v = v; - } + act = -1; + for (Map.Entry<Integer,Double> v : distances.entrySet()) { // finde nächsten Knoten + if (!setVertices.contains(v.getKey()) && v.getValue() < distances.get(act)) { + act = v.getKey(); } } - - if (set_vertices.contains(min_v)) { // Verhindert Entlosschleifen - break; - } - - set_vertices.add(min_v); - act_v = min_v; - + setVertices.add(act); } - } - //Constructs the shortest path from the start node to a given end node using the list of predecessors public ArrayList<Integer> constructPathToNode(Integer endVertex) { ArrayList<Integer> path = new ArrayList<Integer>(); path.add(endVertex); - while (!path.contains(startVertex)) { - Integer currentVertex = path.get(path.size()-1); - Integer nextVertex = predecessors.get(currentVertex); - path.add(nextVertex); + // O(|V|) + while (!path.get(0).equals(startVertex)) { + path.add(0,predecessors.get(path.get(0))); } - Collections.reverse(path); return path; }