package graph; import java.util.HashMap; import java.util.Objects; import java.util.PriorityQueue; import java.util.Vector; public class DirectedGraph extends Graph { // KONSTRUKTOREN public DirectedGraph() { super(); } public DirectedGraph(String s) { super(s); } // KNOTEN EIGENSCHAFTEN // Prüfung, ob zwei Knoten stark adjazent sind public boolean areStrongAdjacent(MarkedVertex n1, MarkedVertex n2) { boolean n1ton2 = false; boolean n2ton1 = false; for (MarkedEdge i: this.getAllEdges()) { if (i.getSource() == n1 && i.getDestination() == n2) { n1ton2 = true; } else if (i.getSource() == n2 && i.getDestination() == n1) { n2ton1 = true; } } return (n1ton2 && n2ton1); } public boolean areStrongAdjacent(String s1, String s2) throws NameDoesNotExistException { MarkedVertex n1 = null; MarkedVertex n2 = null; for (MarkedVertex i: this.getAllVertexes()) { if (Objects.equals(i.getName(), s1)) { n1 = i; } else if (Objects.equals(i.getName(), s2)) { n2 = i; } } if (n1 == null || n2 == null) { throw new NameDoesNotExistException("One of the Vertexes might not exist"); } else { return areStrongAdjacent(n1, n2); } } // Prüfung des Eingangsgrades eines Knotens public int inDegree(MarkedVertex n) { int degree = 0; for (MarkedEdge i: this.getAllEdges()) { if (i.getDestination() == n) { degree += 1; } } return degree; } public int inDegree(String s) throws NameDoesNotExistException{ for (MarkedVertex i: this.getAllVertexes()) { if (Objects.equals(i.getName(), s)) { return inDegree(i); } } throw new NameDoesNotExistException("One of the Vertexes might not exist"); } // Prüfung des Ausgangsgrades eines Knotens public int outDegree(MarkedVertex n) { int degree = 0; for (MarkedEdge i: this.getAllEdges()) { if (i.getSource() == n) { degree += 1; } } return degree; } public int outDegree(String s) throws NameDoesNotExistException{ for (MarkedVertex i: this.getAllVertexes()) { if (Objects.equals(i.getName(), s)) { return outDegree(i); } } throw new NameDoesNotExistException("One of the Vertexes might not exist"); } // Prüfung, welche Knoten Vorgänger sind public Vector> getPredecessors(MarkedVertex n) { Vector> predecessors = new Vector<>(); for (MarkedEdge i: this.getAllEdges()) { if (i.getDestination() == n) { predecessors.add((MarkedVertex) i.getSource()); } } return predecessors; } // Prüfung, welche Knoten Nachfolger sind public Vector> getSuccessors(MarkedVertex n) { Vector> successors = new Vector<>(); for (MarkedEdge i: this.getAllEdges()) { if (i.getSource() == n) { successors.add((MarkedVertex) i.getDestination()); } } return successors; } // AUFGABE 2 // Dijkstra-Algorithmus public int getShortestPathDijkstra(MarkedVertex n1, MarkedVertex n2) { // Erstellt Hashmap um Distanz von Startnoten zu jedem Knoten auf dem Graph zu tracken // Erstellt Hashmap um zu tracken welche Knoten schon besucht wurden // Initialisierung aller Distanzen auf UNENDLICH (= -1) // Initialisierung, dass kein Knoten besucht wurde HashMap, Integer> distance = new HashMap<>(); HashMap, Boolean> visited = new HashMap<>(); for (MarkedVertex i: this.getAllVertexes()) { distance.put(i, -1); visited.put(i, false); } // Erstelle Schlange wo die nächsten Verbindungen drin sind PriorityQueue> queue = new PriorityQueue<>(new WrapperComparator()); // Distanz zu Startknoten auf 0 // Weg zu Startknoten in die Schlange aufnehmen distance.put(n1, 0); queue.add(new WrapperElement<>(n1, 0)); // Variable, die Distanz zwischen aktuellem Knoten und Nachfolger speichert int dist = 0; while (!queue.isEmpty()) { // Den nächsten Knoten, der am wenigsten kostet, besuchen WrapperElement nextVertex = queue.poll(); // Knoten als besucht makieren visited.put(nextVertex.getElement(), true); System.out.println("Visit " + nextVertex.getElement().getName()); // Gehe von diesem Knoten aus alle erreichbaren Knoten durch for (MarkedVertex i: this.getSuccessors(nextVertex.getElement())) { // Kante finde, die den jetzigen und nächsten Knoten verbindet for (MarkedEdge j: this.getAllEdges()) { if (j.getSource() == nextVertex.getElement() && j.getDestination() == i) { // Berechne Distanz zu nächstem Knoten dist = distance.get(nextVertex.getElement()) + j.getWeighting(); break; } } // Wenn es schon einen kürzeren Weg zum Knoten gibt, überspringen if ((distance.get(i) <= dist && distance.get(i) != -1) || visited.get(i)) { continue; } // Aktualisiere Distanz von Start zu nächstem Knoten distance.put(i, dist); System.out.println("Add " + i.getName() + " with " + dist + " weight to queue."); // Nehme nächsten Knoten in die Queue auf queue.add(new WrapperElement<>(i, dist)); } } // Gibt Distanz zu gefragtem Knoten zurück return distance.get(n2); } }