FB Informatik Prof. Dr. R.Nitsch Programmieren 2 Future Car Projekt Praktikum 6 - Graphen Reiner Nitsch - Speichern von Graphen -

Slides:



Advertisements
Ähnliche Präsentationen
Vortrag von Stephanie Weirauch Jens Pleger Peter Jancke Frank Wejmelka
Advertisements

Man bestimme den „minimalen aufspannenden Baum“ des Graphen.
Single-Source Shortest Paths: SSSP
Minimum Spanning Tree: MST
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (26-Graphenalgorithmen: Wiederholung und Übung) Prof. Th. Ottmann.
Kapitel 9: Graphdurchlauf
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Graphen Ein Graph ist eine Kollektion von Knoten und Kanten. Knoten sind einfache Objekte. Sie haben Namen und können Träger von Werten, Eigenschaften.
7. Natürliche Binärbäume
Synonyme: Stapel, Keller, LIFO-Liste usw.
Gliederung Motivation / Grundlagen Sortierverfahren
Programmieren 2 Future Car Projekt Praktikum 6 - Graphen
Programmieren 2 Future Car Projekt Praktikum 6
FB Informatik Prof. Dr. R.Nitsch Programmieren 2 Future Car Projekt Reiner Nitsch
Programmieren 2 Future Car Projekt Praktikum 6
WS Algorithmentheorie 13 - Kürzeste (billigste) Wege Prof. Dr. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (20 – Graphen)
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (26 - Graphen) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (27 – Kürzeste Wege) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (17 – Bäume: Grundlagen und natürliche Suchbäume) Prof. Th. Ottmann.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (21 – Kürzeste Wege) T. Lauer.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (22 - Graphen)
Algorithmentheorie 12 – Spannende Bäume minimalen Gewichts
Algorithmen und Datenstrukturen
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 6 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
High Performance = Innovative Computer Systems + Efficient Algorithms Friedhelm Meyer auf der Heide 1 HEINZ NIXDORF INSTITUT Universität Paderborn Algorithmen.
Minimum Spanning Tree: MST
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Vortrag über Graphen Von Jörg Hendricks.
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer Diskrete Mathematik II Vorlesung 1 SS 2001 Algorithmus von Dijkstra.
Effiziente Algorithmen
Effiziente Algorithmen
Effiziente Algorithmen
Diskrete Mathematik II
Effiziente Algorithmen Hartmut Klauck Universität Frankfurt SS
Effiziente Algorithmen Hartmut Klauck Universität Frankfurt SS
Effiziente Algorithmen
Effiziente Algorithmen Hartmut Klauck Universität Frankfurt SS
Effiziente Algorithmen
Effiziente Algorithmen
Effiziente Algorithmen Hartmut Klauck Universität Frankfurt SS
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Animation von Dijkstra
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Informatik 1 Letzte Übung.
Jan Hinzmann – – GIS Praxis II – Slide 1/10 Der Algorithmus von Dijkstra (Berechnung kürzester Wege in bewerteten Graphen) GIS Praxis II, Jan Hinzmann,
Kapitel 8: Graphalgorithmen 8. 1 Grundlagen 8
Kapitel 8: Graphalgorithmen 8. 1 Grundlagen 8
Informatik Datenstruktur Graph 3.3 Durchlaufen von Graphen
Softwareengineering Graphen und Bäume Teil II
Die Tiefensuche Vorgedanke: Die Sage von Theseus und dem Minotaurus
Algorithmen und Datenstrukturen 1 SS 2002
Minimal spannende Bäume
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer Diskrete Mathematik II Vorlesung Datenstrukturen für den Algorithmus von.
Institut für Kartographie und Geoinformation Prof. Dr. Lutz Plümer Diskrete Mathematik II Vorlesung Suche des kürzesten Weges in einem Netz.
Programmiersprachen II Fortsetzung Datenstrukturen Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Programmiersprachen II Vorbesprechung Klausur Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Programmiersprachen II Graph_Algorithmen Einführung Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Adiazenzmatrix des Graphen
Der Dijkstra-Algorithmus
Übungen Übungsanmeldung Übungskorrektur
3. Die Datenstruktur Graph 3.3 Durchlaufen von Graphen
 Präsentation transkript:

