193 lines
6.2 KiB
Java
193 lines
6.2 KiB
Java
package graph;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Objects;
|
|
import java.util.PriorityQueue;
|
|
import java.util.Vector;
|
|
|
|
public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> extends Graph<T, U> {
|
|
|
|
// KONSTRUKTOREN
|
|
|
|
public DirectedGraph() {
|
|
super();
|
|
}
|
|
|
|
|
|
public DirectedGraph(String s) {
|
|
super(s);
|
|
}
|
|
|
|
|
|
// KNOTEN EIGENSCHAFTEN
|
|
|
|
// Prüfung, ob zwei Knoten stark adjazent sind
|
|
public boolean areStrongAdjacent(MarkedVertex<T> n1, MarkedVertex<T> n2) {
|
|
boolean n1ton2 = false;
|
|
boolean n2ton1 = false;
|
|
for (MarkedEdge<U> 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<T> n1 = null;
|
|
MarkedVertex<T> n2 = null;
|
|
for (MarkedVertex<T> 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<T> n) {
|
|
int degree = 0;
|
|
for (MarkedEdge<U> i: this.getAllEdges()) {
|
|
if (i.getDestination() == n) {
|
|
degree += 1;
|
|
}
|
|
}
|
|
return degree;
|
|
}
|
|
|
|
|
|
public int inDegree(String s) throws NameDoesNotExistException{
|
|
for (MarkedVertex<T> 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<T> n) {
|
|
int degree = 0;
|
|
for (MarkedEdge<U> i: this.getAllEdges()) {
|
|
if (i.getSource() == n) {
|
|
degree += 1;
|
|
}
|
|
}
|
|
return degree;
|
|
}
|
|
|
|
|
|
public int outDegree(String s) throws NameDoesNotExistException{
|
|
for (MarkedVertex<T> 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<MarkedVertex<T>> getPredecessors(MarkedVertex<T> n) {
|
|
Vector<MarkedVertex<T>> predecessors = new Vector<>();
|
|
for (MarkedEdge<U> i: this.getAllEdges()) {
|
|
if (i.getDestination() == n) {
|
|
predecessors.add((MarkedVertex<T>) i.getSource());
|
|
}
|
|
}
|
|
return predecessors;
|
|
}
|
|
|
|
|
|
// Prüfung, welche Knoten Nachfolger sind
|
|
public Vector<MarkedVertex<T>> getSuccessors(MarkedVertex<T> n) {
|
|
Vector<MarkedVertex<T>> successors = new Vector<>();
|
|
for (MarkedEdge<U> i: this.getAllEdges()) {
|
|
if (i.getSource() == n) {
|
|
successors.add((MarkedVertex<T>) i.getDestination());
|
|
}
|
|
}
|
|
return successors;
|
|
}
|
|
|
|
|
|
// AUFGABE 2
|
|
|
|
// Dijkstra-Algorithmus
|
|
public int getShortestPathDijkstra(MarkedVertex<T> n1, MarkedVertex<T> 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<MarkedVertex<T>, Integer> distance = new HashMap<>();
|
|
HashMap<MarkedVertex<T>, Boolean> visited = new HashMap<>();
|
|
for (MarkedVertex<T> i: this.getAllVertexes()) {
|
|
distance.put(i, -1);
|
|
visited.put(i, false);
|
|
}
|
|
|
|
// Erstelle Schlange wo die nächsten Verbindungen drin sind
|
|
PriorityQueue<WrapperElement<T>> queue = new PriorityQueue<>(new WrapperComparator<T>());
|
|
|
|
// 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<T> 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<T> i: this.getSuccessors(nextVertex.getElement())) {
|
|
|
|
// Kante finde, die den jetzigen und nächsten Knoten verbindet
|
|
for (MarkedEdge<U> 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);
|
|
}
|
|
}
|