diff --git a/.idea/workspace.xml b/.idea/workspace.xml index f43f747..01c547d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,15 +6,9 @@ - - - - - - - - - + + + - { + "keyToString": { + "Application.Display.executor": "Run", + "Application.OurApplication.executor": "Run", + "Application.OurLegendArea.executor": "Run", + "RunOnceActivity.ShowReadmeOnStart": "true", + "git-widget-placeholder": "main", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "C:/Git/ProjektGraphMain" } -}]]> +} diff --git a/OurApplication/OurApplication.java b/OurApplication/OurApplication.java index 055edfb..3ba9a59 100644 --- a/OurApplication/OurApplication.java +++ b/OurApplication/OurApplication.java @@ -43,13 +43,7 @@ public class OurApplication { */ public static void main(String[]args){ - Random random = new Random(); - DirectedGraph myGraph = new DirectedGraph<>(); - - ExampleGraphs temp = new ExampleGraphs(); - //myGraph = temp.example2(); - //sean: Ich wollte erst hier dann das ausgewählte Beispiel reinhauen, jedoch wird das hier nur einmal am Anfang aufgerufen System.out.println(myGraph.toString()); diff --git a/graph/ExampleGraphs.java b/graph/ExampleGraphs.java index 3208d3b..5a47940 100644 --- a/graph/ExampleGraphs.java +++ b/graph/ExampleGraphs.java @@ -1,24 +1,30 @@ package graph; import java.awt.*; -import java.util.ArrayList; -import java.util.List; +/** + * Class containing example graphs for demonstration purposes. + */ public class ExampleGraphs { + /** + * Creates an example graph suitable for demonstrating Dijkstra's and A* algorithms. + * This graph contains multiple nodes connected by weighted edges, allowing efficient + * calculation of shortest paths from a start node to an end node. + * + * @return Directed graph instance for example 1. + */ public DirectedGraph example1() { /* - * Erstellt einen Beispielgraphen (Beispiel 4), der sich ideal für die Demonstration der Funktionsweise + * Erstellt einen Beispielgraphen, 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. - * + * Zielknoten effizient zu berechnen und die Pfadfindung der beiden Algorithmen zu veranschaulichen. * */ - DirectedGraph example4 = new DirectedGraph<>(); + DirectedGraph example1 = new DirectedGraph<>(); // Erstellung der Knoten mit Koordinaten MarkedVertex A = new MarkedVertex<>(50, 250, "Start", null, null); @@ -32,48 +38,53 @@ public class ExampleGraphs { // 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); + example1.addVertex(A); + example1.addVertex(B); + example1.addVertex(C); + example1.addVertex(D); + example1.addVertex(E); + example1.addVertex(F); + example1.addVertex(G); + example1.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))); + example1.addEdge(new MarkedEdge<>("AB", A, B, new EdgeWeightMarking(4))); + example1.addEdge(new MarkedEdge<>("AC", A, C, new EdgeWeightMarking(2))); + example1.addEdge(new MarkedEdge<>("BC", B, C, new EdgeWeightMarking(5))); + example1.addEdge(new MarkedEdge<>("BD", B, D, new EdgeWeightMarking(10))); + example1.addEdge(new MarkedEdge<>("CD", C, D, new EdgeWeightMarking(3))); + example1.addEdge(new MarkedEdge<>("CE", C, E, new EdgeWeightMarking(7))); + example1.addEdge(new MarkedEdge<>("DE", D, E, new EdgeWeightMarking(2))); + example1.addEdge(new MarkedEdge<>("DF", D, F, new EdgeWeightMarking(2))); + example1.addEdge(new MarkedEdge<>("EF", E, F, new EdgeWeightMarking(5))); + example1.addEdge(new MarkedEdge<>("EG", E, G, new EdgeWeightMarking(10))); + example1.addEdge(new MarkedEdge<>("FG", F, G, new EdgeWeightMarking(3))); + example1.addEdge(new MarkedEdge<>("FH", F, H, new EdgeWeightMarking(6))); + example1.addEdge(new MarkedEdge<>("GH", G, H, new EdgeWeightMarking(1))); - return example4; + return example1; } + /** + * Creates an example grid graph where each node is connected to its horizontal and vertical neighbors. + * All edges have the same weight. The start node is in one corner of the grid, and the end node is + * in the opposite corner, demonstrating the efficiency of the A* algorithm in structured grid graphs. + * + * @return Directed graph instance for example 2. + */ public DirectedGraph example2() { /* - * Beispiel 1 zeigt ein Gitter aus Knoten und Kanten, bei dem jeder Knoten mit + * Beispiel 2 zeigt ein Gitter aus Knoten und Kanten, bei dem jeder Knoten mit * seinen horizontal und vertikal benachbarten Knoten verbunden ist. Alle Kanten * haben die gleiche Gewichtung. Der Startknoten befindet sich in einer Ecke - * des Gitters und der Zielknoten in der gegenüberliegenden Ecke. - * - * Ziel: - * Demonstrieren, wie der A*-Algorithmus durch gezieltere Suche effizienter ist + * des Gitters und der Zielknoten in der gegenüberliegenden Ecke. Dadurch wird gezeigt, + * wie der A*-Algorithmus durch gezieltere Suche effizienter ist * als der Dijkstra-Algorithmus in einem strukturierten Gittergraphen. * */ - DirectedGraph example1 = new DirectedGraph<>(); + DirectedGraph example2 = new DirectedGraph<>(); int size = 5; MarkedVertex[][] vertices = new MarkedVertex[size][size]; @@ -88,7 +99,7 @@ public class ExampleGraphs { name = "Ende"; } vertices[row][col] = new MarkedVertex<>(50 + col * 100, 50 + row * 100, name, null, null); - example1.addVertex(vertices[row][col]); + example2.addVertex(vertices[row][col]); } } @@ -96,36 +107,36 @@ public class ExampleGraphs { for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { if (col < size - 1) { - addBidirectionalEdge(example1, vertices[row][col], vertices[row][col + 1], new EdgeWeightMarking(1)); + addBidirectionalEdge(example2, vertices[row][col], vertices[row][col + 1], new EdgeWeightMarking(1)); } if (row < size - 1) { - addBidirectionalEdge(example1, vertices[row][col], vertices[row + 1][col], new EdgeWeightMarking(1)); + addBidirectionalEdge(example2, vertices[row][col], vertices[row + 1][col], new EdgeWeightMarking(1)); } } } - return example1; - } - - private void addBidirectionalEdge(DirectedGraph graph, MarkedVertex from, MarkedVertex to, EdgeWeightMarking weight) { - MarkedEdge forwardEdge = new MarkedEdge<>("edge" + from.getName() + "_" + to.getName(), from, to, weight); - MarkedEdge backwardEdge = new MarkedEdge<>("edge" + to.getName() + "_" + from.getName(), to, from, weight); - graph.addEdge(forwardEdge); - graph.addEdge(backwardEdge); + return example2; } + /** + * Creates an example graph illustrating two paths from a start node to an end node with different characteristics: + * one path with few nodes and mostly low-weight edges, and another path with more nodes and higher-weight edges. + * The algorithms will alternate exploration between these paths. + * + * @return Directed graph instance for example 3. + */ public DirectedGraph example3() { - DirectedGraph example2 = new DirectedGraph<>(); - /* - * Beispiel 2 zeigt zwei Wege von einem Startknoten zu einem Zielknoten mit unterschiedlichen Eigenschaften: - * Ein Weg (oben) hat wenige Knoten mit Kanten geringer Gewichtung, außer der letzten Kante, die hohe Gewichtung hat. - * 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. + * Beispiel 3 zeigt zwei Wege von einem Startknoten zu einem Zielknoten mit unterschiedlichen Eigenschaften: + * Ein Weg (oben) hat wenige Knoten mit Kanten geringer Gewichtung, außer der vorletzten Kante, die hohe Gewichtung hat. + * Der andere Weg (unten) hat mehr Knoten mit höherer Gewichtung der Kanten. Die Algorithmen wechseln also mit dem Erkunden + * zwischen den beiden Pfaden. * */ + DirectedGraph example3 = new DirectedGraph<>(); + MarkedVertex A = new MarkedVertex<>(100, 100, "Start", null, null); MarkedVertex B = new MarkedVertex<>(250, 50, "B", null, null); MarkedVertex C = new MarkedVertex<>(400, 100, "C", null, null); @@ -134,38 +145,44 @@ public class ExampleGraphs { MarkedVertex F = new MarkedVertex<>(250, 200, "F", null, null); MarkedVertex G = new MarkedVertex<>(550, 200, "G", null, null); - example2.addVertex(A); - example2.addVertex(B); - example2.addVertex(C); - example2.addVertex(D); - example2.addVertex(E); - example2.addVertex(F); - example2.addVertex(G); + example3.addVertex(A); + example3.addVertex(B); + example3.addVertex(C); + example3.addVertex(D); + example3.addVertex(E); + example3.addVertex(F); + example3.addVertex(G); - example2.addEdge(new MarkedEdge<>("AB", A, B, new EdgeWeightMarking(1))); - example2.addEdge(new MarkedEdge<>("BC", B, C, new EdgeWeightMarking(1))); - example2.addEdge(new MarkedEdge<>("CD", C, D, new EdgeWeightMarking(10))); - example2.addEdge(new MarkedEdge<>("DE", D, E, new EdgeWeightMarking(1))); + example3.addEdge(new MarkedEdge<>("AB", A, B, new EdgeWeightMarking(1))); + example3.addEdge(new MarkedEdge<>("BC", B, C, new EdgeWeightMarking(1))); + example3.addEdge(new MarkedEdge<>("CD", C, D, new EdgeWeightMarking(10))); + example3.addEdge(new MarkedEdge<>("DE", D, E, new EdgeWeightMarking(1))); - example2.addEdge(new MarkedEdge<>("AF", A, F, new EdgeWeightMarking(5))); - example2.addEdge(new MarkedEdge<>("FG", F, G, new EdgeWeightMarking(5))); - example2.addEdge(new MarkedEdge<>("GE", G, E, new EdgeWeightMarking(5))); + example3.addEdge(new MarkedEdge<>("AF", A, F, new EdgeWeightMarking(5))); + example3.addEdge(new MarkedEdge<>("FG", F, G, new EdgeWeightMarking(5))); + example3.addEdge(new MarkedEdge<>("GE", G, E, new EdgeWeightMarking(5))); - return example2; + return example3; } - - + /** + * Creates an example labyrinth graph with four horizontal paths, each consisting of four nodes. + * Each path leads to a respective endpoint, demonstrating how algorithms may explore potentially incorrect paths + * before finding the correct one, and showing the efficiency of A* in finding the correct path quickly. + * + * @return Directed graph instance for example 4. + */ public DirectedGraph 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. + * Beispiel 4 zeigt ein Labyrinth mit vier horizontalen Wegen, die jeweils aus vier Knoten bestehen. + * Jeder Weg führt zum Endpunkt E1, E2, E3 bzw. Ende. Ziel ist es zu zeigen, dass die Algorithmen auch + * potenziell falsche Wege erkunden können, bevor sie den Endknoten erreichen. Zudem wird gezeigt, + * wie A* schnell den richtigen Weg findet, während Djkstra alle Wege durchsucht. * */ - DirectedGraph example3 = new DirectedGraph<>(); + DirectedGraph example4 = new DirectedGraph<>(); // Startpunkt A in der Mitte der Y-Koordinate MarkedVertex A = new MarkedVertex<>(100, 250, "Start", null, null); @@ -194,46 +211,59 @@ public class ExampleGraphs { MarkedVertex D4 = new MarkedVertex<>(400, 400, "D4", null, null); MarkedVertex E4 = new MarkedVertex<>(500, 400, "Ende", null, null); // Endpunkt des vierten Weges - example3.addVertex(A); - example3.addVertex(B1); - example3.addVertex(C1); - example3.addVertex(D1); - example3.addVertex(B2); - example3.addVertex(C2); - example3.addVertex(D2); - example3.addVertex(B3); - example3.addVertex(C3); - example3.addVertex(D3); - example3.addVertex(B4); - example3.addVertex(C4); - example3.addVertex(D4); - example3.addVertex(E1); - example3.addVertex(E2); - example3.addVertex(E3); - example3.addVertex(E4); + example4.addVertex(A); + example4.addVertex(B1); + example4.addVertex(C1); + example4.addVertex(D1); + example4.addVertex(B2); + example4.addVertex(C2); + example4.addVertex(D2); + example4.addVertex(B3); + example4.addVertex(C3); + example4.addVertex(D3); + example4.addVertex(B4); + example4.addVertex(C4); + example4.addVertex(D4); + example4.addVertex(E1); + example4.addVertex(E2); + example4.addVertex(E3); + example4.addVertex(E4); - example3.addEdge(new MarkedEdge<>("AB1", A, B1, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("AB2", A, B2, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("AB3", A, B3, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("AB4", A, B4, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("AB1", A, B1, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("AB2", A, B2, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("AB3", A, B3, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("AB4", A, B4, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("B1C1", B1, C1, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("B2C2", B2, C2, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("B3C3", B3, C3, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("B4C4", B4, C4, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("B1C1", B1, C1, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("B2C2", B2, C2, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("B3C3", B3, C3, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("B4C4", B4, C4, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("C1D1", C1, D1, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("C2D2", C2, D2, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("C3D3", C3, D3, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("C4D4", C4, D4, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("C1D1", C1, D1, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("C2D2", C2, D2, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("C3D3", C3, D3, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("C4D4", C4, D4, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("D1E1", D1, E1, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("D2E2", D2, E2, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("D3E3", D3, E3, new EdgeWeightMarking(1))); - example3.addEdge(new MarkedEdge<>("D4E4", D4, E4, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("D1E1", D1, E1, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("D2E2", D2, E2, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("D3E3", D3, E3, new EdgeWeightMarking(1))); + example4.addEdge(new MarkedEdge<>("D4E4", D4, E4, new EdgeWeightMarking(1))); - return example3; + return example4; + } + + /** + * Helper method to add a bidirectional edge between two vertices in a graph. + * + * @param graph The graph instance where the edge should be added. + * @param from The starting vertex of the edge. + * @param to The ending vertex of the edge. + * @param weight The weight marking of the edge. + */ + private void addBidirectionalEdge(DirectedGraph graph, MarkedVertex from, MarkedVertex to, EdgeWeightMarking weight) { + MarkedEdge forwardEdge = new MarkedEdge<>("edge" + from.getName() + "_" + to.getName(), from, to, weight); + MarkedEdge backwardEdge = new MarkedEdge<>("edge" + to.getName() + "_" + from.getName(), to, from, weight); + graph.addEdge(forwardEdge); + graph.addEdge(backwardEdge); } } - - diff --git a/out/production/ProjektGraph/OurApplication/OurApplication.class b/out/production/ProjektGraph/OurApplication/OurApplication.class index e4a10fa..289c516 100644 Binary files a/out/production/ProjektGraph/OurApplication/OurApplication.class and b/out/production/ProjektGraph/OurApplication/OurApplication.class differ diff --git a/out/production/ProjektGraph/graph/ExampleGraphs.class b/out/production/ProjektGraph/graph/ExampleGraphs.class index ed65523..e9feef1 100644 Binary files a/out/production/ProjektGraph/graph/ExampleGraphs.class and b/out/production/ProjektGraph/graph/ExampleGraphs.class differ