FB Informatik Prof. Dr. R.Nitsch Programmieren 2 Future Car Projekt Praktikum 6 - Graphen Reiner Nitsch - Speichern von Graphen - Traversieren von Graphen - Kürzeste Wege

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 2 Darstellung von Graphen als Array von Listen Grundlagen zu Graphen (siehe Vorlesung Mathematik 1) Ungerichteter Graph G(V,E) V: Knotenmenge E: Kantenmenge Gerichteter Graph Bietet Antwort auf Fragen zu Graphen G wie z.B. Speicherbedarf? proportional zur Anzahl Knoten plus Anzahl Kanten O(|V|+|E|) Wieviele Kanten enden an v i ? Welche Nachbarn v j hat v i ? Existiert Kante E=(v i,v j )? O(|E i |) Gewichteter Graph: Gewicht als zu- sätzliche Info der Listenelemente Adjazenzlisten Die mit Knoten 5 verbunden Nachbarknoten (= Kantenmenge E 5 ) Array von Adjazenzlisten

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 3 Darstellung von Graphen mit Adjazenzmatrix Adjazenzmatrix a mit Elementen aij a ij = 1 wenn Kante E=(v i,v j ) in G enthalten, sonst a ij = Ungerichteter Graph G(V,E) a ij = a ji (symmetrisch) Gerichteter Graph G(V,E) a ij a ji (unsymmetrisch) Bietet Antwort auf Fragen zu Graphen G wie z.B. Welche Kanten enden an v i ? Welche Nachbarn v j hat v i ? Existiert Kante E=(v i,v j )? O(1) Speicherbedarf? O(|V| 2 ) ungünstig wenn G wenige Kanten hat Gewichteter Graph: Gewicht an Stelle von '1' in Matrix eintragen i j

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 4 Adjazenzliste des Graphen der FutureCar World 4,7 7,7 Adjazenzlisten Rasterkarte (Grid) von FC-City Rasterkarte von FC-City mit XY-Koordinaten Graph zur Modellierung der Erreichbarkeitsbeziehungen zwischen den Zellen der Rasterkarte Anmerkung: Wenden ist nicht vorgesehen ,56,5 7,5 5,66,67,6 5,76,77,7 5,86,87,8 5,46,4 7,4 5,96,9 7,9 8,5 8,6 8,7 8,8 8,4 8,9 3,5 3,6 3,7 3,8 3,4 3,9 4,5 4,6 4,7 4,8 4,4 4,´9 #### # # # # # # # # # # ## # # # # # # # # # # # # # # # # # # # # # # 5,86,5 5,5 5,8 4,67,7 7,6 4,6 6,55,8 6,8 6,5 7,74,6 3,7 4,7 4,6 3, Adjazenzlisteninfo als Textsequenz 5

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 5 Implementierungsempfehlungen Empfehlungen: Container zum Verwalten der Knoten? Knoten in Container einfügen? Was sollte in den Adjazenzlisten gespeichert werden? Welcher Datentyp eignet sich für Route? map nodes nodes[ loc ] = Node(…) Location oder Adressen der Nachbarknoten. Verwendbarkeit im Navi sicherstellen (Siehe Praktikum 5) Adjazenzlisten 4,7 7,7 5,86,5 5,5 5,8 4,67,7 7,6 4,6 6,55,8 6,8 6,5 7,74,6 3,7 4,7 4,6 3,6 Node + loc + adjList + Konstruktor: 5,5 4,67,75,8 Graph - nodes:Node[ ] + Graph(filename:string) + … 1 1..N

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 6 Traversieren von Graphen Als Traversieren bezeichnet man das systematische Besuchen aller Knoten und das Durchlaufen jeder Kante eines Graphen. Algorithmen zum Traversieren eines Graphen dienen als Basis für viele andere grundlegende Algorithmen zur Verarbeitung von Graphen Man unterscheidet zwischen –Breitentraversierung (breadth-first search, BFS): Die Knoten werden geordnet nach der "Entfernung" von einem Startknoten durchlaufen zuerst alle Knoten mit 1 Kantenlänge Abstand vom Startknoten danach alle diejenigen Knoten mit Abstand 2, danach die mit Abstand 3, usw. –Tiefentraversierung (depth-first search, DFS): Dieser Algorithmus erhöht immer zuerst die Distanz vom Startknoten, bevor er in die Breite geht und Nachbarknoten mit gleicher Distanz besucht (meist rekursiv implementiert) Bereits besuchte Knoten müssen markiert werden, weil sich die Algorithmen sonst in den Kreisen des Graphen verlieren. Node + loc:Location + adjList + visited:bool + Konstruktor: Markierung

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 7 Tiefentraversierung (Rekursiv) Rekursiver Algorithmus (in Pseudocode), der ausgehend von einer unmarkierten Ecke v i, alle anderen Knoten v j, j!=i eines Graphen G (genauer: einer Komponente desselben) besucht Funktion: traverse-dfs(v) Zweck: Tiefensuche in einem Graphen Parameter v: Ecke bei dem die Suche beginnt PRE: --- POST: Alle Ecken, die von v erreichbar sind, sind gefunden. Markiere v als besucht Bestimme einen Nachbarknoten von v und nenne diesen vnext WHILE(vnext existiert UND noch nicht besucht ist) beginne weitere Tiefensuche bei vnext Wieder zurück, bestimme weiteren Nachbarknoten von v und nenne diesen wieder vnext END WHILE Node + loc:Location + adjList + visited:bool + Konstruktor: procedure traverse-dfs(v) visited(v) := true vnext := adjList[v] WHILE( exist(vnext) AND NOT visited(vnext)) traverse-dfs(vnext) vnext := succ(vnext) END WHILE Algorithmus in Umgangssprache Algorithmus in kompakter selbst- erklärender, leicht merkbarer Syntax (Programmiersprachenunabhängig)

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 8 Beispiel zur Tiefentraversierung Adjazenzlisten von Seite 2 Alle Knoten und Kanten besucht! Startknoten (willkürl.) Komplexität: O(|V|+|E|) procedure traverse-dfs(v) visited(v) := true vnext := adjList[v] WHILE( exist(vnext) AND NOT visited(vnext)) traverse-dfs(vnext) vnext := succ(vnext) END WHILE 2 5

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 9 Tiefentraversierung (Iterativ) Iterativer Algorithmus mit einem Stack, der ausgehend von einer unmarkierten Ecke v i, alle anderen Knoten v j, j!=i eines Graphen G besucht. PRE: --- POST: Alle Ecken, die von v erreichbar sind, sind markiert. procedure traverse-dfs(v) t := empty-stack// t ist ein lokaler Stack visited(v) := true// markiere v als besucht push(t,v)// lege v auf den Stack WHILE NOT empty(t) DO { v := top(t)// hole oberstes Element aus Stack vnext := adjList[v]// hole ersten Nachbarknoten WHILE exist(vnext) AND visited(vnext) DO // schon besucht? vnext := succ(vnext) // Ja! Dann eben den Nächsten END WHILE IF exist(vnext) THEN // Noch einen Unbesuchten gefunden? visit(vnext)// diesen besuchen (und bearbeiten), visited(vnext) := true// als "besucht" markieren und push(t,vnext)// Erst mal auf den Stack damit... ELSE DO pop(t) END IF END WHILE// Erledigt! Alle Nachbarn von v besucht } … und hier schon wieder runter!

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 10 Breitentraversierung Iterativer Algorithmus, der alle Knoten eines zusammenhängenden Graphen geordnet nach der Entfernung vom Startknoten v durchläuft. –Zuerst werden alle vom Startknoten über 1 Kante erreichbaren Knoten besucht –Danach alle über mindestens 2 Kanten erreichbaren Knoten, usw. –Entsteht formal aus iterativer Tiefentraversierung, wenn der Stack zu einer Queue wird. PRE:--- Post:Alle Knoten, die von v erreichbar sind, sind markiert, also besucht worden procedure bfs_node(v) t := empty-queue// Definition einer leeren lokalen Queue visited(v) := true// Starknoten v als "besucht" markieren enqueue(t,v) WHILE NOT empty(t) DO v := front(t)// vordersten Knoten in t lesen vnext := adjList[v]// hole ersten Nachbarknoten WHILE exist(vnext) AND visited(vnext) DO// schon besucht? vnext := succ(vnext)// Ja! Dann eben den Nächsten END WHILE IF exist(vnext) THEN// Noch einen Unbesuchten gefunden? visit(vnext)// diesen besuchen (und bearbeiten), visited(vnext) := true// als "besucht" markieren und enqueue(t,vnext)// erst mal in queue einreihen, wo sie bis zur // Bearbeitung ihrer Nachbarknoten warten ELSE DO dequeue(t)// Erledigt! Alle Nachbarn von v wurden besucht END IF END WHILE Die Änderungen gegenüber der Tiefensuche sind ROT markiert!

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar procedure bfs_node(v) t := empty-queue visited(v) := true enqueue(t,v) WHILE NOT empty(t) DO v := front(t) vnext := adjList[v] WHILE exist(vnext) AND visited(vnext) DO vnext := succ(vnext) END WHILE IF exist(vnext) THEN visit(vnext) visited(vnext) := true enqueue(t,vnext) ELSE dequeue(t) END IF END WHILE Beispiel zur Breitentraversierung Alle Knoten und Kanten besucht! Startknoten Adjazenzlisten von Seite t: Queue Jetzt sind alle Knoten mit Distanz "1Kante" zum Startknoten besucht

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 12 Kürzeste Wege mittels Breitensuche Gesucht ist eine Verbindung (Pfad) zwischen 2 Knoten: –Tiefensuche liefert eine entsprechende Kantenfolge, wenn es eine gibt (aber nicht unbedingt die Kürzeste). –Breitensuche liefert garantiert die Kürzeste. Aufgabe Mit Hilfe eines Breitensuchverfahrens soll der kürzeste Weg in einem ungewichteten Graphen G vom Startpunkt src zum Zielknoten dest gefunden werden, der über die geringste Anzahl von Kanten verläuft. Dabei wird der Weg so codiert, dass man ihn hinterher rekonstruieren kann. Lösung –Die Breitentraversierung durchläuft alle Knoten geordnet nach der Kantendistanz zu src. –Der Vorgängerknoten, von dem ausgehend der Knoten v betreten wird, verbindet somit v auf dem kürzesten Wege mit src (keine Kantengewichte!). –Im Bearbeitungsschritt merkt sich der Knoten v daher seinen Vorgängerknoten –Nachdem Knoten dest betreten wurde und dieser sich seinen Vorgängerknoten gemerkt hat, ist die Suche beendet. –Der kürzeste Weg, der dest mit src verbindet, ergibt sich nun, indem man, beginnend bei dest, die Folge der Vorgängerknoten rekonstruiert. –Rückwärts gelesen ( std::reverse ) ergibt diese Folge den kürzesten Weg.

