2. INFORMATIK-KLAUSUR Name: Info 13 GK (GA) Aufgabe 1: 02.12.2003 − Seite 1 − Bearbeitungszeit: 225 min Graphentheorie – Zusammenhang Karl Vorwerk ist Staubsaugervertreter und möchte in Odenthal und Umgebung seine Staubsauger loswerden. Heute stehen die Orte Altenberg, Blecher, Glöbusch, Höffe, Neschen, Odenthal, Pistershausen und Scheuren auf seinem Plan. Diese hat er in einer schematischen Karte zusammengetragen, welche wie rechts abgebildet aussieht (Entfernungen in km): a) Stellen Sie den Graphen in Form einer Adjazenzmatrix und in Form einer Adjazenzliste dar. Dabei sollen die Knoten in beiden Darstellungen alphabetisch sortiert sein. B 1,5 1,8 G A 2,8 2,3 3,1 N 0,5 2,1 O S 3,9 2,4 H 0,9 P 2,9 b) Herr Vorwerk will feststellen, ob es möglich ist, alle Orte zu erreichen. Dazu verwendet er die Traversierungen BREITENSUCHE und TIEFENSUCHE (siehe Anlage I) mit Startknoten Blecher. (1) Zeigen Sie mit Hilfe der BREITENSUCHE, dass es Herrn Vorwerk möglich ist, alle Orte zu erreichen. Veranschaulichen Sie dafür jedes Mal, wenn Sie im Algorithmus die mit {∗} markierte Stelle erreichen, den aktuellen Inhalt der Schlange. Zeichnen Sie anschließend den sogenannten „Breitensuchbaum“, der nur die Kanten enthält, die für die BREITENSUCHE benutzt wurden. (2) Verwenden Sie nun die TIEFENSUCHE. Veranschaulichen Sie auch hier an gleicher Stelle den aktuellen Inhalt des Stapels. Zeichnen Sie anschließend den „Tiefensuchbaum“. c) Der Algorithmus von WARSHALL ist auch ein Verfahren, mit dem man testen kann, ob ein Graph zusammenhängend ist oder nicht. Erläutern Sie die Vor- und Nachteile gegenüber dem Algorithmus der BREITENSUCHE. Warum ist das Verfahren für die Fragestellung aus Teilaufgabe b „zu mächtig“ d) Herr Vorwerk hat sich anders entschieden. Statt Staubsauger zu verkaufen möchte er lieber von Blecher aus startend das schöne bergische Land erkunden. Der Reiseführer empfiehlt zwei Routen: Route 1: Die Sightseeing-Tour: Alle Städte werden auf kürzestem Weg besucht. Die Tour endet wieder in Blecher. Route 2: Die Motorrad-Tour: Alle Straßen werden abgefahren. Die Tour endet wieder in Blecher. (1) Geben Sie sowohl die Sightseeing- als auch die Motorrad-Tour an. Sind die Touren in diesem Beispiel eindeutig? (2) Sei nun allgemein ein ungerichteter (!) Graph gegeben. (i) Geben Sie eine allgemeine Bedingung dafür an, dass es in diesem Graphen eine Sightseeing-Tour gibt. (ii) Geben Sie ebenso eine allgemeine Bedingung dafür an, dass es in dem Graphen eine Motorrad-Tour gibt. Geben Sie zusätzlich eine Bedingung dafür an, dass sie eindeutig ist. (3) Im Unterricht wurden zu beiden Problemen Algorithmen entwickelt, welche optimale Touren ermitteln. Nennen Sie beide Algorithmen und diskutieren Sie ihre Unterschiede im Hinblick auf ihre Laufzeitkomplexität. 2. INFORMATIK-KLAUSUR Name: Info 13 GK (GA) Aufgabe 2: Bearbeitungszeit: 225 min 02.12.2003 − Seite 2 − Graphentheorie – kürzeste Wege Gegeben ist der rechts abgebildete Graph: a) Suchen Sie die kürzesten Entfernungen vom Startknoten S8 mit Hilfe des Algorithmus von DIJKSTRA (Anlage II). Veranschaulichen Sie dafür jedes Mal, wenn Sie im Algorithmus die mit { ∗} markierte Stelle erreichen, den aktuellen Inhalt der Variablen Distanz und Vorgaenger. b) Erläutern Sie, was man allgemein unter einem Greedy-Algorithmus versteht und begründen Sie, dass der Algorithmus von DIJKSTRA zu dieser Gruppe von Algorithmen gehört. Nennen Sie Problembeispiele auch außerhalb der Graphentheorie, bei denen der Greedy-Ansatz zum raschen Erfolg führen könnte. c) Nimmt man den Algorithmus von DIJKSTRA als Grundlage, so lässt sich mit minimalen Änderungen ein Algorithmus erstellen, welcher einen minimalen Spannbaum im Graphen berechnet. (1) Welche Änderungen müssen lediglich vorgenommen werden? Hinweis: Bitte notieren Sie nur die Änderungen, nicht den ganzen Algorithmus. (2) Die Bedeutung der Variablen Distanz und Vorgaenger haben nun eine andere als beim DIJKSTRA. Erläutern Sie diese im Unterschied zur ursprünglichen Bedeutung. (3) Nach welchem Namen wird dieser Algorithmus benannt? (4) Begründen Sie, dass die Laufzeit dieses Algorithmus in der Klasse O(n2) liegt. d) Im Unterricht haben Sie den Algorithmus von FLOYD (siehe Anlage III) als Alternative zur Bestimmung des kürzesten Weges kennen gelernt. (1) Beschreiben Sie in eigenen Worten, welche Idee dem Algorithmus zugrunde liegt. Worin liegt der wesentliche Unterschied zum Verfahren von DIJKSTRA? (2) Führen Sie das Verfahren anhand des rechts abgebildeten gerichteten (!) Graphen durch. Geben Sie jedes Mal, wenn Sie im Algorithmus die mit {∗} markierte Stelle erreichen, den aktuellen Inhalt der Variablen Distanz und Zwischenknoten an. (3) Mit Hilfe der Matrix Zwischenknoten ist eine Rekonstruktion des kürzesten Weges zwischen beliebigen Start- und Zielpunkt möglich. Schreiben Sie diesen Algorithmus in DELPHI! ALGORITHMUS Rekonstruiere_Weg Input: Distanz: TAdjazenzmatrix Zwischenknoten: TZwischenknotenMatrix { Array[1..n,1..n] of integer } Start, Ziel: integer Output: Weg: ??? Lokal: ??? ??? (4) Die Äußere Schleife des FLOYD-Algorithmus untersucht zuerst alle Zwischenpunkte (Mitte); im Inneren der Schleife werden dann alle Start- und alle Zielknoten abgearbeitet. In wie fern wirkt sich die Vertauschung der beiden Indizes Start und Mitte auf die Korrektheit des Algorithmus aus? Veranschaulichen Sie dies am Beispielgraphen aus (2). Name: Info 13 GK (GA) Aufgabe 3: 2. INFORMATIK-KLAUSUR Bearbeitungszeit: 225 min 02.12.2003 − Seite 3 − Graphentheorie − gerichtete Graphen a) Die Tatsache, ob ein Graph gerichtet ist oder nicht spielt bei vielen Algorithmen eine große Rolle. So ist z. B. der Algorithmus von KRUSKAL nur auf ungerichteten Graphen anzuwenden. Existiert in einem gerichteten Graphen zu jeder Kante a→b auch eine Kante b→a, so spricht man von einem symmetrischen Graphen, welchen man in einen ungerichteten Graphen konvertieren kann. Geben Sie einen DELPHI-Algorithmus an, welcher feststellt, ob ein Graph symmetrisch ist oder nicht. Bestimmen und begründen Sie das Laufzeitverhalten Ihres Algorithmus. ALGORITHMUS Prüfe_auf_Symmetrie Input: Matrix: TAdjazenzmatrix { Array[1..n,1..n] of integer } Output: symmetrisch: boolean Lokal: ??? ??? b) Sei G ein gerichteter Graph mit n Knoten. Eine Senke ist ein Knoten mit Eingangsgrad n−1 und Ausgangsgrad 0; eine Quelle ist ein Knoten mit Eingangsgrad 0 und Ausgangsgrad n−1. Hinweis: Der Ausgangsgrad eines Knotens ist die Anzahl der abgehenden Kanten; der Eingangsgrad die Anzahl der eingehenden Kanten. (1) Zeichnen Sie eine Graphen mit 6 Knoten, welcher eine Senke und eine Quelle enthält. (2) Begründen Sie: Jeder gerichtete Graph besitzt höchstens eine Senke und höchstens eine Quelle. (3) Entwickeln Sie einen Algorithmus, welcher mit Hilfe der Adjazenzliste oder der Adjazenzmatrix in Laufzeit O(n2) feststellt, ob es eine Senke gibt. Begründen Sie, dass Ihr Algorithmus in der geforderten Laufzeitkomplexität liegt. 2. INFORMATIK-KLAUSUR Anlage I zur ALGORITHMUS Input: Output: Lokal: Breitensuche Startknoten: integer Liste: Ergebniskanten: Besucht: Schlange: Zielknoten: { Initialisierung } • Ergebniskanten ← „neue Liste“ • Schlange ← „neue Schlange“ • Für alle Zielknoten tue: • Besucht ← false • Liste[Zielknoten].AnAnfang • Schlange.Enqueue(Startknoten) • Besucht[Startknoten] ← true TAdjazenzliste TLinList array of boolean TQueue integer { über TKantenelement } { über TKnotenelement } { Algorithmus } • Solange NICHT Schlange.Empty tue: • Startknoten ← Schlange.Front • Solange NICHT Liste[Startknoten].AmEnde UND Besucht[Liste[Startknoten].Aktuell] tue: • Liste[Startknoten].Vor • Falls NICHT Besucht[Liste[Startknoten].Aktuell] dann: • Zielknoten ← Liste[Startknoten].Aktuell • Schlange.Enqueue(Zielknoten) • Besucht[Zielknoten] ← true • Ergebniskanten.Einfuegen(Startknoten − Zielknoten) sonst: • Schlange.Dequeue ALGORITHMUS Input: Output: Lokal: Tiefensuche Startknoten: integer Liste: Ergebniskanten: Besucht: Stapel: Zielknoten: TAdjazenzliste TLinList array of boolean TStack integer Ersetze in Breitensuche: Schlange durch Stapel sowie die Methodenaufrufe Enqueue Dequeue Front {∗} durch durch durch Push Pop Top { über TKantenelement } { über TKnotenelement } 2. INFORMATIK-KLAUSUR Anlage II zur ALGORITHMUS Input: Output: Lokal: Dijkstra Matrix: Startknoten: Distanz: Vorgaenger: Erledigt: MinKnoten: Knoten: { Initialisierung } • Für Knoten ← 1 bis n tue: • Distanz[Knoten] ← maxInt • Vorgaenger[Knoten] ← −1 • Erledigt[Knoten] ← false • Distanz[Startknoten] ← 0 TAdjazenzmatrix { Array[1..n,1..n] of integer } integer array[1..n] of integer array[1..n] of integer array[1..n] of boolean integer { hat kleinste Distanz zum Startknoten } integer { durchläuft alle möglichen Knoten } { bedeutet soviel wie: ∞ } { Algorithmus } • Wiederhole n mal: • MinKnoten ← Knoten_mit_kleinster_Distanz {∗} • Falls MinKnoten ≠ −1 dann: • Erledigt[MinKnoten] ← true • Für Knoten ← 1 bis n tue: • Falls NICHT Erledigt[Knoten] UND Distanz[MinKnoten] + Matrix[MinKnoten, Knoten] < Distanz[Knoten] dann: • Distanz[Knoten] ← Distanz[MinKnoten] + Matrix[MinKnoten, Knoten] • Vorgaenger[Knoten] ← MinKnoten Hilfsfunktion zur Bestimmung des Knotens mit minimaler Distanz zum Startknoten: ALGORITHMUS Knoten_mit_kleinster_Distanz Output: MinKnoten: integer { hat kleinste Distanz zum Startknoten } Lokal: MinDistanz: integer Knoten: integer { durchläuft alle möglichen Knoten } • MinDistanz ← maxInt { erst mal von größtmöglicher Distanz ausgehen } • MinKnoten ← −1 • Für Knoten ← 1 bis n tue: • Falls NICHT Erledigt[Knoten] UND Distanz[Knoten] < MinDistanz dann: • MinDistanz ← Distanz[Knoten] • MinKnoten ← Knoten Anlage III zur ALGORITHMUS Input: Output: 2. INFORMATIK-KLAUSUR Floyd Matrix: Distanz: Zwischenknoten: Start, Ziel, Mitte: TAdjazenzmatrix TAdjazenzmatrix TZwischenknotenMatrix integer { Array[1..n,1..n] of integer } { Array[1..n,1..n] of integer } Lokal: { Initialisierung } • Für Start ← 1 bis n tue: • Für Ziel ← 1 bis n tue: • Zwischenknoten[Start, Ziel] ← −1 { es gibt noch keinen Zwischenknoten } • Distanz ← Matrix { Distanz[x,y] = maxInt ⇔ Es existiert keine Kante von Knoten x nach Knoten y } { Algorithmus } • Für Mitte ← 1 bis n { d. h. durchlaufe mit Mitte alle Knoten } tue: • Für Start ← 1 bis n { d. h. durchlaufe mit Start alle Knoten } tue: • Für Ziel ← 1 bis n { d. h. durchlaufe mit Ziel alle Knoten } tue: • Falls Distanz[Start, Mitte] + Distanz[Mitte, Ziel] < Distanz[Start, Ziel] UND Start ≠ Ziel dann: • Distanz[Start, Ziel] ← Distanz[Start, Mitte] + Distanz[Mitte, Ziel] • Zwischenknoten[Start, Ziel] ← Mitte {∗} 2. INFORMATIK-KLAUSUR 02.12.2003 − Seite 1 − LÖSUNGEN Graphentheorie − Zusammenhang Lösungen Aufgabe 1: a) Adjazenzmatrix: A A B G H N O P S B G H 1,5 1,5 1,8 1,8 2,8 2,3 3,1 → → → → → → → → 2,1 2,4 2,9 2,1 2,4 2,9 S 3,1 0,5 3,9 0,9 0,5 3,9 0,9 Adjazenzliste: A B G H N O P S N O P 2,8 2,3 B (1,5) A (1,5) B (1,8) O (2,4) A (2,8) A (2,3) H (2,9) A (3,1) → → → → → → → → N (2,8) → O (2,3) → S (3,1) G (1,8) O (2,1) P (2,9) S (0,5) G (2,1) → H (2,4) → S (3,9) S (0,9) N (0,5) → O( 3,9) → P (0,9) b.1) Die Reihenfolge lautet: B, A, G, N, O, S, H, P, der zugehörige Baum und die Schlange sehen wie folgt aus: B B, A B, A, G A, G A, G, N A, G, N, O A, G, N, O, S G, N, O, S N, O, S O, S O, S, H S, H S, H, P H, P P B 1,5 1,8 G A 2,8 2,3 3,1 N S O 0,9 P 2,4 H b.2) Die Reihenfolge lautet: B, A, N, S, O, G, H, P, der zugehörige Baum und der Stack sehen wie folgt aus: B B, A B, A, N B, A, N, S B, A, N, S, O B, A, N, S, O, G B, A, N, S, O B, A, N, S, O, H B, A, N, S, O, H, P B, A, N, S, O, H B, A, N, S, O B, A, N, S B, A, N B, A B B 1,5 A 2,8 N G 0,5 2,1 O 3,9 2,4 H S P 2,9 2. INFORMATIK-KLAUSUR LÖSUNGEN 02.12.2003 − Seite 2 − c) Tabellarische Darstellung der... Vorteile von WARSHALL gegenüber BS Nachteile gegenüber BS Verbindbarkeit von jedem Knoten zu jedem Laufzeit: O(k3) statt O(k2) Knoten wird überprüft Einfache Implementierung über Matrix viel Speicherplatz O(k2) für Ergebnisspeicherung Leichte Erweiterung zur kürzeste-Wegebenötigt Adjazenzmatrix als Eingabe Algorithmus (FLOYD) Algorithmisch leicht nachzuvollziehen. Keine dyn. Datenstruktur Queue nötig. Der Algorithmus ist zu mächtig, da lediglich die Verbindbarkeit von Blecher gefragt war. Dafür reicht die Breitensuche (Tiefensuche) vollkommen aus. d.1) Sightseeing-Tour: B,G,O,H,P,S,N,A,B Motorrad-Tour: B,G,O,H,P,S,O,A,S,N,A,B Die Sightseeing-Tour ist in diesem Beispiel eindeutig, die Motorrad-Tour dagegen nicht. So ist z. B. B,G,O,H,P,S,O,A,N,S,A,B (Dreieck A,S,N andersherum) auch eine gültige Motorrad-Tour. d.2) (i) Ist ein ungerichteter Graph zusammenhängend, so gibt es eine Sightseeing Tour. Sie ist allerdings nicht immer eindeutig. (ii) Ist ein ungerichteten Graph zusammenhängend und jeder Knoten hat geraden Grad, so gibt es eine Motorrad-Tour. Sie ist allerdings in den seltensten Fällen eindeutig. Eindeutig wird die Tour erst, wenn alle Knoten den Grad 2 haben. d.3) Das Sightseening-Tour-Problem kommt dem TRAVELING-SALESMAN-PROBLEM (TSP) gleich. Das Motorrad-Tour-Problem kommt dem EULER-Kreis-Problem gleich. Die optimale Lösung des TSP-Problems ist nur per Backtracking zu ermitteln. Zwar können die Verwendung von Schranken und bestimmte Auswahlmechanismen (Greedy) die Laufzeit verbessern, allerdings bleibt der Aufwand des TSP-Problems in dieser Form in der Klasse O(n!), das heißt es ist ein Problem, welches sich nicht in polynomieller Zeit lösen lässt. Man spricht deshalb auch von einem NP-Problem (Nicht Polynomiell) Eine Lösung des EULER-Kreis-Problems benötigt eine Laufzeit von O(n2), da jede Kante definitiv nur einmal betrachtet wird. Das heißt, das Problem ist in polynomieller Zeit lösbar. Man spricht deshalb auch von einem P-Problem. 2. INFORMATIK-KLAUSUR LÖSUNGEN Lösungen Aufgabe 2: 02.12.2003 − Seite 3 − Graphentheorie − kürzeste Wege a) Die Suche mit Hilfe des DIJKSTRA-Algorithmus liefert folgende Entwicklung der Arrays Distanz und Vorgaenger: Distanz: Vorgaenger: b) Ein Greedy-Algorithmus versucht bei der Zusammensetzung einer Lösung immer den vielversprechendsten Zweig zuerst. Man spricht deshalb auch von gierigen Algorithmen, weil man hofft, durch die lokal am besten bewertete Lösungserweiterung auch eine optimale Gesamtlösung zu erhalten. Bei vielen Problemen – unter anderem dem Problem des kürzesten Weges − führt dieses Verfahren auch direkt zur optimalen Lösung. Der Algorithmus von DIJKSTRA arbeitet ebenfalls nach dem Greedy-Prinzip. Dies wird darin deutlich, dass er in jedem Schleifendurchlauf die Teillösung um die Kante erweitert, welche die minimalste Distanz zum Startknoten hat. Die Teillösung wird also um die lokal betrachtet am besten bewertete Lösungserweiterung ergänzt. Außerhalb der Graphentheorie sind Greedy-Algorithmen für alle Probleme denkbar, welche schrittweise Teillösungen aufbauen. Beispiele: i) Im Irrgarten geht man beim Backtracking-Algorithmus an Kreuzungen nicht nach einer vorher festgelegten Reihenfolge die Wege ab, sondern untersucht, welcher Weg von der Richtung her der vielversprechendste ist. ii) Beim Einkauf im Supermarkt mit begrenztem Budget packt man zuerst die wichtigsten (Kosten-Nutzen-Relation) Sachen in den Einkaufskorb. iii) Beim Vier-Gewinnt versuche ich, immer möglichst schnell möglichst viele Steine in eine Reihe zu bringen. Diese Strategie ist allerdings sehr schlecht. iv) Beim Anbringen von verschieden großen Bildern an der Wand versucht man immer zuerst die größten Bilder anzubringen. Man hofft, dass die kleineren Bilder später irgendwo dazuwischen passen. v) ... c.1) Zur Erweiterung des DIJKSTRA-Algorithmus: • Falls MinKnoten ≠ −1 dann: • Erledigt[MinKnoten] ← true • Für Knoten ← 1 bis n tue: • Falls NICHT Erledigt[Knoten] UND Matrix[MinKnoten, Knoten] < Distanz[Knoten] dann: • Distanz[Knoten] ← Matrix[MinKnoten, Knoten] • Vorgaenger[Knoten] ← MinKnoten c.2) Die Variable Distanz bedeutet nun nicht wie im Algorithmus DIJKSTRA die Entfernung zum Startknoten, sondern sie bedeutet vor der Hinzunahme zur Zusammenhangskomponente die Entfernung zu eben dieser und nach Hinzunahme zur 2. INFORMATIK-KLAUSUR 02.12.2003 LÖSUNGEN − Seite 4 − Zusammenhangskomponente die Gewichtung, welche diese Kante zum Gesamtgewicht des Spannbaums beiträgt. Die Variable Vorgaenger beinhaltet nach wie vor den Vorgänger, von dem aus dieser Knoten erreicht wurde, allerdings ist diese Information für den gesamten Spannbaum eher uninteressant. Vielmehr ist es durch diese Variable möglich, den Spannbaum zu rekonstruieren. Durchläuft man alle Knoten k und fügt die Kante (k,Vorgaenger[k]) in den Graphen ein, so erhält man den minimalen Spannbaum des ursprünglichen Graphen. c.3) Der Algorithmus hat den Namen PRIM-Algorithmus. c.4) Der Algorithmus durchläuft mit einer äußeren Schleife alle Knoten (Wiederhole n mal...). Innerhalb dieser Schleife wird a) ein Knoten mit minimaler Distanz gesucht (Knoten_mit_kleinster_Distanz). Dies geschieht mit Laufzeit O(n), da alle Knoten nur einmal betrachtet werden müssen. b) für alle Knoten geprüft, ob ein Umweg über den aktuellen Knoten günstiger ist als die bisherige Verbindung. Auch dies geschieht mit einer O(n)-Schleife, welche für jeden Knoten die Distanz einmal vergleicht und evtl. neu berechnet. Insgesamt ergibt sich also eine Laufzeit von O(n⋅n) = O(n2). d.1) Die Idee des Algorithmus liegt darin, dass alle möglichen Wege bis zur Kantenzuglänge n untersucht werden. Im ersten Schleifendurchlauf werden alle Wege betrachtet welche maximal einen Zwischenknoten haben. Im zweiten Durchlauf werden die Wege untersucht, welche maximal zwei Zwischenknoten haben. Usw. Nach dem letzen Schleifendurchlauf sind also alle Wege betrachtet worden, welche maximal n−1 Zwischenknoten besitzen. Damit sind aber auch alle Wege betrachtet worden und man hat definitiv den kürzesten Weg für alle Start- und Zielpunkte gefunden. Der Unterschied liegt darin, dass der FLOYD-Algorithmus im Gegensatz zum DIJKSTRAAlgorithmus die kürzesten Wege für alle Start- und Zielpunkte ermittelt, wogegen beim DIJKSTRA der Startpunkt vorher fest stehen muss. Der FLOYD-Algorithmus leistet also weitaus mehr als der DIJKSTRA-Algorithmus. Deshalb benötigt allerdings der FLOYD auch eine Laufzeit von O(n3) wogegen der DIJKSTRA nur die Laufzeit von O(n2) benötigt. d.2) Distanz und Zwischenknoten beim Start des Algorithmus: Dann wird wie folgt geändert: → → 2. INFORMATIK-KLAUSUR LÖSUNGEN 02.12.2003 − Seite 5 − → d.3) Die Rekonstruktion kann z. B. mit folgendem DELPHI-Algorithmus hergestellt werden (ZK = Zwischenknoten): procedure Rekonstruiere(Distanz: TAdjazenzmatrix; ZK: TZKMatrix; von,nach: integer; var Weg: TLinList); var zwischen: integer; begin if von <> nach then begin zwischen:= ZK[von,nach]; if (zwischen = -1) and (Distanz [von,nach] < maxEntfernung) then Weg.Einfuegen(TKantenelement.Create(von,nach)) else begin Rekonstruiere(Distanz, ZK, von, zwischen, Weg); Rekonstruiere(Distanz, ZK, zwischen, nach, Weg); end; end; end; Der Aufruf sieht wie folgt aus: Weg:= TLinList.Create; Rekonstruiere(Distanz, Zwischenknoten, Start, Ziel, Weg); d.4) Würde man die Schleifenindizes vertauschen, so würde der Algorithmus nie den kürzesten Weg vom Knoten S1 zu den Knoten S2 und S3 finden. Die endgültige Entfernungsmatrix und Zwischenknotenmatrix sähen dann wie folgt aus: und . Dies liegt daran, dass der kürzeste Weg zu S3 (und S2) über den Zwischenknoten S4 führt. Dieser kürzeste Weg (S1→S4) wird allerdings erst dann gefunden, wenn der Zwischenknoten S5 heißt. Dann ist allerdings eine Suche über den Zwischenknoten S4 bereits abgeschlossen. Somit kann kein kürzester Weg mehr gefunden werden. 2. INFORMATIK-KLAUSUR LÖSUNGEN Lösungen Aufgabe 3: 02.12.2003 − Seite 6 − Graphentheorie − gerichtete Graphen a) Ein Algorithmus der dies leistet lautet z. B.: function TGraph.Symmetrisch: boolean; var von, nach: integer; A: TAdjazenzmatrix; Symmetrie_vorhanden: boolean; begin A:= Adjazenzmatrix; Symmetrie_vorhanden:= true; for von:= 1 to Anzahl do for nach:= 1 to von-1 do if A[von,nach] <> A[nach,von] then Symmetrie_vorhanden:= false; Symmetrisch:= Symmetrie_vorhanden; end; b.1) Ein Beispiel wäre der folgende Graph: b.2) Angenommen, zwei verschiedene Knoten S1 und S2 eines Graphen seien Senke. Dann hat S1 den Eingangsgrad n−1, also gibt es auch eine Kante S2→S1. Dann kann aber S2 nicht den Ausgangsgrad 0 haben. Also ist S2 keine Senke. b.3) Eine Lösung wäre die folgende: function TGraph.Senke: integer; var von, nach: integer; a_grad, e_grad: integer; Senke_bei: integer; A: TAdjazenzmatrix; begin A:= Adjazenzmatrix; Senke_bei:= 0; For von:= 1 to Anzahl do begin a_grad:= 0; e_grad:= 0; for nach:= 1 to Anzahl do begin if A[von,nach]<maxEntfernung then inc(a_grad); if A[nach,von]<maxEntfernung then inc(e_grad); end; if (a_grad=0) and (e_grad = Anzahl-1) then Senke_bei:= von; end; Senke:= Senke_bei; end; Die Laufzeit ist direkt einsichtig, da zwei ineinander geschachtelte Schleifen von 1 bis n laufen. Damit ergibt sich O(n⋅n) = O(n2).