So, guten Morgen. Kannst du mich hören? Sehr
gut. So. Bevor wir anfangen, muss ich Ihnen kurz
was zum Übungszettel erzählen. Es ist ein kleiner Fehler unterlaufen
. Sie haben wahrscheinlich alle viel gegrübelt über die Aufgabe 1E.
Da ging es um diese Wegesuche. Und ja, also
da fehlte eine Information. Uns interessierten nämlich nur die Wege,
die über die Wurzel gingen. Ja, tut mir leid.
Also wir haben, als wir die Aufgabe gestellt haben,
haben wir die ganze Zeit über die Suchbäume nachgedacht.
Und da fangen die Wege immer bei der Wurzel an.
Deswegen steht es da explizit nicht drin
Und die Aufgabe ist, ohne diese Informationen, sagen wir mal, schwer lösbar.
Genau genommen weiß ich auch nicht, wie das geht.
Okay, also wir haben ungefähr, wir haben ungefähr 30
Prozent Lösungen von Ihnen, die das richtig interpretiert haben.
Also die haben diese fehlende Information,
sich irgendwie wahrscheinlich auch gedacht und haben quasi das gemacht,
dass sie immer die Wege von der Wurzel ausgenommen haben.
Und wir haben noch eine andere Tranche von Abgaben,
wo der Weg einfach unter der Annahme berechnet wurde,
dass die zwei Knoten vorgegeben wurden, A und B,
dann ist die Aufgabe natürlich sehr einfach.
Da muss man einfach nur zur Wurzel laufen. Das war
definitiv nicht gemeint und meiner Meinung nach auch nicht so zu verstehen,
aber das ist eine andere Geschichte. Was wir jetzt machen,
ist, also sie kriegen Punkte für diese Aufgabe,
also wenn sie hier eine Lösung präsentiert haben,
kriegen sie Punkte dafür, das steht auf dem Zettel,
die drei Punkte, die diese Aufgabe gebracht hätte,
zählen nicht zu der 100-Prozent-Marke.
Das heißt, die, die da was abgegeben haben,
haben das als Bonuspunkte und die,
die nichts abgegeben haben, Und alles andere richtig haben,
haben trotzdem 100 Prozent auf dem Zettel.
Okay. So, das ist zu der Aufgabe und wir
werden uns bemühen, dass das natürlich nicht mehr vorkommt.
Aber ab und zu, das ist bei diesen Algorithmenaufgaben,
man denkt da 100 mal drüber nach, dass man genau präzise formuliert.
Sie wissen alle, wie wichtig das ist,
dass man präzise formuliert und uns passiert das dann eben auch ab und zu mal.
So, okay. So, das war zu dem Übungszettel
. Und jetzt reden wir heute über Grafen. Ich habe
auf der, in der letzten Vorlesung des Kapitel eingeleitet.
Wir haben schon so eine ganze Reihe von wichtigen Definitionen
gesehen zum Thema Agrafen
Heute werden wir anfangen, uns mit den Grafen algorithmisch zu beschäftigen. Ja,
also das,
was Sie in der letzten Vorlesung zu dem Thema gesehen haben,
da war wahrscheinlich auch viel Wiederholung für Sie drin,
also in der Mathematik begegnen Sie den Grafen ja auch,
also in der diskreten Mathematik zum Beispiel.
Und ja, das ist sozusagen der Stand, bei dem wir sind.
Und jetzt werden wir algorithmisch uns mit den Grafen beschäftigen und
einige Verfahren darauf entwickeln. Wir beginnen erst mal mit ungerichteten
Grafen und wir werden jetzt eine Sache anders machen als bisher.
Bisher habe ich Ihnen immer irgendein Problem,
wo ich ihnen irgendwie eine Anwendung erzählt habe,
wo ich sage, das ist da wichtig.
Und diese Fragestellung wollen wir lösen. Und dann haben wir
versucht, die zu lösen. Jetzt werden wir es erstmals
anders vorgehen. Wir werden erst mal einen Algorithmus entwickeln,
der, naja, eine spezielle Strategie verfolgt,
ohne dass wir zunächst einmal genau wissen, warum wir das tun,
ohne auch eine spezielle Anwendung im Kopf zu haben.
Und wir werden dann nachher sehen, dass wir dieses Verfahren,
also diese Strategie einfach nutzen können, zur Lösung verschiedener Probleme.
Wir haben bei den Bäumen, einem Einführungsteil der Bäume,
schon mal gesehen, dass es sinnvoll ist,
eine Strategie zu haben, wie man diese Bäume systematisch durchläuft.
Da haben wir In-Order, Pre-Order und Post-Order
Traversal gesehen in den Bäumen. Das waren also Algorithmen,
mit denen wir einfach nur systematisch die Bäume betrachtet haben.
Diese Algorithmen waren auch so. Die haben erst mal
keine ganz konkrete Frage beantwortet. Die haben nur gesagt,
wie wir systematisch diese Knoten besuchen können.
Und in dieser Art und Weise werden wir es jetzt auch machen.
Wir werden uns erst mal Verfahren überlegen,
wie wir systematisch die Knoten besuchen können in einem solchen Grafen.
In dem Grafen ist es noch ein bisschen schwieriger,
als in einem Baum im Allgemeinen
Weil wir haben ja hier so ein ganzes Geflecht von Kanten
und wir haben keine Hierarchien von einer Wurzel nach unten.
Jeder Knoten ist irgendwie gleichwertig. Und wir müssen irgendwie überlegen,
wie wir da systematisch einfach alles anschauen.
Dazu gibt es in der Informatik zwei ganz zentrale Strategien.
Die Strategien heißen Breitensuche und Tiefensuche. Und die beiden werde ich
Ihnen heute vorstellen. Und wir beginnen mit der Breitensuche.
Die Breitensuche ist ein Verfahren, wo wir quasi uns
einen beliebigen Knoten aussuchen
Und von dem aus den Graphen schrittweise explorieren.
Sie können sich das so vorstellen, sie kommen mit dem Zug
in eine fremde Stadt gefahren, die sie nicht kennen.
Und dann landen sie ja am Hauptbahnhof. Das ist der
erste Ort, wo sie ankommen. Sie kennen die Stadt nicht,
sie kennen sich nicht aus. Und die Frage ist,
wenn sie jetzt das Ziel hätten, was sie wahrscheinlich haben,
aber wenn sie das Ziel hätten, systematisch die Stadt zu erkunden,
wie würden sie vorgehen, wenn sie sich hundertprozentig sicher sein wollen,
dass sie keine Straßenkreuzung, keine Straße auslassen dabei.
Und das ist nicht so einfach,
weil von hier gibt es wahrscheinlich verschiedene Straßen,
denen sie folgen können zu anderen Plätzen Kreuzung und von da gibt es natürlich auch wieder andere Straßen,
die dann weiter in das Stadtnetz hineinführen.
Die Breitensuche ist ein Verfahren, wo wir ausgehen von einem Knoten,
quasi immer zuerst die Knoten betrachten, die möglichst nah an diesem Ort heranliegen.
Also wenn das hier jetzt weitergeht,
würden wir von hier aus erstmal diese Knoten betrachten,
die wir mit einer Kante erreichen können und würden dann versuchen,
in dem nächsten Schritt die Knoten zu betrachten,
die wir dann mit zwei Kanten erreichen können und so weiter.
So würden wir gerne vorgehen. Das ist natürlich noch keine
algorithmische Beschreibung. Also wir haben hier nur eine grobe Strategie,
was wir gerne tun möchten
Wir müssen uns jetzt irgendwie überlegen, wie wir das machen wollen.
Und das ist nicht so einfach, weil, okay,
von unserem Hauptbahnhof aus können wir die Addizenzliste betrachten und von
der Addizenzliste wissen wir dann, welches die Nachbarn sind.
Die Nachbarn, der Nachbarn sind dann natürlich die Knoten,
die zu diesen Knoten,
die wir in der ersten Runde betrachtet haben,
wiederum benachbart sind, also in der Addizenzliste stehen.
Aber wir müssen uns die irgendwie alle merken,
die hier sind, die wir noch betrachten müssen.
Das machen wir mit einer Warteschlange und die Gesamtstrategie sieht dann einfach
wie folgt aus. Wir brauchen irgendwie was zu markieren,
also wir müssen uns irgendwie merken,
an welchem Platz wir
schon mal waren
Das machen wir, indem wir diesen Farbenknoten,
indem wir diesen Knoten Farben geben.
Und unsere Farben sind hier weiß, grau und schwarz.
Das ist nicht besonders bunt. Es hat lediglich damit
zu tun, dass Lehrbücher in schwarz-weiß gedruckt werden.
Deswegen sind die weiß-grau und schwarz. So, also,
am Anfang ist unser kompletter Graf Weiß. Jeder Knoten ist
weiß. Das sind die weißen Flecken auf der Landkarte.
Alles, was sie noch nicht gesehen haben, ist zu
Beginn erstmal weiß. Wenn Sie einen Knoten besucht haben,
den erstmalig gesehen haben, dann wird der Knoten grau.
Sie markieren ihn als etwas,
was sie betrachtet haben
Dieser Knoten hat jetzt potenziell noch weitere Nachbarn, die sie
noch nicht betrachtet haben. Deswegen ist er erstmal nur grau
. Wenn Sie alle Nachbarn dieses Knotens auch betrachtet haben,
wird im nächsten Schritt dieser Knoten schwarz.
Also er durchläuft, während der Algorithmus den Grafen bearbeitet,
durchläuft jeder Knoten die Farben von weiß, über grau zu schwarz.
Weiß heißt, ich habe ihn noch nicht betrachtet. Grau heißt,
ich habe ihn betrachtet, aber er hat noch Nachbarn,
die ich nicht betrachtet habe. Und schwarz bedeutet,
ich habe ihn betrachtet und alle Nachbarn habe ich auch schon gesehen.
Alles, was schwarz ist, müssen sie sich nicht mehr angucken.
Damit sind sie ganz fertig. Was grau ist,
muss sie sich vielleicht nochmal angucken,
weil sie müssen ja noch zu den Nachbarn gehen von
da aus
Das ist der Hintergedanke. Okay, alle Knoten wären zunächst weiß markiert,
zum Zeitpunkt der ersten Entdeckung werden diese Grau gefärbt, markiert.
Die Knoten werden schwarz, wenn alle Adjazentenknoten bereits entdeckt wurden.
Das heißt, wenn die Nachbarknoten alle nicht mehr weißen.
Wir beginnen an einem beliebigen Knoten. S, den können wir nicht
festlegen, jeder Knoten in einem Graf ist erstmal gleich.
Es gibt keine ausgezeichnete Wurzel wie beim Baum.
Also wir beginnen also bei einem Knoten, der heißt S,
den nennen wir hier S, sie können sich merken,
wie Startknoten oder im Englischen ist es eigentlich häufig die Source.
Also da, wo man anfängt, So,
und dann machen wir jetzt folgendes.
Jetzt kommt die Strategie. Also jetzt über,
entscheiden wir, wie besuchen wir jetzt die Nachbarn?
Wir machen jetzt folgendes. Wir besuchen in einer Schleife,
also iterativ, die jeweils noch nicht besuchten Nachbarn von diesem Knoten S,
sagen, okay, welche davon sind noch weiß und die besuchen wir jetzt der Reihe nach.
Und was wir dann machen, ist,
dass wir im nächsten Schritt uns diese Nachbarn vornehmen und dann die Nachbarn der Nachbarn besuchen.
Damit wir keine Knoten vergessen, müssen wir eine Warteschlange haben,
wo wir alle Knoten ablegen, die quasi schon zwar einmal betrachtet wurden,
aber die noch Nachbarn haben, die wir noch nicht betrachtet haben.
Das heißt,
wir haben eine Warteschlange
Wenn wir das so machen, dann gibt es immer einen speziellen Zeitpunkt,
wo so ein Knoten seine Farbe von weiß nach grau wechselt.
Also der hier, der ist jetzt schon grau hier, ja.
Und irgendwann betrachten wir von dem hier diese Kante, nach hier zum Beispiel,
der ist jetzt noch weiß und dann wird der auch grau, ja.
Diese beiden Knoten, die betrachten wir in einem speziellen Verhältnis zueinander,
die bezeichnen wir als zueinander stehen in einer Vorgängernachfolgerrelation, ja.
Dieser Knoten, von dem aus wir diesen Knoten das erste Mal gesehen haben,
ist entsprechend der Vorgänger. Also wenn wir diese Kante betrachten,
Und diese, während wir diese Kante, oh,
die ist nicht gerichtet, während wir diese Kante betrachten,
wird der Knoten ihr Weiß gefärbt und der sei im AU und der heißt V,
dann ist V der Vorgänger von U. Wenn wir das so machen,
dann sehen wir sofort, dass die Kanten,
die wir verwenden, einen Baum darstellen.
Die müssen einen Baum darstellen, weil jeder Knoten wird
nur einmal seine Farbe von Weiß nach Grau wechseln.
Also der kann nicht wieder von Grau zurück nach Weiß und
dann wieder von Weiß nach Grau, der geht nur,
der ist am Anfang weiß und irgendwann wird der einmal grau und in dem Augenblick,
wo er einmal grau wird, entscheiden wir,
wer der Vorgänger ist.
Und deswegen können keine Zyklen entstehen. Deswegen ist es auf
alle Fälle ein Baum. Das ist ein ganz wichtiger Baum,
das ist der BFS-Baum, also der Baum,
der zur breiten Suche gehört, der breiten Suchbaum oder der Bread-First-Search-Baum, Tree.
Und zwar ist das ein Baum, der als Wurzel den Startknoten hatte.
Es war der Knoten hier, wo wir losgelaufen sind.
Okay, was wir noch machen während der Algorithmus arbeitet,
werden wir für so einen Knoten hier einen Wert berechnen
und zwar D von
Und das bezeichnen wir als Distanz. Das ist erstmal für uns
nur eine Zahl. Und was wir einfach machen ist,
immer dann, wenn wir diesen Knoten entdecken, dann gucken wir,
was hat denn der Vorgängerknoten hier für eine Distanz?
Und wir definieren das D von U als D von V plus 1. Wir sagen,
das ist eins der D-Wert ist eins größer als der des Vorgängers.
Und der erste Knoten hier, der hat den D-Wert,
der hat den D-Wert 0. D von S ist gleich null
am Anfang.
Okay,
so gehen wir vor
Distanz hier, die suggeriert schon etwas, was wir damit berechnen wollen,
nämlich die Pfadlänge von der Wurzel bis zu irgendeinem Knoten in dem Baum.
Wir sehen hier, das wäre die Pfadlänge Null,
der Knoten hätte dann die Pfadlänge eins, der hätte zwei.
Das Gefährliche hier dran im Moment ist,
wir haben angegeben, wie wir die D-Werte berechnen,
aber ob das wirklich die Distanz ist, haben wir nicht gezeigt.
Und die Gefahr ist auch ein bisschen,
ich nenne das jetzt hier so,
damit sie ein Gefühl dafür haben, warum wir das überhaupt machen.
Aber sie müssen jetzt im Hinterkopf haben, es ist erstmal
nur eine Zahl, die wir für einen Knoten berechnen.
Und wir müssen noch zeigen,
dass das tatsächlich
diese Pfadlänge auch entspricht
So, okay, hier ist der Algorithmus.
Der ist schnell erklärt. Wir haben eine Vorschleife,
die betrachtet am Anfang alle Knoten des Graphens,
also für jeden Knoten U aus der Knotenmenge V unseres Graphens,
ohne den Startknoten, den betrachten wir nicht.
Der ist gegeben als Eingabe, machen wir Folgendes.
Wir haben ein Attribut des Knotens U, das ist Color
für die Färbung und den setzen dieses Attribut setzen wir auch weiß.
Alle Knoten sind am Anfang weiß. Dieser D-Wert,
den kennen wir nicht und den, da schreiben wir ein unendlich rein.
Wir werden später sehen, warum das sinnvoll ist,
dort unendlich hineinzuschreiben
Offensichtlich können wir nicht null reinschreiben, weil null würde ja bedeuten,
das ist der Startknoten ist. Das wollen wir natürlich nicht
. Und irgendeine endliche Zahl können wir auch nicht reinschreiben,
weil dann würden wir ja so tun, als hätten wir das schon ausgerechnet.
Wir kennen das ja nicht. Im Moment schreiben wir erst mal unendlich rein.
Und dann haben wir noch ein zweites Ergebnis, was wir berechnen,
das ist die Vorgängerrelation, das ist Pi, ja,
und Pi von U zeigt auf einen anderen Knoten,
und zwar auf den Vorgänger.
Ja, also Pi von diesem U würde auf V zeigen,
also den Knoten, den wir von dem aus WU
das erste Mal gesehen haben.
Diese beiden Werte werden wir berechnen,
während der Algorithmus läuft,
für jeden Knoten
So, jetzt haben wir noch den Startknoten, für den gelt
ein bisschen andere Regeln. Der ist grau, weil,
naja, da sind wir jetzt angekommen, mit dem fangen wir an.
Der ist grau, den haben wir jetzt besucht.
Und der hat einen D-Wert von null. Ja,
den setzen wir so. Und der hat einen P-Wert,
das muss ein Essen, P von S gleich Nil. Also,
das heißt, der hat auch keinen Vorgänger zum jetzigen Zeitpunkt,
weil das ist ja der erste Knoten, wo wir anfangen,
der kann keinen Vorgänger haben.
So, jetzt haben wir den Startknoten hier initialisiert.
Jetzt haben wir eine Warteschlange, Kuh, am Anfang leer,
da stehen noch gar keine Knoten drin.
Und das erste, was wir machen, ist,
wir hängen unseren Startknoten in diese Warteschlange rein.
Das ist der Knoten, den wir jetzt bearbeiten wollen.
Hier passiert quasi, das war alles Initialisierung von 1 bis
8 und hier Abzeile 10, hier runter.
Da ist sozusagen die eigentliche Breitensuche, der eigentliche Breitensuchalgorithmus.
Der funktioniert wie folgt. Wir haben eine Wildschleife, oh,
hier ist noch ein Duo, das muss auch weg.
Wir haben eine Wildschleife, die so lange läuft,
wie die Warteschlange nicht leer ist. Und wir machen dann Folgendes,
wir holen es aus der Warteschlange, den ersten Knoten raus,
den vordersten Knoten und den speichern wir in der Variablen
Dann haben wir eine Vorschleife und betrachten in der Vorschleife,
alle kannten aus der Alterzenzliste, die benachbart, also die an U-Inzidenz sind.
Das heißt, wir gehen zu allen Nachbarn,
also vor eJV, das ist jetzt ein Nachbar,
der in der Atjatizenzliste von U gespeichert ist.
Die betrachten wir alle. Und jetzt gucken wir,
ob dieser Nachbarkloten V noch weiß ist, wenn er noch
weiß ist, haben wir den vorher noch nicht betrachtet.
Dann betrachten wir ihn jetzt zum ersten Mal. Wir werden
diesen Knoten jetzt grau färben wohnen wir initialisieren sein D und seinen P-Wert.
Also D von V wird initialisiert als D von U plus 1.
Also wir sagen, der ist jetzt eine Kante weiter weg von
unserem Startknoten wie der Knoten U. Und das P hier,
der Vorgänger von V, wird gesetzt auf U. Wir sagen,
also wir sind von U aus zu diesem Knoten V gelangt.
Okay, so, was wir dann auch machen,
ist, dieser Knoten ist ja jetzt grau geworden.
Den haben wir zwar betrachtet, aber der hat ja potenziell
noch Nachbarn, die wir noch nicht betrachtet haben.
Deswegen müssen wir uns den Knoten merken,
damit wir den später noch abarbeiten können.
Und deswegen hängen wir den an diesem Schritt
in die Warteschlange hinein
Ja, also mit dem NQ hängen wir den Knoten V in die Warteschlange ein.
Und irgendwann später wird in dieser Waldschleife dieser Knoten
wieder extrahiert und bearbeitet. Wenn diese Vorschleife abgeschlossen ist,
dann haben wir alle Nachbarn von U betrachtet.
Einige von denen waren weiß, andere waren vielleicht grau,
andere waren, nee, schwarz waren die nicht,
aber grau können sie schon gewesen sein.
Und die haben wir alle bearbeitet. Und wenn wir damit fertig sind,
dann sagen wir, okay, die ganzen Nachbarn sind grau,
wir haben den Knoten vollständig abgearbeitet,
dieser Knoten wird jetzt schwarz gefährt
Ja. So, jetzt habe ich gerade so zwischendurch gesagt,
naja, die Knoten, die können weiß sein,
die könnten natürlich auch grau sein,
aber die können nicht schwarz sein.
Warum können die nicht schwarz sein? Warum sind die Idee,
warum die nicht schwarz sein können?
Wenn ich hier die Atjazenzliste von dem Knoten U betrachte,
ja, dann sehe ich eine Reihe von Knoten.
Diese Knoten V. Und die können ja irgendeine Farbe haben,
weißgrau oder schwarz. Wenn sie weiß, dann haben wir
sie noch nicht gesehen, dann färben wir sie grau.
Sie könnten auch grau sein,
aber sie können nicht schwarz sein.
Warum können sie nicht
schwarz sein
Ja, also Vorschlag war,
es hat was mit der Richtung zu tun,
dass man ja von innen nach außen,
aber dieses innen nach außen ist natürlich so ein Argument,
das ist jetzt eine bildliche Vorstellung, die wir hier haben,
aber es ist im Kern,
im Kern ist es richtig, was meinen Sie?
Ja, Aber der Knoten kann ja in der Zwischenzeit,
sie müssen jetzt nicht das vorstellen,
diese Knoten werden ja in dieser Wildschleife irgendwie parallel alle bearbeitet.
Der ist irgendwie grau, dann werden die hier grau und dann
werden die Nachbarn grau, dann wird hier der schwarz.
Das heißt, die haben alle so einen Zustand,
wo sie irgendeine Farbe haben.
Noch einen Vorschlag.
Genau, das ist das exakte Argument, was man hier am Algorithmus ablesen kann,
warum der nicht schwarz sein kann. Wenn der Knoten schwarz wäre,
dann hätten wir alle Nachbarn in der Vorsteife bearbeitet,
denn nur danach wird der schwarz und dann wäre der Knoten,
den wir gerade betrachten, schon grau und dann würde er hier nicht mehr bearbeitet.
Das ist exakt, es sagt,
sie haben nicht richtig, es war nicht richtig falsch,
sagt das Gleiche aus, es ist ein Entfernungskriterium,
wir arbeiten die Knoten in einer gewissen Reihenfolge hier ab.
So, okay, das ist der Algorithmus und ja,
den werden wir
jetzt nochmal genauer betrachten
Das erste, was wir natürlich sehen, ist,
dass tatsächlich die Knoten wirklich nur von weiß,
nach grau, nach schwarz gefärbt werden.
Das ist erstmal das erste wichtige Kriterium. Wir sehen keine
andere Art der Färbung darin. Und wir sehen auch,
dass hier ja die Knoten nacheinander bearbeitet werden.
Und wenn sie einmal bearbeitet werden, werden sie auch nicht nochmal bearbeitet.
Das ist das nächste, was wir sehen.
Weil wenn sie bearbeitet wurden, dann werden sie schwarz,
dann sind sie aus der Warteschlange raus,
die Schwarzen kommen nicht mehr in die Warteschlange rein.
Also stehen die alle nur einmal in der Warteschlange,
wenn alle nur einmal bearbeitet.
Okay, also irgendwie haben wir ein Verfahren,
um systematisch diese Knoten genau einmal zu betrachten
Gut. So, jetzt gucken wir uns das nochmal an.
Hier ist mein Beispiel an Graf mit acht Knoten,
ist eine ganze Reihe von Kanten drin.
Hier ist der Startknoten S, das ist also willkürlich irgendeiner
von denen. Und hier in den Kreisen von dem Knoten
, da steht immer der D-Wert drin.
Also hier der Knoten S hat den D-Wert 0,
alle anderen haben den D-Wert unendlich.
Okay, so. Am Anfang ist in der Warteschlange Q
nur der Knoten S enthalten
Und der hat den D-Wert 0, hier drunter steht wieder
der D-Wert. Der hat den D-Wert 0. Von S aus
betrachten wir jetzt, jetzt geht die Wildschleife los.
Der Knoten S wird aus der Warteschlange entnommen.
Wir betrachten alle Nachbarn. Das sind hier R und W.
Und diese Nachbarn werden grau gefärbt und werden in die Warteschlange eingehängt.
Also W und R kommen in die Warteschlange und die beiden
Knoten hier kriegen den Distanzwert eins.
Das ist nämlich null der Distanzwert von S plus eins.
Deswegen haben die beide ja den Distanzwert eins
Ganz wichtig an dieser Stelle ist die Reihenfolge, in der
die beiden Knoten hier in die Warteschlange eingehängt werden, ist nicht definiert.
Ja, das hängt einfach davon ab, wie die zufällig in dieser Addizenzliste stehen.
Ihr könnt auch genauso gut eher und dann wehstehen. Okay,
so, jetzt sind die beiden drin,
da beide drin und diese Kanten,
die habe ich rot markiert, weil über diese Kanten,
hier haben wir die Knoten R und W erstmals gesehen und
deswegen werden die durch die Vorgängerrelation dargestellt.
Also P von W wäre es und P
von R wäre S und das sind genau diese beiden
Kanten hier
Okay, nächste Iteration, wir nehmen den Knoten weh aus der Warteschlange heraus.
Wir betrachten alle Nachbarn und wir sehen, der Knoten ist schwarz.
Jetzt habe ich ihn gerade ganz lange breit erklärt,
warum die Nachbarknoten nicht schwarz sein können.
Okay, es gibt einen schwarz, nämlich der Vorgänger,
von dem man gekommen ist. Der kann natürlich schwarz sein
. Die anderen sind natürlich alle nicht schwarz. Okay,
also der Vorgängerknoten, den betrachten wir dann nicht nochmal,
der ist schwarz, dann gucken wir uns die Nachbarn an,
die sind zwei Knoten, die waren weiß, die werden jetzt grau gefärbt.
Ja, die werden grau gefärbt und kriegen einen D-Wert zugeordnet,
nämlich einen Fluss, den D-Wert des Knotens weh,
macht zwei und hier auch zwei
Die beiden Kanten hier werden durch die Vorgängerrelation abgebildet und
die Knoten Tee und X werden in die Warteschlange reingehängt.
Hier steht jetzt T und X. Jetzt bearbeiten wir Knoten R,
das ist der hier,
gucken wir die Nachbarn an und der Nachbar V hier unten ist noch weiß,
der wird also in die Warteschlange gehängt, kriegt die Farbe grau,
der Devid ist eins plus der D-Wert des Vorgängers,
diese Kante wird gespeichert über die Vorgängerrelation und wir haben diesen Zustand hier.
So und jetzt langsam sollten sie das Konzept drin haben als
nächstes betrachten wir den Knoten Tee, das ist der,
der wird, wir betrachten die Nachbarn U und X kommen
Nee, U kommt in die Warteschlange X,
stand schon drin in der Warteschlange und war schon grau,
wird also nicht nochmal bearbeitet.
U kriegt den Distanzwert von T plus 1, also 3,
ja, und ja, dann machen wir weiter mit dem Knoten X.
Hier finden wir noch den Knoten Y, der wird in die Warteschlange gehängt.
Kriegt der Distanzwert 3, also den Wert von X 2 plus 1.
Dann wird V bearbeitet, der wechselt die Farbe auf Schwarz.
Er hat keine weißen Nachbarn mehr, es passiert ansonsten nichts.
Und dann wird U und Y bearbeitet,
da passiert auch nichts mehr,
weil die auch keine weißen Nachbarn mehr haben
Dann sind alle Knoten schwarz, die Warteschlange ist leer,
der Algorithmus terminiert und in jedem Knoten steht ein Distanzwert drin.
Und der Algorithmus ist beendet in diesem Augenblick. Okay,
so, das ist das Verfahren und das können wir jetzt
genauer anschauen und was wir noch herausfinden wollen, ist,
ob tatsächlich dieser D-Wert, den wir hier haben,
garantiert in jedem Fall uns eine Distanz zu dem Startknoten angibt.
Wenn das so wäre, dann hätte dieser Algorithmus schon eine recht nützliche Funktion.
Er könnte uns diesem Grafen quasi schon die Entfernung zu einem Punkt ausrechnen,
also den kürzesten Pfad mitteilen. In unserem Beispiel funktioniert das,
also der Knotentee, da brauchen wir zwei Kanten,
um zu S zu gelangen, von Y aus brauchen wir drei Kanten,
1, 2, 3, von U auch,
da gibt es sogar zwei Möglichkeiten, hier lang oder hier lang,
so alle Möglichkeiten, dass das geht.
Wir sehen sogar noch mehr, wenn das tatsächlich so ist,
dass diese D-Werte uns die Länge eines kürzesten Pfades angeben,
dann kennen wir sogar den Pfad, um dahin zu kommen.
Wir müssen nämlich von jedem Knoten aus immer nur die Vorgängerrelation auswerten,
also die Pi Funktionen, die das P-Array verwenden und zu sagen,
der Vorgänger von UST, der Vorgänger von CSW,
der Vorgänger von BSS, und wir kennen damit auch den Pfad,
um von einem beliebigen Knoten mit möglichst wenig Kanten zum Start für uns zu kommen.
Aber, wie gesagt, da sind wir noch nicht,
wir müssen noch zeigen, dass der Algorithmus auch tatsächlich funktioniert,
dass er diese, dass das tatsächlich auch die Länge eines kürzesten Pfahles ist.
Okay, so, wir gucken erstmal den Baum an. Hier ist er nochmal formal definiert,
das ist also der Vorgänger Teilgraf oder der BFS Baum,
der hat eine Knotenmenge oder eine Kantenmenge, die Kantenmenge,
sind alle Kanten P von U, Ja,
also die kannten die von dem Vorgänger zu einem Knoten U gehen und U und Pi von Usen natürlich Knoten aus unserem Grafen.
Und das sind immer die Kanten, über die wir
Knoten erstmalig besucht haben. Die Knotenmenge unseres Vorgänger-Teilgrafen,
hier sind die Knoten U mit der Eigenschaft,
das Pi von U ungleich Neil ist und der Startknoten.
Der Startnoten, bei dem, der hat ja die Eigenschaft,
dass er keinen Vorgänger hat,
deswegen ist das hier gleich Neil und trotzdem wollen wir
den natürlich dabei haben,
deswegen steht er hier
Hier stellt sich so ein bisschen die Frage,
gibt es denn überhaupt Knoten in dem Grafen, die diese Eigenschaft nicht erfüllen?
Also wenn man hier mal so guckt, dann haben wir
alle Knoten besucht und jeder Knoten hat einen Vorgänger gefunden.
Es sieht alles eigentlich gut aus. Warum sollte es jetzt
einen Knoten geben, wo das noch nie ist?
Außer vielleicht den Startknoten, da war das ja nie,
weil der keinen Vorgänger hatte. Naja,
hier haben wir streng genommen ein Beispiel mit einem Sonderfall,
denn dieser Graf hat die Eigenschaft, dass er zusammenhängend ist.
Das heißt, sie können in diesem ungerichteten Graf von jedem Knoten
jeden anderen erreichen und deswegen sind die natürlich auch für alle definiert.
Wenn Sie sich vorstellen, Sie hätten hier nochmal fünf Knoten,
die auch alle viele Kanten haben,
die aber keine Kante haben zu diesen acht Knoten hier,
dann würden Sie von S aus diese Knoten nicht erreichen können.
Und die P-Werte wären noch Nil. Also die würden nicht initialisiert
. Die Distanzwerte wären zu dem Zeitpunkt alle noch unendlich.
Wir haben gerade gesehen, wir können mit dem Algorithmus doch
was total Interessantes ausrechnen. Wir können nämlich den Zusammenhang feststellen.
Wir können feststellen, welche Teile können wir voneinander erreichen voneinander
und welche bilden eine Zusammenhangskomponente.
Das kann in ungerichteten Graben
Ok, so,
also das ist die Knotenmenge unseres Vorgängerteilgrafs und der Graf GP
ist halt der mit diesen Knoten und diesen Kanten und das
ist eben ein Baum mit einer Wurzel S und der beschreibt quasi,
das ist das Rote,
was wir in diesem Grafen sehen.
Das ist dieser Vorgängerbaum. Jetzt kann ich natürlich behaupten,
es ist ein Baum, es ist natürlich zeigen,
dass ein Baum ist, warum ist es ein Baum?
Also warum muss zusammenhängend sein und er darf keine Zyklen enthalten oder Kreise.
Warum ist er zusammenhängend? Er ist zusammenhängend,
weil für alle Knoten V gibt es einen Pfad von V
zu Wurzel
Also wir kommen immer zur Wurzel,
weil wir haben ja diesen Knoten V besucht und wir können natürlich rekusiv argumentieren,
dass wir natürlich den Vorgänger besucht haben und deswegen haben wir
den Vorgänger vom Vorgänger besucht und den Vorgänger vom Vorgänger,
von Vorgänger und irgendwann sind wir bei dem Knoten S angekommen.
Deswegen ist der Graf zusammenhängt und er kann keine Zyklen enthalten,
das habe ich eigentlich gerade schon mal gesagt,
weil jeder Knoten nur einmal grau gefärbt wird und nur zu
einem Zeitpunkt wird entschieden, wer der Vorgänger ist.
Und insofern können gar keine Zyklen entsprechend auftreten. Ja,
Okay, so, die Laufzeit ist das Nächste,
was wir uns anschauen, wie lange dauert denn das alles?
Hier steht schon das Ergebnis,
O von N plus M und nur nochmal für die,
die es jetzt gerade nicht mehr parat haben,
N ist die Anzahl der Knoten und M ist die Anzahl der Kanten.
So, das ist die Laufzeit, die wir haben für
die Breitensuche und die Frage ist, warum ist das so?
Denn so ganz einfach ist das diesem Algorithmus nichts zu entnehmen.
Man muss schon mal einmal drüber nachdenken.
Wenn wir hier drauf gucken, dann sagen wir,
okay, also hier haben wir eine Vorschleife,
die besucht alle Knoten
Alles klar, das ist O von Betrag von V oder N.
Also das ist keine Frage. Hier haben wir eine Wildschleife und die Wildschleife,
die besucht alle Knoten. Also offensichtlich wird diese Wildschleife auch
en-mal ausgeführt oder O von N mal, n-mal ausgeführt.
Haben wir wieder was, was proportional zu N ist.
Dummerweise ist sie aber noch eine Schleife drin, nämlich die Vorschleife.
Und die wird für alle Kanten ausgeführt, die an diesen Knoten V stoßen.
Wenn wir jetzt grob schätzen, dann könnten wir sagen,
naja, im schlimmsten Fall ist dieser Knoten,
hier U zu allen anderen Knoten benachbart.
Dann wäre diese Addizenzliste N-1 kannten groß oder lang.
Im schlimmsten Fall würde also diese Vorschleife hier auch en mal durchlaufen.
Und der Algorithmus hätte eine Laufzeit von O von N-Quadrat.
Wenn wir das so betrachten, dann ist das zwar im
Worst Case korrekt. Wir haben aber relativ grob abgeschätzt,
weil wir hier einfach davon ausgegangen sind,
dass jeder Knoten mit jedem benachbart ist,
was in den allermeisten Grafen natürlich nicht der Fall ist.
Um zu sehen,
was die tatsächliche Laufzeit ist oder eine etwas dichtere Schranke,
müssen wir einfach
die Länge der Addizenzlisten bei der Analyse betrachten
Und das geht wie folgt. Hier erstmal der einfache Teil,
die Initialisierung, benötigt O von Betrag von V oder O von N.
Also jeder Knoten wird einmal betrachtet.
Jeder Knoten wird einmal in Q eingefügt und wieder entnommen.
Das ist auch offensichtlich O von V für die Wahlschleife.
So, jetzt kommt der Teil in der Wildschleife.
Und was wir wissen ist, in der Wildschleife wird jeder
Knoten einmal betrachtet. Das heißt, wir können,
anstatt zu sagen, wir machen einfach en Schleifendurchläufer,
auch sagen, wir haben die Laufzeit als Summe über alle Knoten
Jeder Knoten wird einmal betrachtet und produziert etwas Laufzeit, Bedarf.
Und für diesen Knoten betrachten wir alle Kanten,
aber nur die Kanten, die an den Knoten V anstoßen.
Und für jede Kante, das ist jetzt die innere Vorschleife,
benötigen wir wieder etwas Laufzeit. Und die Zeit, die
wir dann haben, ist aber konstant. Also das,
was innerhalb der Vorschleife, das ist ein konstanter Zeitaufwand,
den wir hier haben. Also diese Wildschleife ist die Summe über
alle Knoten und diese Vorschleife ist die Summe über alle Kanten,
die inzident sind zu unserem Knoten,
uh, den wir gerade betrachten
Okay, damit haben wir diese Formel und jetzt müssen wir
überlegen, was ist denn diese Summe hier?
Also wir sagen, wir betrachten jeden Knoten und von jedem
Knoten aus, alle kannten die da rausgehen.
Wenn man sich das dann mal überlegt, dann sieht man sofort,
dass hier jede Kante genau zweimal gezählt wird.
Eine Kante hat zwei Nachbarn, also zwei hat ja
zwei inzidente Knoten, zwei Knoten, die da anstoßen.
Also wird diese Kante hier zweimal gezählt. Einmal,
wenn wir den Knoten V betrachten und einmal,
wenn wir den Knoten U betrachten
Das heißt, in dieser großen Summe betrachten wir genau jede Kante zweimal.
Das heißt, das hier ist genau das Gleiche wie zweimal,
zehnmal der Betrag der Anzahl der Kanten.
Dieses, diese Auflösung dieser Summe durch zweimal E ist quasi, das ist das Handshake-Lemmer.
Das haben sie vielleicht in der Mathematik schon mal gehört,
dass man das so auflösen kann. Und sie können das,
und wenn, das können sie auch wörtlich nehmen,
wenn sie dann sagen, sie haben hier eine Bewiebeanzahl von Personen im Raum,
ja, und die schütteln sich alle genau,
jeder einmal die Hände, ja, dann wissen sie genau,
wie sie das ausrechnen müssen
Indem sie hier einfach sagen, okay, wenn wir wissen wollen,
wie häufig wurden denn da die Hände geschüttelt?
Können wir jede Einzelperson betrachten und fragen,
wie häufig hast du dir denn die Hände geschüttelt?
Das können wir alles aufaddieren und dann müssen wir es noch
durch zwei dividieren. Oder andersrum, wir wissen,
es ist Anzahl der Kanten zweimal eben,
also zweimal eh genau die Anzahl der Adjazenzlistenlängen ist.
Okay, also jetzt haben wir zehnmal Betrag von V plus
zweimal zehnmal Betrag von E.
Und ja, das ist im Okalkül O von V plus E.
Und das bezeichnen wir, wie gesagt,
als N, das als M,
also O von N plus
Jetzt könnte man sagen, ja,
das ist jetzt aber als Schranke gar nicht so viel besser,
als wir hatten ja eben auch von N ein Quadrat.
Und im schlimmsten Fall haben wir ja nun mal quadratisch viele Kanten in
so einem Grafen, wenn jeder mit jedem verbunden ist.
Also ist das ja eigentlich auch O von N, Valar.
Das stimmt, dass da mit, das ist korrekt.
Allerdings haben wir in der Praxis ganz selten so dichte Grafen.
Also wenn wir irgendwelche Dinge durch Grafen modellieren, haben wir
selten so dichte Grafen. Stellen Sie sich vor,
unser Stadtnetz, wenn wir sagen,
wir bauen ein Navigationssystem und müssen die,
müssen eine Stadtkarte repräsentieren durch einen Grafen
An jeder Kreuzung, das wäre ja ein Knoten,
natürlich nur eine konstante Zahl von ausgehenden Nachbarn.
Und dann haben sie natürlich keine große Kantenzahl. Dann haben sie
nur eine Kantenzahl, die proportional ist, so eins der Leckknoten.
Und es ist bei ganz, ganz vielen Anwendungen so,
dass das M hier eigentlich nur ein Faktor der Anzahl der Knoten ist,
die wir haben.
Und dann ist das natürlich eindeutig besser hier, diese Schranke.
Okay, diese Schranke erreichen sie übrigens nur,
wenn sie die Grafen über Adlizenzlisten darstellen.
Wenn die Graf, wenn die Grafen dargestellt sind,
über eine Adlizenzmatrix
Also mal angenommen, wir hätten eine Addizenz-Matrix, sage ich
nicht nur eben die Matrix, diese Darstellung, diese hier.
Dann haben sie nicht die Laufzeit-O von N plus M,
weil, wir gucken in den Algorithmus, wir haben diese Vorschleife hier,
wo wir die Nachbarn betrachten und diese Vorschleife wäre bei einer Addizenz-Matrix eine Vorschleife,
die von 1 bis N laufen würde,
um diese Zeile in dem Addizenz-Matrix abzuarbeiten.
Und es steht ab und zu eine Nullerin und ab und zu
eine Eins drin und die Nullen überspringen sie über den Einsen, machen sie was.
Diese Schleiffahrt unabhängig von der Anzahl der Einsen,
die da drin vorkommt, natürlich O von Endzeit,
Endschleifendurchläufe,
die sie machen müssen
Das heißt, nur bei Repräsentation durch Attrizenzlisten haben sie
O von N-Plus M, wenn sie Attrizenz Matrizen verwenden,
haben sie O von N-Quadrat unabhängig von der Anzahl erkannten.
So, und jetzt wollen wir noch wissen,
ob denn tatsächlich der Algorithmus auch diese kürzesten Pfade berechnet.
Also, als erstes Mal müssen wir sagen,
was denn das Ergebnis ist, was wir raushaben wollen,
das wollen wir definieren, das bezeichnen wir jetzt im Folgenden als Delta.
Also Delta von SU ist der minimale,
die minimale Anzahl Kanten eines Pfades von S nach
Also die minimale Anzahl Kanten, die wir brauchen,
um von S nach U zu gelangen.
Wenn dieser Pfad nicht existiert, dann sagen wir,
dass dieser Wert unendlich ist. Also der Knoten-U ist unendlich weit entfernt,
wir können den nicht erreichen von S aus. Okay,
so, dieses Delta wird als der kürzeste Abstand bezeichnet und
der Pfad von S nach U wird als der kürzeste Pfad bezeichnet.
So, jetzt müssen wir mit diesem kürzesten Faden arbeiten und
dazu müssen wir ein paar Eigenschaften zeigen, die gelten.
Ich sage Ihnen, die meisten dieser Eigenschaften werden Ihnen trivial vorkommen,
sagen, ja, klar ist das so,
aber trotzdem muss man sie einmal hingeschrieben haben,
zu zeigen, dass die auch wirklich dann gültig sind.
Die Struktur kürzester Pfade, das ist etwas, was wir kennen.
Das haben wir schon als Steinzeitmenschen gebraucht, die Eigenschaft.
Deswegen kommt uns die garantiert selbstverständlich vor. Die sagt nämlich nichts weiter aus,
dass wenn wir einen Graf haben und einen Staat knoten,
dann gilt für alle Kanten UV,
dass der kürzeste Fahrt von S nach V kleiner gleich den kürzesten Pfad von S nach US plus 1. Das bedeutet,
Das bedeutet nichts weiter, als wenn wir eine Kante haben,
wenn wir eine Kante haben,
die geht von einem Knoten U zu einem Knoten V.
Und irgendwo haben wir unseren Startknoten. Dann gibt es einen kürzesten Weg,
der führt uns irgendwie zu dem Knoten U. Und das einzige,
was wir sagen, ist der kürzeste Weg,
der uns zu einem Knoten V führen kann,
der kann nicht länger sein als der kürzeste Weg Von S nach U plus diese eine Kante,
die wir noch nicht laufen müssen.
Vielleicht ist er kürzer, aber länger ist er definitiv nicht.
Das ist die Struktur. Und der Beweis dafür ist,
okay, mal angenommen, er ist von U ist unendlich,
da müssen wir eigentlich gar nichts zeigen,
weil wenn hier auf der Seite unendlich steht,
ist es völlig egal, wie es von V ist.
Aber trotzdem kann man sagen, naja, also S von U unendlich bedeutet,
wir können den gar nicht erreichen, diesen Knoten.
Also U ist nicht erreichbar von S. Und damit können wir
auch V nicht erreichen. Beachten Sie dieses Argument gilt nur für ungerichtete Graphen.
Bei gerichteten ist das anders. Aber wenn wir sagen,
wir können U nicht erreichen, können wir auch V nicht erreichen,
weil wir können ja diese Kante in beide Richtungen durchlaufen.
Also können wir den auch nicht erreichen. Und dann sind
die beide unendlich. Und dann ist die Aussage korrekt. So,
wenn der Delta-Wert hier kleiner ist als unendlich,
also wir können, es gibt einen Pfad,
der uns von S nach U führt, dann können wir sagen,
es gibt einen Pfad von SU und dann können wir über die Kante E zu V zu gelangen.
Es ist das, was ich ihnen hier aufgemalt habe.
Und das ist erstmal irgendein Pfad, der uns zu V führt.
So, und der kürzeste Pfad ist definitiv kleiner als das.
Und das heißt, dass das Delta SV,
also der kürzeste war das kürzer als irgendein Vater uns zu den Knoten führt.
Das ist also kleiner gleich, Delta SU plus
So, das ist erstmal die Struktur, die wir haben,
in kürzestem Faden. Die werden wir noch viel benutzen. Ja,
das ist, wie gesagt, etwas,
was uns relativ trivial erscheint, aber was sehr,
sehr wichtig ist, um die Korrektheit von Verfahren zu zeigen.
Okay, so, das Erste, was wir uns angucken,
ist, dass unsere Breitensuche, dass Delta SU abschätzt und zwar von oben.
Das heißt, wir haben ein Gras G,
es ist ein Startknoten D,
sind die durch Breitensuche berechneten Werte und dann gilt,
dass für jeden Knoten D von V größer gleich dem Delta SV ist.
Das heißt, das D, das beschreibt eine Fahrtlänge.
Und wir wissen dann noch nicht, ob es der kürzeste
Pfad ist, aber es ist garantiert größer als das.
Das ist das Erste, was wir zeigen wollen.
Und das funktioniert wie folgt. Wir müssen eine Induktion machen.
Das ist auch wieder ein relativ einfacher Beweis. Wir machen
eine Induktion über die Einfüge Reihenfolge. Also die Reihenfolge,
in der wir die Knoten in die Warteschlange einhängen.
Am Anfang gilt das D von V, also nein,
unsere Annahme, die wir zeigen wollen, ist hier nochmal hingeschrieben,
D von V ist größer, gleich Delta von SV,
für alle Knoten aus V.
Im Induktionsbeweis würden wir sagen, gut,
das gilt für alle Knoten,
die in der Warteschlange hängen und für die anderen dann noch nicht und mit jedem Induktionsschritt,
zeigen wir, dass für die nächsten Knoten diese Eigenschaft auch gilt.
Am Induktionsanfang ist das dann erfüllt, weil der Staatsknoten die Entfernung null hat.
Und das ist natürlich die Länge des kürzesten Pfades von S
nach S. Und die anderen Werte, die von V,
die sind alle unendlich und das ist größer gleich Delta von SV.
Also unähnlich ist auf alle Fälle größer als die tatsächliche Länge des kürzesten Pfades.
Also am Anfang sind alle Bedingungen, die Bedingungen erfüllt.
Jetzt kommt der Induktionsschritt. Wir betrachten also den Zeitpunkt in dem Algorithmus,
wo wir einen Knoten V erstmals erreichen, über diese Kante von U nach V.
Was gilt dann? Wir wissen, dass wir den DV-Wert
hier initialisieren als DU plus 1. Das macht der Algorithmus,
das schreibt er da rein. Also DV ist gleich DU plus 1. Wenn der Knoten,
uh, vorher schon bearbeitet wurde, also wenn da die Berechnung abgeschlossen ist,
dann wissen wir, dass der DU-Wert größer gleich,
also es ist für den, die Induktionsbedingungen schon gilt,
DVU ist dann größer, gleich Delta, SU,
ja, als das größer gleich Delta,
SU plus 1.
Und wir wissen, aufgrund des Strukturlämmers,
dass das größer gleich dem Delta SV ist,
also dem kürzesten Pfad zu
Damit haben wir gezeigt, dass unser Algorithmus auf alle Fälle
die kürzesten Pfade erstmal überschätzt. Das heißt also überschätzt,
dass entweder trifft er sie oder sie sind größer,
aber er unterschätzt sie entsprechend nicht. Okay,
um auch das Gegenteil, also die andere Richtung zu zeigen,
dass wir exakt mit D die kürzesten Pfade berechnen,
müssen wir uns ein bisschen mit der Struktur der Warteschlange Kuh auseinandersetzen.
Die in der Warteschlange Kuh stehen ja die Knoten in einer speziellen Art und Weise drin.
Wir können uns nochmal das Beispiel anschauen, um zu sehen,
Ob man schon erkennt, was die Eigenschaft ist.
Also, was man hier an dem Beispiel sieht, ist,
offensichtlich werden, also die Werte werden ja immer größer,
so nach und nach. Wir sehen, die Werte sind aufsteigend.
Wir haben in der Warteschlange nie die Situation, dass ein,
er ist ein großer und dann wieder ein kleinerer Wert kommt.
Das kann man dem Algorithmus sofort entnehmen, weil,
wenn wir etwas hinten in die Warteschlange reinhängen,
dann nehmen wir ja den Wert von dem,
was gerade vorher stand, plus eins.
Das reicht noch nicht als Argument, wie wir gleich sehen werden,
aber zumindest ist es erstmal ein Hinweis darauf,
dass die Werte scheinbar immer
steigend sind
Die sind immer aufsteigend in der Richtung. In dem Beispiel
sieht man noch etwas, und zwar man sieht,
dass streng genommen immer nur zwei mögliche Werte vorkommen.
Also am Anfang ist es nur Null, dann ist es
nur eins. Jetzt ist es eins und zwei.
Hier ist es dann eine Zeit lang nur zwei.
Hier ist es zwei und drei, zwei und drei.
Hier ist dann nur noch drei und dann ist es zu Ende.
Das Beispiel ist noch nicht groß genug,
um zu sehen, ob das jetzt ein Zufall ist,
weil das Beispiel so klein war.
Aber das scheint auch eine Eigenschaft zu sein,
die man sich anschauen kann. Das heißt,
in der Warteschlange gibt es eigentlich immer nur zwei mögliche Werte.
Und die sind so, dass wir am Anfang
die kleineren haben und dann die größeren Werte
Gut, so, das ist die Struktur der Warteschlange,
das steht hier nur noch mal aufgeschrieben, wenn G unser Graf ist und S,
ein Startknoten.de sind unsere Werte, die wir aus dem Algorithmus entnehmen.
So, und dann ist Kuh, also unsere Warteschlange zu irgendeinem Zeitpunkt im Algorithmus. Ja,
und da stehen jetzt Knoten drin, das fängt an mit V1,
V2, V3 und so weiter, wir wissen nicht,
wie viele Knoten da drin stehen, das geht irgendwie bis VR.
Die stehen jetzt alle in dieser Warteschlange drin, ja,
dann behaupten wir, dass zu jedem Zeitpunkt gilt für diese Warteschlange,
dass diese Werte mono und steigend sind,
also D von V1, ist kleiner gleich D von V2,
ist deiner gleich und so weiter, D von VI,
kleiner gleich D von VI plus 1 und so weiter,
bis zum letzten Element,
D von VR.
Und wir behaupten auch, dass das letzte Element hier
kleiner gleich D von V1 plus 1 ist.
Es ist maximal um eins größer als das erste Element.
Und da wir nur ganzteilige Werte haben, ist dann klar,
es gibt nur zwei mögliche Werte in der Warteschlange.
Zwei mögliche D-Werte. Okay, so, das wollen wir zeigen.
Es kann sich auch nochmal schnell aufmalen. Also hier ist
unsere Warteschlange Kuh, ja, zu irgendeinem Zeitpunkt. Hier vorne steht das V1,
ja, dann stehen die hier alle, hier ist irgendwo VI,
VI plus 1, ja, und dann geht das hier irgendwie so weiter.
Hier ist das letzte Element, das ist das VR und wir wissen,
dass die alle eine Kleinergleichrelation haben, ja,
also es wird von hier,
ach hier werden die D-Werte immer größer, ja,
und das andere, was wir wissen, ist,
dass hier am Ende dieses, das D von dem VR,
Ja, das ist, hat eine Beziehung zu dem ersten Element.
Und zwar ist das kleinergleich die von V1 plus 1. Ja,
so sieht unsere Warteschlange aus. Und jetzt müssen wir gucken,
jetzt müssen wir zeigen, dass das stimmt.
Und wie zeigen wir das, das stimmt?
Naja, wir gucken einfach, was der Algorithmus macht.
Der Algorithmus nimmt aus der Warteschlange ja immer vorne was raus.
Der nimmt vorne was raus, der nimmt das V1 hier raus.
Und wenn das V1 rausnimmt, dann hängt er hier hinten ja offensichtlich was dran.
Da würde dann jetzt VR plus 1 drangehängt, das nächste Element.
Und wir müssen zeigen, dass durch diese Operation, die wir machen,
also V1 rausnehmen und VR plus 1 dranhängen, wir diese Struktur erhalten.
Am Anfang gilt sie offensichtlich. Am Anfang ist die Warteschlange
ja, da steht ja nur unser Knoten S drin.
Ja, und da ist die Eigenschaft ja offensichtlich erfüllt.
Okay, das heißt, wir haben in zwei Operationen,
die wir mit der Warteschlange machen, wir machen die Ancue-Operation,
dann hängen wir ein neues Element hinten ran und wir machen die DQ-Operation.
Wir löschen das vordere Element aus der Warteschlange. Und bei beiden Operationen müssen wir zeigen,
dass unsere Eigenschaft, die wir formuliert haben, nämlich,
dass wir immer eine kleinergleichbeziehung der D-Werte haben und dass die
Spanne von hier bis hier bis zum letzten Element nur eins ist,
erhalten bleibt
Okay, so, also wir gucken uns die beiden Operationen an.
Das erste, was wir machen in dem Algorithmus,
ist ein DQ. Wir nehmen einen Knoten aus der Warteschlange
raus, nochmal zurück zum Algorithmus, da.
Also hier nehmen wir einen Knoten raus. Hier werden wir
gleich dann einen Knoten einhängen. Aber jetzt nehmen wir erstmal
einen raus. Was passiert, wenn wir einen Knoten rausnehmen?
Wenn wir einen Knoten herausnehmen, so hier sind wir,
ja, dann wird ja dieses Element gestrichen.
Das ist dann weg. Und jetzt ist V2
das neue erste Element
So, das heißt, und offensichtlich gilt jetzt für die Warteschlange Kuh
immer noch das Gleiche, dass die alle kleiner gleich sind.
Also wir haben ja nichts geändert, wir haben ja nur das erste Element weggenommen.
Also warum sollte sich dann die Beziehung der Elemente untereinander verändern? Also das ist offensichtlich erhalten geblieben. So,
was ist mit der Eigenschaft, dass das letzte Element,
kleiner gleich D von V1 plus 1 ist,
jetzt haben wir das V1 nicht mehr und der neue Listenkopf ist das V2,
aber das V2 ist ja größer als V1. Das heißt,
das Einzige, was passieren könnte, ist,
dass wir hier diese Schranke vergrößern,
Also jetzt hätten wir ja die Beziehung, das D von VOR,
müsste kleiner gleich D von V2 plus 1 sein.
Ja, aber das D von V2, das wissen wir ja schon,
ist ja kleiner gleich dem D von V1. Und da müsste
es die Bedingungen auf alle Fälle wieder erfüllt.
Das heißt, in dem Augenblick, wo wir ein DQ machen,
machen wir nichts kaputt. So, jetzt kommt das NQ,
jetzt hängen wir einen neuen Knoten rein.
Jetzt kommt hier dieser Knoten dazu. Okay, was passiert denn
jetzt? Also, V ist der neu eingefügte Knoten,
VR plus 1,
da ist jetzt hier
Wow. Wenn wir das machen, dann betrachten wir ja gerade
eine Kante. Also wir betrachten eine Kante von U nach V.
Und u haben wir gerade aus der Warteschlange herausgenommen.
Und V fügen wir hinten in die Warteschlange ein.
Genau, mal zurückgehen zum Algorithmus, um das zu sehen.
Also U nehmen wir aus der Warteschlange raus. Und in
dieser Vorschleife hängen wir V hinten in die Warteschlange rein.
Okay, so. Okay, wir wissen,
D von V wird initialisiert als D von U
Also D von V ist gleich D von U plus 1.
Das rechnet unser Algorithmus so aus.
So definiert er den Wert. Und das D von U,
das kennen wir, weil der Knoten war ja bis eben
noch vorne in der Warteschlange dran.
Nach der Induktionsannahme gilt, dass das DU.
Kleiner gleich D von V1 sein muss. Also zu dem Zeitpunkt,
wo wir das gelöscht haben,
ist das das neue D von V1. Wir haben das ja
rausgenommen und das war vorher in der Warteschlange und die waren ja alle aufsteigend sortiert.
Also ist das das Kleinere. Also das heißt D
von U ist kleiner gleich D von V1. Also dann ist
D von VR plus 1,
also das nächste Element
Es ist ja unser D von V,
das ist ja D von U plus 1, so wurde das ja definiert,
ja, und das entspricht dann dem D von V1 plus 1. Also insofern ist alles gut.
Und das nächste, was gilt, ist,
dass das D von VR, kleiner gleich D von U plus 1 ist,
weil das ist ja gerade das Element, was wir eingefügt haben hinten.
Okay, so, das heißt,
wir haben also immer nur zwei mögliche Werte hier, ja,
und an irgendeiner Stelle hier ist mal so ein Sprung drin,
ne, also hier haben wir die Werte,
was weiß ich,
I und dann kommt der Sprung und der Rest der Schlange
hat dann die Werte I plus
Okay, also, ihr steht's nochmal, die D-Werte sind in Kuh,
sind monoton steigend und sie sind diskret und es gibt nur zwei mögliche Werte,
der von dem Head und der von dem Head und dann plus eins,
also nicht vom nächsten Element,
sondern den D-Wert des Heads plus eins.
So, und wenn man das hat, können wir zeigen,
dass wir tatsächlich kürzeste Wege oder kürzeste Pfade mit der tiefen Suche berechnen können.
Das steht hier, das ist das Breitensuchtheorie,
da steht also drin, wir haben also einen Graf,
wir haben einen Startknoten und nach Durchführung unseres BFS-Algorithmus gilt für alle Knoten V,
die von S aus erreichbar sind, erstens diese Noten sind schwarz.
Die haben wir besucht. Das ist wichtig für die Korrektheit,
damit wir sagen, wir haben die auch alle betrachtet.
Das nächste ist, für alle Knoten gilt D von V ist gleich Delta SV.
Das heißt, der D-Wert, der im Algorithmus berechnet wurde,
entspricht dem kürzesten Abstand des Knotens zum Startknoten, also dem Delta SV.
Und drittens, es gibt einen kürzesten Pfad von S nach V,
der mit der Kante PV, also Vorgänger von V und V, endet.
Das ist der letzte, wenn man von S aus zu V läuft.
Ja, das heißt, damit sehen wir auch,
dass die Vorgängerrelation genau die ist,
die die kürzesten Pfade beschreibt
Schreiben. So, das Einzige, was wir hier ausführlich zeigen wollen,
ist der Teil, dass wir tatsächlich die kürzesten Pfade berechnen.
Das heißt, dass der D-Wert dem Delta-Wert entspricht.
Die anderen beiden Teile, die ergeben sich,
das haben wir mehr oder weniger schon gesehen.
Okay, wir haben schon gezeigt,
dass das D von V größer gleich Delta SV ist.
Also die D-Werte, die im Algorithmus berechnet werden,
sind größer gleich dem kürzesten Faden.
Das wissen wir schon. Das haben wir schon gezeigt.
Jetzt machen wir einen Widerspruchsbeweis. Wir sagen jetzt,
aha, mal angenommen, es gibt einen Knoten V,
für den das jetzt nicht gilt.
Also für den nicht gilt,
dass die Entfernung gleich ist
Da haben wir einen Fehler gemacht.
Unser Algorithmus hat für diesen Knoten V einen D-Wert berechnet,
der echt größer ist als der kürzeste Pfad zu dem Knoten V.
So, den betrachten wir, um herauszufinden,
ob es diesen Knoten überhaupt geben kann oder nicht.
Wir nehmen mal an, den gibt es und wir gucken,
ob wir einen Widerspruch produzieren können.
Wir überlegen uns mal, welcher Knoten V das sein könnte.
Also mal angenommen, also der Startnoten kann es nicht sein.
Also der Startnoten hat diese Eigenschaft definitiv nicht,
weil für den Startknoten wissen wir,
dass der D-Wert null ist und das Delta ist
auch entsprechend null für diesen Knoten
Also es ist nicht der Startknoten. So,
offensichtlich muss dieser KnotenV, für den diese,
für den wir die Entfernung falsch berechnet haben, erreichbar sein.
Den müssen wir erwischen können von dem Knoten S aus.
Warum? Naja, wenn wir ihn nicht erreichen können,
dann ist der D-Wert unendlich und das entspricht auch dem Delta-Wert.
Das heißt, die Knoten, die wir nicht erreichen können,
für die können wir auch die kürzesten Fahrtlängen nicht richtig falsch berechnen.
Das heißt, dieser KnotenV ist irgendein Knoten in dem Graf,
den wir von S aus erreichen können,
aber S selber ist es nicht.
Okay, was machen wir jetzt?
Naja, wir gucken uns jetzt
den Graf an
Und in dem Graf haben wir jetzt den Knoten S,
ja, und wir haben unsere Vorgängerrelation und wir haben also jetzt viele Knoten,
ja, und irgendwie haben wir so einen Baum und nach hierhin
werden die Knoten immer weiter entfernt, ja.
Das ist nicht der Grab, sondern es ist nur die,
nur der BFS-Baum, den wir hier sehen,
von dem Startknoten S aus. Und wir sagen jetzt,
okay, hier gibt's jetzt einen, also der hier zum Beispiel,
ne, das ist jetzt unser Knoten,
wo der Algorithmus sich vertan hat,
das heißt,
das D von V ist echt größer als das Delta SV
Mal angenommen, der wäre das. Wenn er sich für den verrechnet,
hat er sich vielleicht noch für ganz viele andere verrechnet.
Kann ja sein, dass sie irgendwie 30 Prozent der Knot
falsche Ergebnisse haben. Unter all denen, die falsch,
dann suchen wir uns einen raus. Wir suchen uns einen
raus. Und zwar nehmen wir einfach von allen,
die falsch sind, den, der am dichtesten an S liegt.
Das heißt, wir wählen den Knoten so, dass Delta SV minimal ist.
Also wir nehmen den Knoten hier mit minimalem Delta SV.
So, was gilt jetzt? Wir gucken uns mal
den Vorgänger an auf dem kürzesten Pfad
Den Vorgänger von V auf dem kürzesten Pfad. Wir sehen hier,
das ist der BFS-Baum, so ein Knoten-U, das kann natürlich der sein,
aber vielleicht funktioniert ja auch unsere Vorgängerrelation nicht richtig.
Ja, wissen wir nicht so genau.
Deswegen betrachten wir jetzt den kürzesten Pfad. Wir sagen jetzt,
aha, okay, wir haben irgendwo den Start,
Knoten-S. Wir haben den kürzesten Pfad, der führt uns zum Knoten-U,
dann haben wir die Kante zu unserem Knoten V.
So, diesen Knoten-U gibt's, ja,
weil es gibt ja einen kürzesten Pfad von V zu Es,
den muss es ja geben,
weil das Delta ist ja kleiner
als unendlich
So, also, für, was wir jetzt wissen,
ist, dass Delta SV, das,
was Hirsch zu dem gehört,
das ist natürlich das Delta von SU plus 1. Strukturkürzester Fade,
entlang der kürzesten Pfade, wissen wir,
dass die Pfadlänge sich immer genau um eins verlängert.
Okay. So, der Knoten V war der mit minimalem
Abstand zu S, für den das Ergebnis falsch war.
Das bedeutet, uh,
ist näher dran
Der Delta-Wert ist ja kleiner als V. Und weil V,
der war, der am nächsten war mit dem falschen Ergebnis,
wissen wir, für U haben wir das richtige Ergebnis berechnet.
Okay, und wenn wir das wissen,
dann wissen wir, dass das D von U,
das muss jetzt dem Delta-SU entsprechen.
Ja, weil wir haben ja den nächsten Knoten gewählt.
Und jetzt müssen wir es nur noch zusammensetzen. Wir wissen jetzt,
dass D von V ist größer als das Delta-SV.
Das war ja unsere Annahme. Die Berechnung war falsch.
Das Delta-SV ist aber
das Delta-SU plus
Ja. Und das Delta SU entspricht dem D-Wert,
weil da haben wir es ja richtig berechnet.
Also DU plus 1. Und jetzt steht hier das DV,
größer ist als DU plus 1. Und das kann nicht sein. Ja,
weil wir wissen bereits, wir haben ja die Kante,
die uns von U zu V führt.
Ja, diese Kante hier, ja.
Und diese Kante haben wir betrachtet und damit ist das DVN
V natürlich maximal gleich D von U plus 1. Okay,
zweiter Schritt ist also, dass, das haben wir gesehen.
Also D von V ist erstmal größer als D von U
plus 1 und jetzt müssen wir noch gucken,
dass das tatsächlich nicht auftreten kann
Wir müssen in den Algorithmus reingucken. Und die Frage ist,
was passiert zu der Zeitpunkt, wo wir U aus der Warteschlange genommen haben?
Also der Algorithmus hat jetzt hier gearbeitet, Breitensuche, Breitensuche.
Uh, so, Knoten-U wird betrachtet, Knoten-U wird aus der Warteschlange herausgenommen.
Okay, mal angenommen, der Knoten ist weiß.
Wenn der Knoten weiß ist, dann wird das D von U,
das D von VfD von U plus 1 gesetzt.
So wird das initialisiert. Das kann aber nicht sein,
weil wir wissen schon, dass das D von V
größer sein muss als D von U plus 1.
Das folgt aus unserer Annahme, dass das Ergebnis für V
falsch berechnet ist.
Also der Knoten-V kann nicht
weiß sein
Schwarz, naja, schwarz kann er sowieso nicht wirklich sein.
Also V wurde bereits aus der Warteschlange entfernt,
also ist D von V garantiert erst mal kleiner gleich DVU.
Kann nicht sein. Und wenn er grau ist, naja,
wenn er grau ist, müssen wir noch mal gucken,
dann hat er jetzt einen anderen Vorgänger, ja,
der Knoten und das ist einmal der Knoten weh.
Und dann müssen wir der Vorgänger W, das ist der,
wo wir dann V, dann sind wir nicht hier entlang gelaufen,
sondern haben irgendeinen anderen Knoten gesehen, weh, ja,
und der Knoten hat dazu geführt, dass wir den Knoten grau gefärbt haben.
So, w haben wir
aber schon bearbeitet
Der ist ja, also V ist ja schon grau.
Deswegen haben wir den schon bearbeitet. Und das heißt,
W ist der Knoten, bei dessen Entnahme V grau gefärbt wurde.
Damit ist D von W. Kleiner gleich D von U.
Die D-Werte steigen immer nur, während wir das berechnen.
Und dann wissen wir schon,
dass D von V gleich D von W plus 1 ist,
weil das war ja der Zeitpunkt, wo wir V grau gefärbt haben.
Da sind wir die Kante lang gelaufen, haben den D-Wert definiert. Und daraus folgt sofort,
dass das D vom VHD von W plus 1 und das
ist kleinerrechtlich von U plus 1 und das ist wieder ein Widerspruch,
weil wir gerade ja gezeigt haben, dass das D von V größer sein muss als D von U plus sein.
Es bleibt keine Farbe übrig, also egal,
also ob V, weiß, schwarz oder grau war,
in allen Fällen haben wir einen Widerspruch, wir zeigen,
dass in keiner Situation das D von V größer sein konnte,
als das D von U plus 1 und damit haben wir gezeigt,
dass dieser Knoten V nicht existieren kann, V kann es nicht geben,
diese Annahme ist falsch und damit gilt für alle Knoten,
dass das D von V gleich Delta SV ist.
Damit ist gezeigt, dass diese Breitensuche tatsächlich
kürzeste Pfade berechnet
Und was hier schon mal deutlich wird, ist etwas,
was bei Graf-Algorithmen häufig der Fall ist,
dass einem intuitiv klar ist, dass das Afferfahren eigentlich funktionieren müsste.
Also ich glaube schon mit dem Beispiel haben sie nicht mehr wirklich dran gezweifelt,
dass der das Richtige tut und diese D-Werte berechnet.
Und es ist manchmal eben nicht so trivial,
dann zu zeigen, dass es tatsächlich auch korrekt ist.
Und das muss man natürlich streng genommen immer machen,
weil sonst baut man, sonst denkt man manchmal,
das wäre richtig und ist es vielleicht doch nicht richtig.
Und dazu muss man einfach Beweise führen. Diese Art von Beweis,
die wir hier gesehen haben, diesen Widerspruchsbeweis,
um die Korrektheit zu zeigen, ist, wo ist er?
Hier ist ganz typisch für Grafalgorithen, um die Korrektheit von Grafalgorithmen nachzuweisen.
Das werden wir noch ein paar Mal sehen.
Man nimmt einfach das Gegenteil an und zeigt,
dass das im Grafen nicht vorkommen kann.
Und auch ganz typisch ist dieses Entfernungsargument, dass man sagt,
man nimmt sich das, was am nächsten dran liegt und entscheidet darüber.
Also das ist einfach eine Beweistechnik,
die hier in der einfachsten Form auftritt,
einfach um diese zu zeigen,
dass die kürzesten Pfade
korrekt berechnet sind
So, die anderen beiden Eigenschaften, diese sehr,
sehr wichtigen Graftheoriems hier, die brauchen wir nicht mehr zeigen,
das ist eigentlich aus dem Algorithmus klar,
dass die Knoten alle schwarz sind, wenn sie erreichbar sind.
Und der dritte Teil ist, dass wir mit den Kanten
Pi von V eben die kürzesten Pfade auch wirklich beschreiben.
Ja, muss man durch streng genommen jetzt auch noch formal aufschreiben.
So, damit haben wir den ersten Graf-Algorithmus,
der uns schon zwei ganz wichtige Probleme löst.
Das erste ist, er kann Erreichbarkeit bestimmen,
wir können Zusammenhangskomponenten bestimmen in einem Graf.
Wir können sagen, was können wir von wen aus erreichen?
Und wir können kürzeste Pfade bestimmen
In dem Grafen von einem Startknoten aus und können dann sozusagen
die Knoten ordnen, wenn sie so wollen.
Nach einer Entfernung, so einem Startknoten,
vielleicht gibt es auch Anwendungen, wo dieser Wert relevant ist.
In der Praxis ist der in der Regel nicht relevant,
kann ich Ihnen auch gleich sagen,
weil wenn Sie in der Praxisentfernung, also kürzeste Pfade ausrechnen,
haben Sie normalerweise an diesen Kanten nicht eine Einheitslänge stehen,
sondern eine tatsächliche Distanz.
Wenn Sie also auf einer Stadtkarte eine Entfernung ausrechnen,
dann müssen Sie immer die Länge der Straße zwischen zwei Knoten
berücksichtigen und da können Sie nicht sagen,
die sind alle erstmal gleich lang
Es gibt natürlich Anwendungen, wo es vielleicht so ist,
aber in der Regel hat man da Distanzen an den einzelnen Kanten dran stehen.
Und dann brauchen wir noch einen anderen Algorithmus als den hier,
aber zumindest können wir hier schon für diesen diskreten Fall,
alle Kanten sind gleich lang, so eine Entfernung.
Bestimmt. So, das war die Breitensuche.
Wir werden uns dieser kürzesten Wegeproblematik noch zuwenden in Kürze.
Aber bevor wir das vertiefen, schauen wir uns
die andere Strategie an, um Grafen zu durchlaufen.
Das ist die Tiefensuche
Okay, die Strategie, die wir eben hatten,
war von einem Punkt aus möglichst alles,
was dicht dran ist, als erstes zu besuchen.
Und dann das, was wieder dicht dran ist.
Also immer möglichst wie so ein Stein, der ins Wasser fällt,
immer erst die Ringe, die möglichst nah dran sind.
Die betrachten wir als erstes. Bevor wir was anderes machen.
So, jetzt machen wir es andersrum. Wir sagen bloß weg vom Startknoten,
so weit wie möglich weg, so schnell wie möglich weg.
Wir suchen in die Tiefe. Wir entfernen uns so schnell
wie möglich von dem Startknoten. Das ist erstmal verwirrend,
weil jetzt ist es nicht mehr so klar,
wie wir das systematisch tun können,
wenn wir uns davon entfernen, Wie stellen wir sicher,
dass wir tatsächlich auch den ganzen Grafen besuchen,
jeden Knoten auch möglichst nur einmal?
Das ist jetzt nicht mehr so trivial bei diesem Ansatz.
Allerdings können wir das machen und wir müssen streng genommen nur ein kleines Detail ändern,
nämlich die Art und Weise, wie wir die Knoten speichern,
die noch Nachbarn haben, die wir nicht betrachtet haben.
Bei der breiten Suche haben wir hier für eine Warteschlange verwendet
und haben dadurch sichergestellt, dass das,
was wir früh gesehen haben, wir auch früh bearbeiten.
Bei einer tiefen Suche verwenden wir einfach einen Stapel.
Wir sagen, das, was wir als letztes gesehen haben,
werden wir als erstes auch wieder bearbeiten
Ja, und dadurch stellen wir sicher,
dass wir erstmal immer in die Tiefe also gehen,
also uns von den Startknoten weg bewegen. Okay,
die Strategie der Tiefensuche ist also, wir suchen in die Tiefe,
das heißt für jeden Knoten arbeiten wir zuerst den ersten Nachfolger vollständig ab.
Dann den zweiten und dann den dritten und so weiter.
Okay, das ergibt sich hier noch nicht so richtig.
Also statt einer Schlange verwenden wir einen Stapel,
den Stapel werden wir nicht explizit als Datenstruktur realisieren,
da wird nicht irgendwie ein Stapel vorkommen,
sondern was wir einfach machen werden, ist,
wir werden eine Rekursion verwenden.
Wir rufen einfach die Funktion rekursiv auf dann stehen ja
die Funktionsrümpfe auf einem, auf dem Ausführungsstapel.
Und das ist der Stapel, den wir nutzen.
Wir benutzen den implizit durch die Realisierung des Algorithmus durch eine Rekursion.
Wir werden auch wieder die Farben weiß-grau und schwarz haben und die bedeuten auch das Gleiche.
Weiß heißt, der Knoten wurde noch nicht besucht.
Weißer Fleck auf der Landkarte. Grau heißt, er wurde besucht,
aber die Atiazenzliste ist noch nicht abgearbeitet und schwarz heißt,
er ist vollständig abgearbeitet.
Wir werden wieder etwas berechnen während der Algorithmus läuft.
Wir werden jetzt wieder einen D-Wert und einen zusätzlichen Wert F
berechnen. D und F sind jetzt aber was anderes und
insbesondere müssen sie bei D jetzt umschalten
D ist keine Distanz mehr. Nee, ist ein Zeitpunkt ab jetzt.
Wenn wir über Tiefensäure reden, ist es immer ein Zeitpunkt.
Und D steht für die Entdeckungszeit. Also es ist der Zeitpunkt,
wo wir den Knoten das erste Mal betrachtet haben.
D ist also die Discovery-Time. Und dann gibt es noch
das F und das F ist der Zeitpunkt,
wo wir den Knoten das letzte Mal betrachten.
Das heißt, wo dieser Knoten schwarz wird.
Das ist die Finishing-Time. Also eine Discovery und eine Finishing-Time
. Okay, offensichtlich, achso, die können wir natürlich
genau markieren im Algorithmus. Der D-Zeitpunkt ist der Zeitpunkt,
wo die Farbe des Knotens von weiß
auf grau geht
Und dann haben wir ihn das erste Mal gesehen, Ikaoden.
Und der F-Zeitpunkt ist der Zeitpunkt, wo die Farbe von Grau auf schwarz geht.
Das heißt, wo wir den Knoten vollständig abgearbeitet haben.
Offensichtlich gilt DVUs kleiner als F&U. Klar, also erst mal
müssen wir den entdecken. Erstmal wird der Knoten von Weiß
nach Grau gefärbt und dann irgendwann später mal von Grau nach schwarz.
Hier nur noch mal der Hinweis, das D von U
ist kein Abstand mehr. Ja, es ist ein Zeitpunkt.
Auch hier können wir wieder einen Baum kreieren, wenn wir so wollen.
Oder wenn wir den kompletten Grafen abarbeiten, einen Wald.
Das ist der DFS-Wald. Das heißt, kannten die bei
erst maligen Besuch durchlaufen werden, beschreiben eine Menge von Bäumen. Das bedeutet,
wir machen hier das Gleiche wie bei der Breitensuche,
wenn wir das erste Mal einen Knoten sehen,
der wird von Weiß nach Grau, dann wissen wir,
über welche Kante wir zu dem Knoten gelangt sind.
Und diese Kante merken wir uns, indem wir sagen,
der Knoten von dem, was wir gekommen sind, ist der Vorgänger.
Dann kriegen wir wieder seine Warmstruktur und wir haben mit P
wieder die Vorgänger. So, okay,
also wir berechnen jetzt drei Dinge in dem Algorithmus,
Pi sowie vorher, ein D-Wert, ein Erfährt.
Das ist keine Distanz mehr, sondern das sind zwei Zeitpunkte
So, das ist die Tiefensuche. Die besteht jetzt aus
zwei Funktionen. Das erste ist erst mal die Funktion selber,
die die Initialisierung vornimmt und die die rekurive Funktion aufruft.
Wir initialisieren, wir betrachten alle Knoten,
alle Knoten werden weiß, der P-Wert wird auf Neil gesetzt.
Hier ist unsere Uhr, wir haben eine diskrete Uhr,
da steht am Anfang eine Null drin und immer,
wenn wir so einen Zeitstempel brauchen, um eine Zeit zu markieren,
erhöhen wir das einfach um eins.
So, dann betrachten wir Hier in einer Vorschleife alle Knoten,
wenn der Knoten weiß ist, dann rufen wir unsere Tiefensuche auf.
Ja? Okay. Das ist, hier ist es ein Unterschied zur Breitensuche.
Die Breitensuche haben wir nur mit einem Knoten gestartet.
Hier würden wir die Breitensuche so lange immer,
die Tiefensuche immer so lange wieder neu starten,
wie wir noch Knoten haben, die weiß sind.
Also wir gehen da jetzt hier los. Der erste Knoten
wird natürlich an Knoten sein, der weiß ist.
Haben wir alle weiß gefärbt und wir starten unsere rekursive Tiefensuche.
So, diese Funktion läuft jetzt für einen Knoten.
Uh, ja? Oh, das erste,
was sie macht, ist, sie sagt,
Den Knoten haben wir jetzt besucht, der wird grau.
Das ist der Zeitpunkt, wo wir den Knoten von weiß nach grau färben.
Der war ja weiß und jetzt haben wir ihn das erste Mal besucht.
Jetzt wird er grau. Diesen Zeitpunkt merken wir uns.
Die Zeit wird um eins erhöht, also unser Zähler hier.
Diese Zeitzähler wird um eins erhöht und die Discovery Time wird festgesetzt für
den Knoten-U auf die aktuelle Zeit, die wir haben.
So, dann gehen wir durch die Addizenzliste durch.
Machen wir hier in dieser Vorschleife. Und wir gucken,
ob der Knoten hier weiß ist.
Das ist ein Knoten, den wir noch nicht betrachtet haben.
Wenn dem so ist, dann setzen wir die Vorgängerrelation dieses
Knotens und rufen die Funktion rekusiv auf
Und jetzt sieht man den Unterschied zur breiten Suche.
Bei der breiten Suche haben wir gesagt, okay, wir merken uns,
dass erstmal in der Warteschlange und machen mal weiter mit den anderen.
Hier steigen wir rekrusiv direkt da rein. Wir sagen,
okay, wir haben einen Knoten gefunden, der es noch weiß,
super, da gehen wir hin und gucken mal,
was da noch los ist und machen da weiter.
Und würden dann hier in die Funktion wieder aufrufen.
Irgendwann kommen wir von diesem rekrusiven Aufruf wieder zurück.
Irgendwann ist da abgearbeitet, kommen wir hier wieder an.
Und dann würden wir die nächste Kante betrachten. Und dann
die nächste und die nächste und irgendwann haben wir alle betrachtet,
dann müssen wir alle kannten, die,
also alle Nachbarn von dem Knoten U
sind grau
Und wir können den Knoten U schwarz werben.
Das ist der zweite Zeitpunkt, den wir uns merken.
Das ist die Finishing Time. Der Knoten ist vollständig bearbeitet.
Wir setzen unsere Uhr, die zählen wir jetzt wieder einen Schritt weiter.
Und F&U wird auf die aktuelle Zeit gesetzvollständig abgearbeitet.
Ja, okay, das ist die Tiefensuche.
Hier ist wieder ein schönes Beispiel. Wir werden die Tiefensuche
jetzt, die kam natürlich auch auf ungerichteten Grafen machen.
Wir werden die auf gerichteten Grafen jetzt betrachten.
Hier ist mein Graf. Der hat sechs Knoten.
Hier, UVW XYZ und eine ganze Reihe von Kanten
Am Anfang sind alle weiß und wir beginnen willkürlich bei diesem Knoten
uh hier. Wir hatten auch bei jedem anderen anfangen können.
Das ist jetzt zufällig bei mir der Knoten,
der vorne in der Liste der Knoten steht.
Okay, der Knoten wird grau gefärbt und kriegt die Discovery-Zeit 1.
Also hier vor dem Schrägstrich steht immer die Discovery-Zeit.
Er kriegt die Discovery-Zeit 1. Jetzt kommt der rekrusive Aufruf,
D von uh und wir sind also jetzt auf U,
wir rufen das auf und in der Vorschleife betrachten wir die Nachbarn.
In der Atlazenzliste ist V, jetzt willkürlich der nächste Knoten,
hätte auch X sein können, ist bei mir einfach jetzt V zufällig.
V kriegt die Discovery-Zeit 2. Und während wir V schon,
also während wir V das erste Mal sehen, starten wir gleich den rekrusiven Aufruf.
Wir verlassen U und gehen zu V und machen mal V weiter. V hat jetzt den Wert,
die Discovery-Zeit 2 ist grau, wir machen mit V weiter,
wir gucken V hat noch eine ausgehende Kante,
die geht zu Y. Dirk Knoten ist weiß, der kriegt die Discovery-Zeit 3,
der Knoten wird grau und wir verlassen V direkt,
gehen direkt zu Y, machen wir Y weiter.
Wir gucken Y. Y hat auch eine ausgehende Kante,
die führt uns zu X. Okay,
das gleiche Spiel nochmal, wir laufen zu X,
der kriegt die Discovery-Zeit 4 und wird ebenfalls grau gefärbt.
In der Addizenzliste von X finden wir eine Kante,
die führt uns zu V. V ist zu dem Zeitpunkt schon grau.
Und deswegen laufen wir da nicht lang. Wir besuchen immer
nur die weißen Knoten. Damit wäre die Addizenzliste von X
vollständig abgeschlossen. Diese Kante ist hier markiert als eine Kante,
die wir quasi nicht explorieren.
Also wir gehen nicht zu dem nächsten Knoten hin.
Deswegen ist die jetzt hier so gestrichelt.
Warum dann B steht, erzähle ich Ihnen später.
Okay, jetzt haben wir alle Kanten betrachtet,
die den Coden X verlassen
Wir beenden die Vorschleife. Der Knoten wird schwarz und kriegt
seine Finishing-Zeit. Zeitpunkt 5. Von X aus gehen wir jetzt,
ist der rekrusive Aufruf beendet. Wir gehen also zu dem
Knoten von dem aus, wie er X aufgerufen haben.
Das ist der Knoten Y. So, von Y sehen wir,
bei Y sehen wir, wir haben alle Kanten,
ausgehende Kanten betrachtet.
Die Vorschleife wird beendet, der Knoten wird schwarz und kriegt die Finishing-Zeit 6.
Von da gehen wir zu Knoten V. Und da passiert das Gleiche.
Es gibt keine Kante mehr, die wir noch nicht betrachtet haben.
Der Knoten wird schwarz, Finishing zahlt
7. Wir gehen zur
Und auch da passiert, dass gleiche U hat keine weitere,
also, Entschuldigung, U hat noch eine,
U hat noch eine Kante, nämlich die Kante, die hier runterführt.
Die haben wir noch nicht betrachtet. Die führt uns auf
einen schwarzen Knoten. Das heißt, da machen wir nichts.
Wir machen keinen rekursiven Aufruf. Wir machen den nur,
wenn die Knoten weiß sind. Okay, da gucken wir runter,
sehen diese Kante, die wird wieder gestrichelt,
weil die führt nicht zu einem rekursiven Aufruf.
Die hat eine Markierung, sage ich ihnen, wie gesagt,
später, warum die F heißt, die geht hier runter.
Und wir haben den Knoten vollständig abgearbeitet, Finishing Zeit.8, Knoten wird schwarz.
Jetzt sind wir erstmals, zurück in dem Algorithmus, wieder in dieser Vorschleife angekommen. Ja,
mit dem ersten Knoten, uh,
den rekursiven Aufruf gestartet und sind hier rekursiv immer abgestiegen,
wieder aufgestiegen und hier wieder angekommen an diesem Zeitpunkt,
zu diesem Zeitpunkt, ja, weil es keinen Knoten mehr gab,
den wir noch weiß hätten, werden können.
Ups. So, was machen wir zu dem Zeitpunkt?
Jetzt suchen wir in der Liste der Knoten,
ob es noch weiße Knoten gibt, dann würden wir hier langlaufen,
würden sagen, V ist ja schon schwarz, X ist schwarz,
Y ist schwarz und dann sind wir weh, ne?
Wer es noch weiß, super.
Jetzt geht das ganze Spiel weiter, ne?
Wir gehen mit W wieder los,
rekursiver Aufruf,
W wird grau
Der Knoten kriegt den Zeitpunkt 9, als Discovery-Teil zugeordnet,
von W aus explorieren wir die Adjazzenz. Die erste Kante,
die wir sehen, wäre diese hier und die führt uns zu einem schwarzen Knoten,
da machen wir nichts, kein rekrusiver Aufruf, deswegen wird die Kante gestrichelt.
Da passiert nichts, hat wieder eine Markierung, C,
eine andere, da gehen auch gleich noch was die Markierung bedeuten,
dann suchen wir die nächste Kante, die führt uns zu Z,
Z ist weiß, das gibt wie einen rekrusiven Aufruf,
Z wird auf, wir rufen DFS Visit mit Ted auf,
Startpunkt oder Discovery-Zeit wird auf 10 gesetzt.
Wie haben wir eine Kante, wird von Z auf sich selber.
Da ist der Knoten natürlich schon grau zu dem Zeitpunkt,
wird also nicht durchs Laufen, passiert also nichts.
Dann haben wir alle Kanten an Set bearbeitet, Z kriegt,
wird schwarz, die Finishing-Zeit wird auf elf gesetzt,
wir gehen zum Vorgängerknoten, der Knoten hier hatte die,
ja, der ist jetzt auch, sie sind auch alle Kanten bearbeitet,
kriegt hier die Farbe schwarz und der kriegt die Finishing-Zeit 12 und der Algorithmus würde terminieren.
Wir gehen wieder in die Hauptstreife, wir würden sehen,
alle Knoten sind nicht mehr weiß und damit ist Schluss.
Das ist unser Berechnungsergebnis hier, was wir haben
Ja, bei der Tiefensuche sieht man nicht so direkt,
wozu das gut ist. Also wir haben gesehen,
wir sind systematisch durch den Grafen durchgelaufen.
Wir haben alle Knoten einmal besucht. Wir haben uns tendenziell
immer versucht, von dem Knoten wegzubewegen.
Das funktioniert aber nicht unbedingt. Also man könnte ja meinen,
ah, damit berechnen wir jetzt die längsten Pfade oder sowas,
möglichst schnell weg von irgendwas, führt uns zu den längsten fahren.
Funktioniert natürlich nicht, weil wir haben ja gesehen,
von U aus sind wir zu Faust,
Y zu X gelaufen und wir haben uns natürlich nicht von U weg bewegt.
Wir sind natürlich noch nah an X dran.
Es ist irgendwie nur eine andere Strategie,
die wir verwenden
Ja, für diese Strategie gibt es viele Anwendungen, die werden wir noch sehen.
Viele Dinge, die man damit tun kann. Eine Sache
kann man damit aber auch machen, das sehen wir schon direkt.
Also wenn wir einen ungerichteten Grafen hätten, den haben wir hier nicht,
hätten wir mit der Strategie auch die Zusammenhangskomponenten berechnen können.
Das wäre hiermit auch gegangen. Das ging auch mit der breiten Suche,
aber hiermit auch,
weil wir wüssten immer genau, wenn immer dann,
wenn wir wieder in dieser Vorschleife ankommen,
haben wir eine Menge von Knoten bearbeitet und wir konnten die anderen scheinbar nicht erreichen,
ja,
und dann suchen wir uns den nächsten und hier
würde dann eine neue Zusammenhangskomponente aufgefunden
Hier ein weiterer Knoten wäre, der noch weiß ist.
Das können wir hiermit schon mal machen. Für den ungerichteten Fall.
Für den gerichteten Fall müssen wir uns noch genau anschauen,
was da der Zusammenhang bedeutet und wie man den berechnen kann.
Okay, bevor wir sehen können,
was wir alles mit diesem Algorithmus machen können,
müssen wir uns mit der Struktur auseinandersetzen.
Und wir müssen uns anschauen, was eigentlich gilt für diese Werte,
die wir da berechnen. Was kommt da so raus?
Es gibt zwei entscheidende Eigenschaften, die die Tiefensuche hat.
Die sind zusammengefasst in zwei Theorieme.
Die heißen Klammerungstheorien und das Theorien der weißen Pfade
Ja, wir haben so schildernde Namen und die müssen wir uns anschauen.
Das Klammerungstheorium ist das Erste und ich zeige ihnen mal,
als erstes das Bild dazu, dann sehen Sie gleich, wovon wir reden.
Wir betrachten mal den Zeitstrahl, denn sehen Sie hier unten,
ja, also hier sehen Sie diskrete Zeiten, ja.
Das ist unsere Time-Funktion, also die Time-Variable, die immer
in diskreten Schritten weiterzählt. Zu jedem Zeitpunkt passiert irgendwas.
Entweder entdecken wir einen Knoten oder wir schließen ihn ab. Ja,
zum Zeitpunkt eins haben wir den Knoten S entdeckt und dann haben wir
irgendwie alles Mögliche gemacht und zum Zeitpunkt 10 hätte wir diesen Knoten,
haben wir den Knoten schwarz gefärbt und würden ihn nicht weiter betrachten.
Okay, das Beispiel ist jetzt ein anderes, es muss
ein bisschen komplexer werden an dieser Stelle, das Beispiel.
Es bezieht sich jetzt nicht mehr auf das Beispiel,
was wir gerade gesehen haben, sondern auf dieses hier.
So, okay, wenn wir den Algorithmus laufen lassen,
Z zum Beispiel würde zu einem Zeitpunkt 2 entdeckt,
unterm Zeitpunkt 9 würde Z schwarz gefärbt nicht weiter betrachtet.
Das heißt, D und F beschreiben einen Zeitintervall, ja,
und das ist das Zeitintervall, wo der Knoten auf dem Stapel liegt.
Bei D wird er quasi auf den Stapel draufgelegt. Da wird er bearbeitet,
der Knoten wird grau und bei der Finishing-Zeit wird er abgearbeitet,
er wird vom Stapel wieder heruntergenommen, der Knoten wird schwarz.
Das heißt, das ist so eine Art Lebenszeit auf dem Stapel, die wir sehen.
Und das wird beschrieben durch dieses Intervall von D bis F,
für diesen Knoten S. So, und was Sie hier sehen,
ist, dass diese Zeitintervalle eine Struktur haben,
die sind nicht beliebig angeordnet, sondern die haben eine Struktur.
Und die Struktur ist, dass sie entweder so nebeneinander stehen,
das heißt, die Intervalle haben einen leeren Schnitt,
die haben nichts miteinander zu tun, oder aber Oder aber,
sie sind komplett darin enthalten.
Also, was wir nicht sehen, ist der Zustand,
wir haben das eine Intervall,
das fängt an und dann fängt ein neues Intervall an und
dann haben die so einen Überlapp und dann endet das andere Intervall und dann endet das Zweite.
Also, so ein Szenario sehen wir nicht. Entweder,
wenn hier drinnen eins anfängt, dann wird das hier drinnen auch abgeschlossen,
ist also komplett enthalten in dem Intervall oder es ist des Jungs,
hat damit nichts zu tun.
Diese beiden Fälle gibt es nur. Und wenn man sich überlegt,
wie der Algorithmus arbeitet, ist es eigentlich auch klar,
weil ich habe einen Knoten, David Recosiv bearbeitet,
dann mache ich einen rekusiven Aufruf und bearbeite den Knotenset.
Und bevor ich diesen Knoten esse, überhaupt wieder betrachte,
muss der rekusive Aufruf von Z beendet sein.
Das heißt, die Finishing-Zeit hier liegt auf alle Fälle vor der Finishing-Zeit des Knotens S.
Und deswegen haben wir diese Struktur. So,
weil das so ist, können Sie sich die Zeiten auch vorstellen,
wie Klammerpaare. Ja, und dann sehen Sie hier entsprechend,
dass es die öffnende Klammer von S, und das ist die schließende Klammer von S.
Das ist die öffnende Klammer von Z und die schließende Klammer
von Z. Ja, und dann kriegen Sie ein wohldefinierten Klammerausdruck.
Die haben, die sind sauber ineinander geschachtet. Das Entscheidende,
das sagt das Klammerungstheorie und das Entscheidende am Klammerungstheorien sind Nicht die drei Fälle,
die auftreten, die werden wir gleich beschreiben,
sondern das ist der eine Fall, der nicht auftritt.
Was nicht auftritt, ist, dass diese Intervalle sich einfach
so partiell schneiden. So, das ist hier formuliert,
also nach Durchführung eines DFS-Algorithmus gelten für die Entdeckungs- und Endzeiten D&F,
für je zwei Knoten UNV.
Wir bezeichnen mit 11 von U, das Intervall von DU bis FU,
also das Zeitintervall, wo der Knoten lebt.
Das ist die Lifetime L. Und für dieses gibt es jetzt drei Fälle.
Erster Fall, 11 von U, geschnitten 11 von V ist die leere Menge.
Die haben nichts miteinander zu tun, wenn dem so ist,
dann ist U zu V in unserem DFS-Wald überhaupt nicht verwandt.
Die haben nichts miteinander zu tun. Da ist weder U,
ein Vorfahrer von V, noch V,
ein Vorfahrer von U, die sind getrennt.
Die sind irgendwie in einer anderen Beziehung zueinander,
aber nicht in einer Vorfahre nachfahre bis hier.
Zweite Möglichkeit ist, L von U,
also die Lebenszeit von U ist enthalten in der Lebenszeit von V,
dann ist U im DFS-Wald ein Nachfahre von V. Also in dem Baum kommt der Knoten dann irgendwo weiter unten.
Das können wir symmetrisch auch umdrehen,
wenn L von U eine Obermenge von L von V ist,
dann ist U im DFS-Wald ein Vorfahrer von V. Also
zwei und drei sagen eigentlich das Gleiche,
wir tauschen nur UNV aus
Das Wichtigste in dem Theorien ist das, was hier nicht steht.
Viertens, es gibt eben nicht den Fall,
dass L von U und L von V einen nicht leeren Schnitt haben,
ohne dass die Intervalle vollständig ineinander enthalten sind.
Es gibt nur diese drei der vier möglichen Fälle,
Szenarien, die wir haben. Okay, so,
jetzt müssen wir noch zeigen, dass das auch tatsächlich so ist.
Wir gehen mal davon aus, wir haben erst U entdeckt und dann V.
Also RSU, dann V. Also wir haben unseren,
hier unseren Zeitstrahl,
das ist Time
Das geht hier so lang. Und dann zu irgendeinem Zeitpunkt haben wir D von U.
Zu dem Zeitpunkt haben wir den Knoten U entdeckt.
Dann läuft der Algorithmus weiter, macht alles Mögliche weiter.
Dann kommt der Zeitpunkt D von V. Wir haben V entdeckt.
Und das Einzige, was wir sagen, ist,
wir wählen U und V so aus, dass UVV entdeckt wurde.
Sonst tauschen wir einfach O und V aus.
Okay, so, wir unterscheiden zwei Fälle.
Der erste Fall ist D von V ist kleiner als F&U.
Also irgendwo in diesem Zeitstrahl muss ja jetzt das F&U sein.
Irgendwann muss ja das U beendet werden. Jetzt könnte es
eine Möglichkeit wäre, dass D von V kleiner ist als F&U.
Das heißt,
F&U wäre hier irgendwo
Das heißt, die Lebenszeit von U ist das hier.
Das ist L von U. So,
hier beginnt die Lebenszeit von V. Wir wissen nicht,
wie weit die hier rübergeht, aber da beginnt die erstmal.
So, was müssen wir zeigen? Wir müssen zeigen,
dass das F&U irgendwo hier zwischen liegt.
Das darf nicht auf der Seite liegen. Dann hätten wir
genau den Fall, den wir nicht haben wollten.
So, das Erste, was wir sehen, ist,
zum Zeitpunkt DVV ist die Farbe des Knotens U-Grau.
Das ist klar. Hier wird U-Grau gefärbt. Hier wird
U-Schwarz gefärbt. Zu dem Zeitpunkt ist U offensichtlich grau,
muss so sein. So, damit ist U Ein Vorfahrer
von V, denn U ist noch nicht vollständig abgearbeitet.
Wir sind irgendwo in dem Abstiegsbaum nach unten und wir haben entlang dieser Kanten,
die wir gefolgt haben, immer die Vorgängerrelation.
Also ist U ein Vorfahrer von V. So,
alle Kanten von U werden bearbeitet, sondiert in der Vorschleife,
bevor wir den rekusiven Aufruf von V terminieren.
Bevor wir sagen, hier ist Schluss, ja,
wir betrachten alle Kanten, die da rausgehen.
Und das bedeutet, irgendwann wird diese rekusive Aufruf beendet und
erst dann gelangen wir wieder zu den vorgehenden rekusiven Aufruf.
Das heißt, irgendwo hier gibt es dann den Zeitpunkt, F&V.
Und er kann nicht auf der Seite liegen, weil wir einen Stapel haben.
Okay, in so einem Szenario hätten wir den dritten Fall
des Theoriums, der würde hier eintreffen.
So, jetzt gucken wir mal, das D von V
sei jetzt größer als F&U. So, das bedeutet,
weg, dass DVV ist größer als F&U, das heißt,
hier wäre das F&U und das hier wäre die Lebenszeit unseres Knotens um.
So, das heißt, die Lebenszeit von dem Knoten V,
die beginnt hier Ja, und wir haben offensichtlich hier den ersten Fall.
Wir sehen schon, die werden nichts miteinander zu tun haben,
die beiden Intervalle. Das heißt, zum Zeitpunkt DVV ist
der Knoten U bereits schwarz, der ist bereits schwarz gefärbt.
U ist bereits abgearbeitet, somit ist U kein Vorfahrer von V.
Das geht nur entlang des rekursiven Aufrufs.
V wird nach U entdeckt,
somit ist U kein Nachfahrer von V. Kann auch nicht sein,
weil den Vorgänger hätten wir früher entdecken müssen.
Wir wissen, DVV ist kleiner als F von V.
Also F von V ist irgendwo hier hinten,
Und D von U ist kleiner als FVNU, klar.
Und FVNU ist kleiner als D von V, das hatten wir vorausgesetzt.
Und damit sind die beiden Intervalle komplett getrennt.
Und das ist der erste Fall des Theoriums. Ja,
und der zweite Fall ist mehr oder weniger nur der gespiegelte,
der entsteht, wenn man D von U größer als D von V annimmt.
Okay, das ist das Klammerungstheorie, was hier grafisch dargestellt wird.
Und das ist unser erstes Strukturtheorium, was uns sagt,
was für eine Information in diesen Seiten drinsteckt.
Okay, gut. Damit müssen wir jetzt so ein bisschen mittendrin aufhören.
Wir werden in der nächsten Vorlesung dann die weißen Pfade sehen
und dann anfangen sinnvolle Dinge mit der Tiefensuche zu tun.
Dann war es das für heute