FB Informatik Prof. Dr. R.Nitsch Projekt FutureCar 13 Breitensuche des Knotens d ausgehend vom Startknoten s PRE:exist(s), exist(d) POST:Alle Knoten, die von v erreichbar sind, sind markiert, also besucht worden FUNCTION bf_search(s,d) t := empty-queue// Definition einer leeren lokalen Queue visited(s) := true// Starknoten v als "besucht" markieren pred(s) := nil// s kennt seinen Vorgänger noch nicht enqueue(t,s) WHILE NOT empty(t) AND front(t)!=d DO // Abbruch der Suche wenn d besucht v := front(t)// vordersten Knoten in t lesen vnext := adjList[v]// hole ersten Nachbarknoten WHILE exist(vnext) AND visited(vnext) DO vnext := succ(vnext)// Bereits besuchte Knoten überspringen END WHILE IF vnext != nil THEN// Solange unbesuchte Nachbarknoten zu v existieren visit(vnext)// diese besuchen (und bearbeiten), pred(vnext) := v// Vorgänger merken (besuchen & bearbeiten) visited(vnext) := true// als solche markieren und enqueue(t,vnext)// in queue einfügen, wo sie bis zur Bearbeitung // ihrer Nachbarknoten warten ELSE DO dequeue(t)// entferne vorderstes Element aus t END IF// Alle Nachbarn dieses Knotens sind besucht IF empty(t) THEN { kein Pfad von s nach d } Ergänzungen zum vorherigen Algorithmus sind ROT markiert Node + loc:Location + adjList + pred + visited:bool + Konstruktor: Verweis auf Vorgängerknoten

