Compare commits

...

3 Commits

Author SHA1 Message Date
7014e9308c Window size and Example restructuring 2024-07-08 18:03:30 +02:00
deaffff595 Merge branch 'main' of https://gitea.hb.dhbw-stuttgart.de/i23024/ProjektGraph
# Conflicts:
#	graph/DirectedGraph.java
#	graph/Graph.java
#	graph/NameDoesNotExistException.java
#	graph/UndirectedGraph.java
#	out/production/ProjektGraph/graph/Graph.class
#	out/production/ProjektGraph/graph/WrapperComparator.class
#	out/production/ProjektGraph/graph/WrapperElement.class
2024-07-08 17:51:11 +02:00
5bab9b5992 Improved Algortihms and A Star Heuristik 2024-07-08 17:12:08 +02:00
18 changed files with 125 additions and 132 deletions

View File

@ -73,7 +73,7 @@ public class OurApplication {
frame.pack();
applet.init();
applet.start();
frame.setSize(1000,800);
frame.setSize(1350,800);
frame.setVisible(true);
}

View File

@ -349,18 +349,18 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
// Den nächsten Knoten, der am wenigsten kostet, besuchen
WrapperElement<T> nextVertex = queue.poll();
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
// Logging
textDescription = "Visit " + nextVertex.getElement().getName();
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
// Falls Knoten schon besucht
if(!visited.get(nextVertex.getElement())){
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
textDescription = "Visit " + nextVertex.getElement().getName();
// Logging
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
// Wenn Weg gefunden, brich ab
if (nextVertex.getElement() == n2) {
@ -445,7 +445,7 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
* @param n2 the ending vertex
* @return the shortest distance from n1 to n2, or -1 if no path is found
*/
public int getShortestPathAStar(MarkedVertex<T> n1, MarkedVertex<T> n2) {
public double getShortestPathAStar(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
@ -453,11 +453,11 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
// Initialisierung aller Distanzen auf UNENDLICH (= -1)
// Initialisierung, dass kein Knoten besucht wurde
// Initialisierung aller Vorgänger auf null
HashMap<MarkedVertex<T>, Integer> distance = new HashMap<>();
HashMap<MarkedVertex<T>, Double> distance = new HashMap<>();
HashMap<MarkedVertex<T>, Boolean> visited = new HashMap<>();
HashMap<MarkedVertex<T>, MarkedVertex<T>> predecessors = new HashMap<>();
for (MarkedVertex<T> i: this.getAllVertexes()) {
distance.put(i, -1);
distance.put(i, -1.0);
visited.put(i, false);
predecessors.put(i, null);
}
@ -467,15 +467,15 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
// Distanz zu Startknoten auf 0
// Weg zu Startknoten in die Schlange aufnehmen
distance.put(n1, 0);
distance.put(n1, 0.0);
queue.add(new WrapperElement<>(n1, 0));
// Variable, die Distanz zwischen aktuellem Knoten und Nachfolger speichert
int dist = 0;
double dist = 0;
// Variable, die Distanz zwischen dem potenziell nächsten Knoten und dem Zielknoten speichert
int airDist = 0;
double airDist = 0;
// Variable, die Distanz zwischen dem aktuellen Knoten bis zum Endknoten speichert
int distToFinish = 0;
double distToFinish = 0;
// Zähler für LogList
int step = 0;
// String für den Description Inhalt
@ -492,17 +492,19 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
// Den nächsten Knoten, der am wenigsten kostet, besuchen
WrapperElement<T> nextVertex = queue.poll();
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
// Logging
textDescription = "Visit " + nextVertex.getElement().getName();
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
// Falls Knoten schon besucht
if(!visited.get(nextVertex.getElement())){
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
textDescription = "Visit " + nextVertex.getElement().getName();
// Logging
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
// Wenn Weg gefunden, brich ab
if (nextVertex.getElement() == n2) {
@ -531,8 +533,8 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
if (j.getSource() == nextVertex.getElement() && j.getDestination() == i) {
//Berechnung der Heuristik über die Luftdistanz des nächsten Knoten zum Zielknoten
airDist = (int) Math.sqrt(Math.pow((i.getCords()[0] - n2.getCords()[0]), 2)
+ Math.pow((i.getCords()[1] - n2.getCords()[1]), 2));
airDist = Math.sqrt(Math.pow((i.getCords()[0] - n2.getCords()[0]), 2)
+ Math.pow((i.getCords()[1] - n2.getCords()[1]), 2)) / 100;
// Berechne Distanz zu nächstem Knoten
EdgeWeightMarking marking = (EdgeWeightMarking) j.getMarking();
@ -554,7 +556,7 @@ public class DirectedGraph<T extends VertexMarking, U extends EdgeMarking> exten
distance.put(i, dist);
// Logging
textDescription = "Add " + i.getName() + " with " + dist + " weight to queue.";
textDescription = "Add " + i.getName() + " with " + distToFinish + " weight to queue.";
System.out.println(textDescription);
if (i.getScreenVertex().getColor() != Color.RED) {
i.getScreenVertex().setColor(Color.YELLOW);

View File

@ -8,6 +8,59 @@ public class ExampleGraphs {
public DirectedGraph<VertexMarking, EdgeMarking> example1() {
/*
* Erstellt einen Beispielgraphen (Beispiel 4), der sich ideal für die Demonstration der Funktionsweise
* des Dijkstra- und A*-Algorithmus eignet. Der Graph enthält eine Vielzahl von Knoten, die durch
* gewichtete Kanten verbunden sind. Dies ermöglicht es, den kürzesten Weg von einem Startknoten zu einem
* Zielknoten effizient zu berechnen und die Unterschiede zwischen den beiden Algorithmen in der
* Pfadfindung zu veranschaulichen.
*
*
*/
DirectedGraph<VertexMarking, EdgeMarking> example4 = new DirectedGraph<>();
// Erstellung der Knoten mit Koordinaten
MarkedVertex<VertexMarking> A = new MarkedVertex<>(50, 250, "Start", null, null);
MarkedVertex<VertexMarking> B = new MarkedVertex<>(150, 150, "B", null, null);
MarkedVertex<VertexMarking> C = new MarkedVertex<>(150, 350, "C", null, null);
MarkedVertex<VertexMarking> D = new MarkedVertex<>(250, 100, "D", null, null);
MarkedVertex<VertexMarking> E = new MarkedVertex<>(250, 250, "E", null, null);
MarkedVertex<VertexMarking> F = new MarkedVertex<>(350, 200, "F", null, null);
MarkedVertex<VertexMarking> G = new MarkedVertex<>(450, 300, "G", null, null);
MarkedVertex<VertexMarking> H = new MarkedVertex<>(450, 100, "Ende", null, null);
// Hinzufügen der Knoten zum Graphen
example4.addVertex(A);
example4.addVertex(B);
example4.addVertex(C);
example4.addVertex(D);
example4.addVertex(E);
example4.addVertex(F);
example4.addVertex(G);
example4.addVertex(H);
// Erstellung der Kanten mit Gewichtungen
example4.addEdge(new MarkedEdge<>("AB", A, B, new EdgeWeightMarking(4)));
example4.addEdge(new MarkedEdge<>("AC", A, C, new EdgeWeightMarking(2)));
example4.addEdge(new MarkedEdge<>("BC", B, C, new EdgeWeightMarking(5)));
example4.addEdge(new MarkedEdge<>("BD", B, D, new EdgeWeightMarking(10)));
example4.addEdge(new MarkedEdge<>("CD", C, D, new EdgeWeightMarking(3)));
example4.addEdge(new MarkedEdge<>("CE", C, E, new EdgeWeightMarking(7)));
example4.addEdge(new MarkedEdge<>("DE", D, E, new EdgeWeightMarking(2)));
example4.addEdge(new MarkedEdge<>("DF", D, F, new EdgeWeightMarking(2)));
example4.addEdge(new MarkedEdge<>("EF", E, F, new EdgeWeightMarking(5)));
example4.addEdge(new MarkedEdge<>("EG", E, G, new EdgeWeightMarking(10)));
example4.addEdge(new MarkedEdge<>("FG", F, G, new EdgeWeightMarking(3)));
example4.addEdge(new MarkedEdge<>("FH", F, H, new EdgeWeightMarking(6)));
example4.addEdge(new MarkedEdge<>("GH", G, H, new EdgeWeightMarking(1)));
return example4;
}
public DirectedGraph<VertexMarking, EdgeMarking> example2() {
/*
* Beispiel 1 zeigt ein Gitter aus Knoten und Kanten, bei dem jeder Knoten mit
* seinen horizontal und vertikal benachbarten Knoten verbunden ist. Alle Kanten
@ -18,8 +71,6 @@ public class ExampleGraphs {
* Demonstrieren, wie der A*-Algorithmus durch gezieltere Suche effizienter ist
* als der Dijkstra-Algorithmus in einem strukturierten Gittergraphen.
*
* Startknoten: A
* Endknoten: Y
*/
DirectedGraph<VertexMarking, EdgeMarking> example1 = new DirectedGraph<>();
@ -63,7 +114,7 @@ public class ExampleGraphs {
graph.addEdge(backwardEdge);
}
public DirectedGraph<VertexMarking, EdgeMarking> example2() {
public DirectedGraph<VertexMarking, EdgeMarking> example3() {
DirectedGraph<VertexMarking, EdgeMarking> example2 = new DirectedGraph<>();
@ -73,8 +124,6 @@ public class ExampleGraphs {
* Der andere Weg (unten) hat mehr Knoten mit höherer Gewichtung der Kanten. Der Algorithmus sollte zuerst den oberen
* Weg erkunden, bis er die hohe Gewichtung der letzten Kante des unteren Wegs berücksichtigt.
*
* Startknoten: A
* Endknoten: E
*/
MarkedVertex A = new MarkedVertex<>(100, 100, "Start", null, null);
@ -107,15 +156,13 @@ public class ExampleGraphs {
public DirectedGraph<VertexMarking, EdgeMarking> example3() {
public DirectedGraph<VertexMarking, EdgeMarking> example4() {
/*
* Beispiel 3 zeigt ein Labyrinth mit vier horizontalen Wegen, die jeweils aus vier Knoten bestehen.
* Jeder Weg führt zum Endpunkt E1, E2, E3 bzw. E4. Ziel ist es zu zeigen, dass die Algorithmen auch
* potenziell falsche Wege erkunden können, bevor sie den richtigen Endpunkt erreichen.
*
* Startknoten: A
* Endknoten: E2
*/
DirectedGraph<VertexMarking, EdgeMarking> example3 = new DirectedGraph<>();
@ -187,63 +234,6 @@ public class ExampleGraphs {
return example3;
}
public DirectedGraph<VertexMarking, EdgeMarking> example4() {
/**
* Erstellt einen Beispielgraphen (Beispiel 4), der sich ideal für die Demonstration der Funktionsweise
* des Dijkstra- und A*-Algorithmus eignet. Der Graph enthält eine Vielzahl von Knoten, die durch
* gewichtete Kanten verbunden sind. Dies ermöglicht es, den kürzesten Weg von einem Startknoten zu einem
* Zielknoten effizient zu berechnen und die Unterschiede zwischen den beiden Algorithmen in der
* Pfadfindung zu veranschaulichen.
*
* Startknoten: A
* Zielknoten: H
*
*/
DirectedGraph<VertexMarking, EdgeMarking> example4 = new DirectedGraph<>();
// Erstellung der Knoten mit Koordinaten
MarkedVertex<VertexMarking> A = new MarkedVertex<>(50, 250, "Start", null, null);
MarkedVertex<VertexMarking> B = new MarkedVertex<>(150, 150, "B", null, null);
MarkedVertex<VertexMarking> C = new MarkedVertex<>(150, 350, "C", null, null);
MarkedVertex<VertexMarking> D = new MarkedVertex<>(250, 100, "D", null, null);
MarkedVertex<VertexMarking> E = new MarkedVertex<>(250, 250, "E", null, null);
MarkedVertex<VertexMarking> F = new MarkedVertex<>(350, 200, "F", null, null);
MarkedVertex<VertexMarking> G = new MarkedVertex<>(450, 300, "G", null, null);
MarkedVertex<VertexMarking> H = new MarkedVertex<>(450, 100, "Ende", null, null);
// Hinzufügen der Knoten zum Graphen
example4.addVertex(A);
example4.addVertex(B);
example4.addVertex(C);
example4.addVertex(D);
example4.addVertex(E);
example4.addVertex(F);
example4.addVertex(G);
example4.addVertex(H);
// Erstellung der Kanten mit Gewichtungen
example4.addEdge(new MarkedEdge<>("AB", A, B, new EdgeWeightMarking(4)));
example4.addEdge(new MarkedEdge<>("AC", A, C, new EdgeWeightMarking(2)));
example4.addEdge(new MarkedEdge<>("BC", B, C, new EdgeWeightMarking(5)));
example4.addEdge(new MarkedEdge<>("BD", B, D, new EdgeWeightMarking(10)));
example4.addEdge(new MarkedEdge<>("CD", C, D, new EdgeWeightMarking(3)));
example4.addEdge(new MarkedEdge<>("CE", C, E, new EdgeWeightMarking(7)));
example4.addEdge(new MarkedEdge<>("DE", D, E, new EdgeWeightMarking(2)));
example4.addEdge(new MarkedEdge<>("DF", D, F, new EdgeWeightMarking(2)));
example4.addEdge(new MarkedEdge<>("EF", E, F, new EdgeWeightMarking(5)));
example4.addEdge(new MarkedEdge<>("EG", E, G, new EdgeWeightMarking(10)));
example4.addEdge(new MarkedEdge<>("FG", F, G, new EdgeWeightMarking(3)));
example4.addEdge(new MarkedEdge<>("FH", F, H, new EdgeWeightMarking(6)));
example4.addEdge(new MarkedEdge<>("GH", G, H, new EdgeWeightMarking(1)));
return example4;
}
}

View File

@ -412,6 +412,6 @@ public abstract class Graph<T extends VertexMarking, U extends EdgeMarking> {
* @param n2 Destination vertex.
* @return Length of the shortest path between the vertices.
*/
public abstract int getShortestPathAStar(MarkedVertex<T> n1, MarkedVertex<T> n2);
public abstract double getShortestPathAStar(MarkedVertex<T> n1, MarkedVertex<T> n2);
}

View File

@ -58,7 +58,7 @@ class WrapperElement<T extends VertexMarking> {
// ATTRIBUTE
private MarkedVertex<T> element;
private int priority;
private double priority;
// KONSTRUKTOR
@ -69,7 +69,7 @@ class WrapperElement<T extends VertexMarking> {
* @param element The marked vertex to wrap.
* @param priority The priority associated with the element.
*/
public WrapperElement(MarkedVertex<T> element, int priority) {
public WrapperElement(MarkedVertex<T> element, double priority) {
this.element = element;
this.priority = priority;
}
@ -92,7 +92,7 @@ class WrapperElement<T extends VertexMarking> {
*
* @return The priority.
*/
public int getPriority() {
public double getPriority() {
return this.priority;
}
@ -130,6 +130,6 @@ class WrapperComparator<T extends VertexMarking> implements Comparator<WrapperEl
* priority is less than, equal to, or greater than the second element's priority.
*/
public int compare(WrapperElement<T> element1, WrapperElement<T> element2) {
return Integer.compare(element1.getPriority(), element2.getPriority());
return Double.compare(element1.getPriority(), element2.getPriority());
}
}

View File

@ -253,17 +253,18 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
// Den nächsten Knoten, der am wenigsten kostet, besuchen
WrapperElement<T> nextVertex = queue.poll();
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
// Logging
textDescription = "Visit " + nextVertex.getElement().getName();
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
// Falls Knoten schon besucht
if(!visited.get(nextVertex.getElement())){
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
textDescription = "Visit " + nextVertex.getElement().getName();
// Logging
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
// Wenn Weg gefunden, brich ab
@ -349,7 +350,7 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
* @param n2 The ending vertex of the shortest path.
* @return The length of the shortest path between n1 and n2.
*/
public int getShortestPathAStar(MarkedVertex<T> n1, MarkedVertex<T> n2) {
public double getShortestPathAStar(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
@ -357,11 +358,11 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
// Initialisierung aller Distanzen auf UNENDLICH (= -1)
// Initialisierung, dass kein Knoten besucht wurde
// Initialisierung aller Vorgänger auf null
HashMap<MarkedVertex<T>, Integer> distance = new HashMap<>();
HashMap<MarkedVertex<T>, Double> distance = new HashMap<>();
HashMap<MarkedVertex<T>, Boolean> visited = new HashMap<>();
HashMap<MarkedVertex<T>, MarkedVertex<T>> predecessors = new HashMap<>();
for (MarkedVertex<T> i: this.getAllVertexes()) {
distance.put(i, -1);
distance.put(i, -1.0);
visited.put(i, false);
predecessors.put(i, null);
}
@ -371,15 +372,15 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
// Distanz zu Startknoten auf 0
// Weg zu Startknoten in die Schlange aufnehmen
distance.put(n1, 0);
distance.put(n1, 0.0);
queue.add(new WrapperElement<>(n1, 0));
// Variable, die Distanz zwischen aktuellem Knoten und Nachfolger speichert
int dist = 0;
double dist = 0;
// Variable, die Distanz zwischen dem potenziell nächsten Knoten und dem Zielknoten speichert
int airDist = 0;
double airDist = 0;
// Variable, die Distanz zwischen dem aktuellen Knoten bis zum Endknoten speichert
int distToFinish = 0;
double distToFinish = 0;
// Zähler für LogList
int step = 0;
// String für den Description Inhalt
@ -396,18 +397,18 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
// Den nächsten Knoten, der am wenigsten kostet, besuchen
WrapperElement<T> nextVertex = queue.poll();
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
// Logging
textDescription = "Visit " + nextVertex.getElement().getName();
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
// Falls Knoten schon besucht
if(!visited.get(nextVertex.getElement())){
// Knoten als besucht makieren
visited.put(nextVertex.getElement(), true);
textDescription = "Visit " + nextVertex.getElement().getName();
// Logging
System.out.println(textDescription);
if (nextVertex.getElement().getScreenVertex().getColor() != Color.RED) {
nextVertex.getElement().getScreenVertex().setColor(Color.BLUE);
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
}
this.logList.add(new OurLogElement(step, textDescription, 0, this.getScreenGraphCopy()));
// Wenn Weg gefunden, brich ab
if (nextVertex.getElement() == n2) {
@ -436,8 +437,8 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
if (j.getSource() == nextVertex.getElement() && j.getDestination() == i) {
//Berechnung der Heuristik über die Luftdistanz des nächsten Knoten zum Zielknoten
airDist = (int) Math.sqrt(Math.pow((i.getCords()[0] - n2.getCords()[0]), 2)
+ Math.pow((i.getCords()[1] - n2.getCords()[1]), 2));
airDist = Math.sqrt(Math.pow((i.getCords()[0] - n2.getCords()[0]), 2)
+ Math.pow((i.getCords()[1] - n2.getCords()[1]), 2)) / 100;
// Berechne Distanz zu nächstem Knoten
EdgeWeightMarking marking = (EdgeWeightMarking) j.getMarking();
@ -456,7 +457,7 @@ public class UndirectedGraph<T extends VertexMarking, U extends EdgeMarking> ext
distance.put(i, dist);
// Logging
textDescription = "Add " + i.getName() + " with " + dist + " weight to queue.";
textDescription = "Add " + i.getName() + " with " + distToFinish + " weight to queue.";
System.out.println(textDescription);
if (i.getScreenVertex().getColor() != Color.RED) {
i.getScreenVertex().setColor(Color.YELLOW);