Motivation und Beispiel Definition und Begriffe Implementierung Klassische Probleme 1 Aufgabe aus dem Bundeswettbewerb Informatik: 2 !" #! $ Aufzeichnen, wer mit wem in Sympathie steht: (Sympathie ist nicht immer symmetrisch!) % !" #! $ Ordnen führt zu übersichtlicher Darstellung: 3 ' & Ein Graph beschreibt eine Struktur aus Objekten und den Beziehungen zwischen ihnen. Ein Graph besteht aus – – einer Menge von Knoten (vertex) (Objekten) und einer Menge von Kanten (edges) (Beziehungen), die die Knoten verbinden. Mathematisch G=(V,E) heißt ein Graph, mit: (i) V eine endliche nichtleere Menge (Knoten) (ii) E eine Menge von ein- oder zwei-elementigen Teilmengen von V. Ein Paar {u,v} ∈ V heißt Kante, u und v sind adjazent. Ein Element {a} ∈ V heißt Schlinge. ( ! $ Simulation von Verkehrsflüssen 4 ! ) Stammbaum der Musikerfamilie Bach (Ausschnitt) – Knoten: Person – (gerichtete) Kante: „ist-Kind“ Quelle: http://www.bzn.rt.bw.schule.de/pages/pro_bach/bilder/stammbaum.gif Haben die Kanten eine Richtung, so spricht man von gerichteten Graphen Im Englischen: directed graph oder kurz digraph Die zu Grunde liegende Relation zwischen den Knoten ist dann nicht symmetrisch Beispiele: – Ist-Lehrer-von, Ist-Sohn-von, ist-sympathisch Beispiele für symmetrische Relationen – Ist-verwandt-mit, wohnt-neben 5 ! Endlicher Automat – Knoten: Zustand – gerichtete Kante: Zustandsübergang ! Termbaum zu – Knoten: atomare Termeinheit – Kante: Beziehung zu anderen Bestandteilen des Terms ! 6 ! Netz im Burggymnasium – Knoten: Switch/... – Kante: Ethernetsegmente B04 CDI B02 Bib Ver BR Ph Ver hat keine Verbindung zu den anderen Teilen! „Als Netz oder Netzwerk werden Strukturen und Systeme bezeichnet, die sich mathematisch als Graphen modellieren lassen. Ein Netzwerk besteht aus einer Menge von Elementen (Knoten), die mittels Verbindungen (Kanten) miteinander verbunden sind.“ (J. Herlitz, AG ICSY, TU KL 2004) * ! + $# Sind je zwei Knoten durch einen Weg miteinander verbunden, so heißt der Graph zusammenhängend. Sind je zwei Knoten durch eine Kante miteinander verbunden, so heißt der Graph vollständig. 7 ! Das „Haus vom Nikolaus“ http://www.linux-related.de/index.html?/coding/alg_nikohaus.htm % , ! Zurück zur Aufgabe... Wollen erst einmal nur beobachten, wie sich eine Tratsch-Nachricht ausbreitet. – Es gibt eine Tratsch-Quelle, wo alles beginnt. – Es gibt keine Charmefehler. 8 & , ! -."! " # Wie breitet sich der Tratsch unter den Chatonen aus? – jeder erzählt es allen, die im sympathisch sind , ( ! Alle Knoten werden nacheinander „besucht“. Diesen Vorgang nennt man Traversieren. Idee: Besuche Knoten x Markiere x als schon besucht. Für alle Knoten y, die von x aus erreichbar sind, tue: Wurde y schon besucht? ja nein Besuche Knoten y Rekursiver Algorithmus Tiefendurchlauf (im Gegensatz zur Abbildung der vorigen Folie) 9 , ) ' $" "' Ausbreitung des Tratsches /0 12 " # Traversieren von Binärbäumen ! 10 3 3 " # Wie werden Graphen im Rechner dargestellt? Knoten – Werden auf irgendeine Art und Weise aufgezählt (durchnummeriert, als Aufzählungsdatentyp, als geordnete Liste, ...) Kanten – Spiegeln die Beziehungen zwischen den Knoten wieder und werden entweder als Beziehungsmatrix oder durch ein(e) Liste(n) dargestellt. ! " " Zur Beschreibung der Beziehungen: – Adjazenzmatrix (oder Adjazenzliste) – Im Prinzip wie in der Tratsch-Aufgabe vorgegeben: A A B C D Ja E Ja C H Ja Ja D Ja E Ja Ja Ja Ja G H G Ja B F F Ja Ja 11 3 3 " # Definition des Datentyps tKnoten und tAdjMatrix: TYPE tKnoten = (A, B, C, D, E, F, G, H); tAdjMatrix = ARRAY[A..H, A..H] of boolean; Abspeichern der Adjazenzmatrix: Aufzählungsdatentyp 8×8 Matrix = 2-dimensionale Reihung CONST symp : tAdjMatrix = ((false,true, false,false,true, false,false,false), (false,false,true, false,false,false,false,false), (false,false,false,true, false,false,true, false), (false,false,true, false,false,false,false,false), (false,false,false,false,false,true, false,false), (false,true, false,false,true, false,true, false), (false,false,false,false,false,false,false,true ), (false,false,false,true, false,false,false,false)); 3 3 " # FUNCTION name(k : tKnoten) : char; begin RESULT := chr(ord(k)+65); end; PROCEDURE besuche(aktKnoten : tKnoten); VAR naechsterKnoten : tKnoten; begin erledigt[aktKnoten] := true; writeln('Besuche: ', name(aktKnoten)); for naechsterKnoten := A to H do IF not (naechsterKnoten = aktKnoten) AND (symp[aktKnoten, naechsterKnoten]) AND (not erledigt[naechsterKnoten]) then besuche(naechsterKnoten); end; 12 3 3 " # PROCEDURE traversiere; VAR erledigt: ARRAY[A..H] of boolean; k : tKnoten; FUNCTION name(k : tKnoten) : char; ... PROCEDURE besuche(aktKnoten : tKnoten); ... begin for k := A to H do erledigt[k]:=false; besuche(A); end; % 4 !! ! 5 3 Eulersche Wanderungen Hamiltonsche Rundreisen Das Labyrinthproblem Das Problem des Handlungsreisenden Das Problem der kürzesten Wege 13 & 2" ! 6 $ " # – Königsberg, die Pregelflüsse und die Insel Kneiphof um 1736 – Euler suchte einen Rundweg, bei dem jede Brücke genau einmal überschritten wird – Er begründet 1736 mit seiner Modellierung und Lösung des Problems die Graphentheorie 2" ( 7 # Eulerweg – Unter einem Eulerweg versteht man einen Kantenzug, in dem jede Kante des Graphen genau einmal vorkommt. Eulerkreis – Ein geschlossener Eulerweg (mit Anfangsknoten = Endknoten) heißt Eulerkreis Satz von Euler – Ein zusammenhängender Graph besitzt dann und nur dann einen Eulerkreis, wenn alle Knoten geraden Grad haben. Antwort auf Königsberger Brückenproblem: – Gibt keinen Eulerkreis! Algorithmus von Hierholzer – Liefert einen Eulerweg, sofern existent 14 ) 8" 2" 7 # Idee: – Beginne bei einem beliebig gewählten Startknoten – Probiere eine der abgehenden Kanten aus, sollte das nicht klappen, kehre wieder hierher zurück und probiere die nächste Kante. – Lösche die verwendete Kante aus dem Graphen und wende den gleichen Algorithmus auf den neuen Graphen an. – Bleiben Kanten übrig: • Kehre zurück zum letzten Knoten • trage die verwendete Kante wieder in den Graphen ein • Versuche eine andere Kante !-9 "!- 3-: "! Bekanntermaßen gibt es zum Niko-Haus einen Eulerweg (aber keinen Eulerkreis) Hier: – Nicht: jede Brücke darf einmal überschritten werden – sondern: Jede Linie soll einmal gezeichnet werden! http://www.linux-related.de/index.html?/coding/alg_nikohaus.htm 15 : 9 "!; Datenmodell CONST Min = 0; Max = 4; Also gibt es Knoten 0, 1, 2, 3 und 4 TYPE tKnoten = Min..Max; tAdjMatrix = ARRAY[Min..Max] of ARRAY[Min..Max] of boolean; Adjazenzmatrix, symmetrisch (die Richtung der Striche ist egal) : 9 "!; # * Variable var verbunden : tAdjMatrix = ((false,true, true, true, false), (true, false,true, true, false), (true, true, false,true, true ), (true, true, true, false,true ), (false,false,true, true, false)); Start : tKnoten; weg : string; Merkt sich den versuchten Weg Belegung der Adjazenzmatrix (diesmal nicht als Konstante) Startknoten: Wo soll mit der Zeichnung begonnen werden? 16 : 9 "!; 9 '!'" Ausgabe des Knotennamens function name(x : tKnoten) : string; begin RESULT := inttostr(x); end; : 9 "!; < PROCEDURE haus( VAR verbunden : tAdjMatrix; aktKnoten : tKnoten; Die AnzahlStriche : byte; Adjazenzmatrix wird verändert VAR weg : string ); werden Wie viele Striche habe ich schon gemalt? Wenn alle gemalt, bin ich fertig! An welchem Knoten bin ich im Moment mit dem Stift? VAR Naechster : tKnoten; wegneu : string; Der Knoten, der als nächster bearbeitet wird 17 : 9 "!; < for Naechster := Min to Max do if verbunden[AktKnoten, Naechster] then begin wegneu := weg+' -> '+name(Naechster); if ( AnzahlStriche < 7 ) then begin verbunden[AktKnoten, Naechster] := false; verbunden[Naechster, AktKnoten] := false; haus( verbunden, Naechster, Rekursiver Aufruf AnzahlStriche+1, wegneu ); verbunden[AktKnoten, Naechster] := true; verbunden[Naechster, AktKnoten] := true; end; end; % : 9 "!; 9 " # 33 begin for Start := Min to Max do begin weg := name( Start ); haus( verbunden, Start, 0, weg); end; readln; end. 18 : & 9 "!; / !" – Lässt sich nur von den Knoten 0 und 1 aus beginnend zeichnen – Dann gibt es jeweils 44 Möglichkeiten (hier Start = 1): 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ( -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 2 2 2 2 2 2 3 3 3 3 3 3 0 0 0 0 3 3 3 3 3 3 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 1 1 3 3 4 4 1 1 2 2 4 4 1 1 3 3 0 0 1 1 4 4 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 3 3 1 4 3 3 2 2 1 4 2 2 3 3 2 4 1 2 0 0 2 2 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 2 4 2 2 1 2 3 4 3 3 1 3 2 4 4 2 3 4 2 3 0 0 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 4 2 4 1 2 1 4 3 4 1 3 1 4 2 3 3 4 3 4 4 1 3 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 3 3 3 3 3 3 2 2 2 2 2 2 3 3 1 1 2 1 3 2 3 1 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 4 4 4 4 4 4 0 0 0 0 2 2 2 2 2 2 4 4 4 4 4 4 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 3 3 3 3 3 3 1 1 2 2 0 0 1 1 4 4 2 2 2 2 2 2 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 0 0 1 1 2 2 2 2 3 4 1 3 0 0 3 3 0 0 1 1 3 3 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 1 2 0 0 0 0 3 4 4 3 2 4 2 3 0 0 1 3 0 0 0 0 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 3 3 2 3 1 3 4 3 2 2 4 2 4 4 1 2 2 2 2 3 1 2 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 2 1 3 2 3 1 2 2 1 1 3 1 3 2 2 1 3 1 3 2 2 1 -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> -> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 # Harmlos erscheinende Änderung: – Nicht alle Kanten sollen einmal genutzt werden, sondern jeder Knoten genau einmal aufgesucht werden! Hamiltonwege – Wege, bei denen jeder Knoten genau einmal besucht wird. Hamiltonkreise – Geschlossene Hamiltonwege Bis heute keine allgemeine Aussage: – „Über die Bedingung zur Existenz einer Hamiltonschen Linie ist im allgemeinen nichts bekannt“ (König, 1936) Einzige allgemeingültige Möglichkeit: – alle Wege betrachten und darin Hamiltonkreis suchen. (naiver Algorithmus) 19 ) 4 #! # Beide Aufgaben verbieten Wiederholungen: – Ein Eulerweg darf Knoten mehrfach passieren, muss aber jede Kante genau einmal nutzen – Ein Hamiltonweg kann Kanten auslassen, muss aber jeden Knoten genau einmal aufsuchen. In Königsberg – existiert Hamiltonkreis ABDCA – existiert kein Eulerkreis – Beide Aufgaben rein äußerlich analog, aber Suche nach Hamiltonkreisen ist ein „wesentlich schwierigeres“ Problem. ! 8 # " Alte Schachaufgabe: – Eine Springerfigur steht auf einem beliebigen Feld eines Schachbretts – Durch aufeinander folgende Springerzüge soll der Springer auf jedem Feld des Bretts genau einmal zu stehen kommen, um schließlich zur Anfangsposition zurückzukehren. Verallgemeinerung: – Das Schachbrett ist rechteckig mit m*n-Feldern, m<n+1. Aufgabe: – Jeder Knoten genau einmal, also: suche Hamiltonkreis! Resultate: – 3*3 keine Springertour (Mittelfeld kann nie erreicht werden) – 3*4 mindestens eine Springertour, Startfeld (1,1) 20 ! 8 # " Siehe LOG IN 14 (1994) Heft 4 Seite 29 = 3 Typische Probleme in einem Labyrinth: – Wie gelangt man in einem Labyrinth zum Ziel? – Wie kann man verhindern, sich zu verirren? Modellierung natürlich wieder als Graph – Kreuzungen (Knoten) – Wege (Kanten) Vorgehensweise – Markiere die benutzen Abzweigungen irgendwie – An neuen Kreuzungen nächsten Weg beliebig auswählen. Erweist er sich als Sackgasse, zurück zur letzten Kreuzung und nächsten unbenutzten Weg nehmen. – An alten Kreuzungen ebenfalls zurück zur letzten Kreuzung 21 = 3 Vorgehen entspricht dem Traversieren eines Graphen – Beschriebenes Verfahren ist ein Tiefendurchlauf – Vgl. Tratsch-Ausbreitung – Alternativ: Breitendurchlauf 9 $ " #! ! $ Problem des Handlungsreisenden Travelling Salesman Problem (TSP) – Ein Vertreter möchte alle seine Kunden in beliebiger Reihenfolge, jeden genau einmal, aufsuchen und am Ende wieder an seinem Wohnort ankommen. – Die Reise soll die kürzestmögliche Gesamtlänge haben. Ebenfalls schwieriges Problem – Praktiker behelfen sich mit Heuristik: „Fahre immer zur nächgelegenen noch nicht besuchten Stadt!“ – Liefert Näherungslösung Praktische Relevanz – U.a. Bohren von Platinen, ... 22 6 3 ' " Siehe Computerzeitung Nr. 42/35 vom 11.10.2004, Titelseite „Tour für Wahlkampf errechnet“ % 0 " http://www.educeth.ch/informatik/entdecken/brueckenbauen/ 23 & 0 " – Die Inseln sollen durch Brücken verbunden werden. – Es wird mindestens ein Weg von S nach T verlangt. – Zwei Algorithmen sind vorgegeben und können experimentell untersucht werden ( 0 " Vergleich der Ergebnisse beider Algorithmen 24 ) ! ;.# 3"! Beobachtbare Eigenschaften – Alle Knoten sind miteinander verbunden – Die Summe der Kantenlängen ist minimal – Es gibt keine „überflüssigen“ Kanten, also keine Schleifen bzw. Kreise – Das Entfernen einer Kante führt dazu, dass ein Knoten unerreichbar ist – Beim Hinzufügen eines Knotens wird mindestens eine weitere Kante benötigt Minimaler Spannbaum ! ;.# 3"! Beobachtbare Eigenschaften – Nur Start und Ziel (und „auf dem Weg liegende“ Knoten) sind verbunden – Die Summe der Kantenlängen ist minimal – Jeder Knoten hat höchstens zwei Kanten Suche nach kürzestem Weg von einer Insel zur einer bestimmten anderen Insel 25 ! ; !. > Problem – Hier sind noch keine Kanten vorgegeben! – In Realität häufig: Graph gegeben, Spannbaum oder Kürzester Weg gesucht! Dabei dürfen nur vorhandene Kanten genutzt werden! Ansatz – Interpretiere Graphen als vollständig (theoretisch sind ja alle möglichen Brücken denkbar) 8 #, . #? Zweck: – Switches fluten alle eingehenden Broadcasts. Enthält die Netztopologie eine Schleife, würde das Netz lahmgelegt, da die Switches vollauf damit beschäftigt wären, die Broadcasts weiterzuleiten. – Viele Netzkomponenten beherrschen den STA, der dazu verwendet wird ein Netz so zu konfigurieren, dass es baumartig aufgebaut ist und keine Schleifen enthält. Zugehöriger Graph: – Knoten: Switches – Kanten: Ethernetsegmente (Kabel, Hubs, ...) – Heutige Netze arbeiten alle duplex, daher hier nur ungerichtete Graphen 26 8,.; " !7 ! Siehe J. Herlitz: „Topologieerkennung“ DA, TU Kaiserslautern, AG ICSY 2004 8,.; 2 # ! Siehe J. Herlitz: „Topologieerkennung“ DA, TU Kaiserslautern, AG ICSY 2004 27 .# 3"! 5 3 Ziel: Minimaler Spannbaum Idee: – Baue den Baum Kante für Kante auf. – Um sicherzustellen, dass wirklich ein Baum gebaut wird, darf jede hinzuzufügende Kante mit dem bisher aufgebauten Teilbaum nur genau einen Knoten gemeinsam haben. – Jede hinzugefügte Kante ist unter den zur Auswahl stehenden Kanten eine billigste. Eigenschaften – Algorithmus ist „gierig“: In jedem Schritt wird eine weitere Kante aufgenommen, und eine einmal aufgenommene Kante wird nie wieder entfernt. % ! "3 . #? 5 3 28 & .# 3"! @ ! Ziel: Kürzester Weg zwischen zwei Knoten Idee: – Der Graph wird von Boten durchlaufen. – Die Boten merken sich, wie sie den Graphen durchlaufen und wieweit sie gelaufen sind. – An Kreuzungen werden neue Boten erzeugt, die ebenfalls den bisher gelaufenen Weg und seine Länge kennen. ( .# 3"! @ ! – Regeln: • Jeder Bote (grün) trägt als Markierung die Summe der Gewichte des bisherigen Weges, dabei zählt sein Weg und der seiner Vorgänger. • In jedem Schritt ist der Bote mit der kleinsten Markierung aktiv (blau) • Jeder Bote merkt sich, woher er kam. – Ablauf: • Vom Startknoten werden Boten auf allen Kanten ausgesendet, befindet sich auf einem Knoten schon ein Bote, gewinnt der mit der kleineren Markierung. • Der aktive Bote bleibt auf dem nächsten Knoten und sendet seinerseits auf allen Kanten Boten aus (aber nicht in die Richtung roter Boten). Er selbst wird jetzt passiv (rot) 29 ) .# 3"! @ ! – 3 Mengen: • Kosten stehen fest (rot) • Kosten vorläufig (grün) • Kosten unbekannt (schwarz) – Auch bekannt als schwarz/grau/weiß-Algorithmus u.ä. – Im Prinzip nicht viel mehr als ein Breitendurchlauf mit gewissen Spielregeln % 40 ! 6 # A @ ! B http://www.educeth.ch/informatik/puzzles/routing/docs/dijkstra.exe 30 ! % B Z C D A B A 21,E E % 8 A C C D 20,S 21,E E 15,E 18,E 2,S 15,E 18,E 2,S 21,E 16,C 15,E 18,E 2,S 19,B 20,D 16,C 15,E 18,E 2,S 19,B 20,D 16,C 15,E 18,E 2,S 19,B @ ! Z 15,E 18,E 2,S 16,C 15,E 18,E 2,S 21,E 16,C 15,E 18,E 2,S 19,B 20,D 16,C 15,E 18,E 2,S 19,B 20,D 16,C 15,E 18,E 2,S 19,B Z 16,C S 2,S 21,E E 2,S 21,E "3 B D 20,S E C D B Z Nach Z gelangt man unter Kosten von 19 am billigsten über B A Nach B gelangt man unter Kosten von 16 am billigsten über C 31 @ ! % Liefert nicht nur kürzesten Weg: – baut gleichzeitig einen Spannbaum auf, der die kürzesten Wege – ausgehend von einem Startknoten – zu allen anderen erreichbaren Knoten im Graphen enthält! Einschränkung: – Funktioniert nur mit nicht-negativen Gewichten! Praktischer Einsatz – im Open-Shortest-Path-First-Protokoll, einem der bekanntesten Routing-Protokolle (entwickelt Ende der 80er, definiert in RFC 1131 und RFC 2328). – Knoten: z.B. Internetknoten (Router) % 3 Graphen vs. andere Datenstrukturen – Listen, Bäume u.a. sind nur spezielle Graphen – Graphen sind eine allgemeine Datenstruktur, die die anderen bekannten Datenstrukturen umfasst Baumann (LOG IN 14 Heft 4, S. 25) – „Denn aus Sicht der Anwendungen sind Graphen weitaus wichtiger (und auch motivierender) als Baumstrukturen – und zwar aufgrund der einfachen Tatsache, daß sich jede Sammlung irgendwelcher Objekte, seien es nun Personen, Städte, Spielpositionen oder Begriffe – und die Beziehungen zwischen ihnen – als Graphen modellieren lassen. Mehr noch: Jedes Problemlösen kann als Suche in Graphen aufgefaßt werden.“ 32 % <"! 33 ' !!" # Graphen – Viele Probleme lassen sich mittels Graphen elegant modellieren und auf bekannte Graphenprobleme zurückführen Typische Algorithmen auf Graphen sind – Tiefendurchlauf – Breitendurchlauf und damit – Suche nach Kürzesten Wegen – Erzeugung von Spannbäumen %% 6 . # !C Gerichtete Graphen: (directed graph, digraph) Kanten dürfen nur in einer Richtung durchlaufen werden (die zugrundeliegende Relation ist nicht symmetrisch) Gewichtete Graphen: Die Kanten sind mit einem Gewicht versehen Zusammenhängende Graphen: Zwischen je zwei Knoten gibt es einen (ungerichteten) Weg Zyklen sind geschlossene Wege Vollständige Graphen: Alle Knoten sind paarweise durch Kanten miteinander verbunden Der Grad eines Knoten entspricht der Anzahl der Kanten, die von ihm abgehen. Gerüst ist ein kreisfreier Teilgraph (Baum), der alle Knoten enthält. 33 %& " – Baumann, R.: Graphen und Algorithmen. Fünf klassische Probleme. LOG IN 14 Heft 4, S. 25-37 – Baumann, R.: Informatik für die Sekundarstufe II, Band 2. Klett, Stuttgart 1994 – Bielig-Schulz, G.: Einige erstaunliche Graphenalgorithmen. Können Lösungen so einfach sein? LOG IN 14 Heft 4, S. 3844 – Jungnickel, D.: Graphen, Netzwerke und Algorithmen. BIWissenschaftsverlag, Mannheim 31994 – Volkmann, L.: Graphen und Digraphen. Eine Einführung in die Graphentheorie. Springer Verlag, Wien 1991. – Diverse Autoren, ETH Zürich: • http://www.educeth.ch/informatik/ • http://www.educeth.ch/compscience/ 34