FB Informatik Prof. Dr. R.Nitsch Implementierung der Wegesuche mittels Breitentraversierung Projekt FutureCar 14 std::list & Graph::bfSearchForShortestPath( const Location& src, const Location& d, std::list & route ) { if( world.getTrait(src)==NOTTRAVERSABLE ) // PRE: src is TRAVERSABLE throw "RUNTIME_ERROR GraphUnweighted::bfSearchForShortestPath PRE s"; if ( world.getTrait(d)==NOTTRAVERSABLE ) // PRE: dest is TRAVERSABLE throw "RUNTIME_ERROR GraphUnweighted::bfSearchForShortestPath PRE d"; std::list t; // t := empty-queue (contains addresses of neighbors) nodes[s].pred = &nodes[s]; // pred(s) := nil (std::map nodes) nodes[s].visited = true; // visited(s) := true t.push_back( &nodes[s] ); // enqueue(t,s) while( !t.empty() && !(t.front()->loc==d) ) // WHILE NOT empty(t) AND front(t)!=d DO { Node* v = t.front(); // v := front(t) // Get adjacencylist for node v std::list & v_neighbors = nodes[v->loc].adjNodePointerList; std::list ::iterator iter = v_neighbors.begin(); // vnext := adjList[v] // Find neighbor not yet visited while( iter!=v_neighbors.end() ) { // WHILE exist(vnext) if( !(*iter)->visited ) { // AND NOT visited(vnext) DO Node* vnext = *iter; vnext->visited = true; // visited(vnext) := true vnext->pred = &nodes[v->loc]; // pred(vnext) := v Vorgängerknoten merken t.push_back(vnext); // enqueue(t,vnext) } ++iter; // AND visited(vnext) DO } // END while t.pop_front(); // ELSE DO dequeue(t) } // Fortsetzung nächste Seite

FB Informatik Prof. Dr. R.Nitsch Path-Container mit Knotensequenz des kürzesten Weges füllen // 1. dest in Path-Container für Location-Objekte schreiben // 2. v=dest // 3. In nodes das mit v assoziierte Node -Objekt suchen und den Vorgängerknoten pred(v) ermitteln // 4. pred(v) in Path-Container speichern // 5. Solange 2. bis 4. wiederholen, bis pred(v)==src // 6. Falls die Knotenreihenfolge im Container dest -> src ist, diese noch umdrehen: src -> dest // 7. Die Knotensequenz in eine Folge von Navi-Kommandos ( GOAHEAD3, GOAHEAD1, GORIGHT, GOLEFT, TURN ) übersetzen. // Die Route ist berechnet … Projekt FutureCar 15