Graphen und ihre Verarbeitung

Post on 19-Jan-2016

53 views 0 download

description

Graphen und ihre Verarbeitung. Klaus Becker 2010. Graphen. Teil 1. Vernetzte Strukturen. Routenplanung. Typisches Routenproblem: Wie kommt man am besten mit dem Auto von Worms nach Speyer?. Routenplanung mit dem Computer. Modellierungsproblem: - PowerPoint PPT Presentation

Transcript of Graphen und ihre Verarbeitung

Graphen und ihre Verarbeitung

Klaus Becker

2010

2 Graphen

3 Teil 1

Vernetzte Strukturen

4 Routenplanung

Typisches Routenproblem: Wie kommt man am besten mit dem Auto von Worms nach Speyer?

5 Routenplanung mit dem Computer

Modellierungsproblem:Wie wird das Verkehrsnetz im Computer repräsdentiert?

Berechnungsproblem:Wie wird die optimale Route ermittelt?

6

Beschreibung vernetzter Strukturen

Modellierung: Will man die Information über ein solches Straßennetz beschreiben, so konzentriert man sich auf die relevanten Fakten und lässt alles andere erst einmal weg. Ist man z.B. nur an den Autobahnverbindungen um Ludwigshafen / Mannheim interessiert, so könnte eine abstrahierende Beschreibung des Autobahnnetzes wie folgt aussehen:

7 Fachkonzept Graph

Ein Graph besteht aus einer Menge von Knoten und einer Menge von Kanten (die jeweils zwei Knoten miteinander verbinden).

Graphen dienen dazu, vernetzte Strukturen zu beschreiben. Die Knoten repräsentieren die Objekte des Anwendungsbereichs, die Kanten die Beziehungen zwischen den Objekten.

Graphen sind ein wichtiges und häufig benutztes Modellierungsmuster in der Informatik (und Mathematik), das in ganz unterschiedlichen Anwendungsbereichen zum Einsatz kommt.

Mathematisch: G = (V, E)

V = {WO, KR-FR, ..., SP, ...} ist die Menge der Knoten.

E = {{WO, KR-FR}, ... {SP, HO}, ...} ist die Menge der Kanten.

8 Graph-Editor

siehe: http://www.yworks.com/en/products_yed_about.html

9 Graphen in Anwendungssituationen

Aufgabe

(a) Wie sind die Verbindungslinien zwischen den Fährhäfen hier zu deuten? Warum beschreiben sie nicht die tatsächlichen Schifffahrsrouten? Warum reicht hier eine abstrahierende Darstellung der Fährverbindungen?

(b) Man möchte zusätzlich die Streckenlängen der Fährverbindungen angeben. Wie könnte man solche Informationen in der gezeigten Darstellung integrieren?

siehe auch: http://www.ferrylines.com/de/europaeisches-buchungsportal-fuer-faehren/

10 Graphen in Anwendungssituationen

Aufgabe

Wie kommt man über Land von Deutschland nach Finnland? Wie viele Ländergrenzen muss man dabei mindestens passieren?

(a) Der (noch unfertige Graph) zeigt Deutschland und seine Nachbarländer. Trage erst einmal sämtliche noch fehlenden Nachbarländer in die bereits vorgegebenen Knoten ein.

(b) Wie würde man die Kanten in der gezeigten Darstellung deuten?

(c) Erweitere das Diagramm um die Nachbarländer von Polen usw., bis du das oben beschriebene Problem mit Hilfe des Graphen lösen kannst.

(d) Wie kommt man über Land von Finnland nach Irland? Wie würde man das am Graphen erkennen?

siehe auch: http://moritz.stefaner.eu/projects/relation-browser/relationViewer.swf

11 Graphen in Anwendungssituationen

Aufgabe

In Königsberg (heute Kaliningrad) teilt der Fluss Pregel die Stadt in mehrere Stadtteile auf. Der Stadtplan hebt die Brücken hervor, die die Stadtteile miteinander verbinden. Der Mathematiker Euler beschäftigte sich mit der Frage, ob es einen Rundgang durch Königsberg gibt, der jede der sieben Brücken über den Fluss Pregel genau einmal benutzt.

(a) Versuche erst einmal, das Problem von Euler zu lösen.

(b) Der folgende Graph zeigt die Brückensituation in Königsberg in einer abstrahierenden Darstellung. Was stellen die Knoten des Graphen, was die Kanten dar?

(c) Wie viele Kanten gehen von den jeweiligen Knoten aus? Was hat das mit der Lösung des Problems von Euler zu tun?

12 Graphen in Anwendungssituationen

Aufgabe

(a) Beschreibe die Struktur des folgenden (siehe rechts Mitte) wer-kennt-wen-Netzwerks mit Hilfe eines Graphen.

(b) Noch ein soziales Netzwerk (siehe rechts unten). Wie würde man hier die Vernetzungungsstruktur darstellen?

(c) Bist du Mitglied in einem sozialen Netzwerk? Wie hoch ist dein Mitgliedsbeitrag? Nimm Stellung zu folgender Aussage: "Die Mitglieder zahlen mit ihren Daten."

An: Daniel

Hallo Daniel, Rebekka hat dich als Freund/Freundin auf ... hinzugefügt. Wir benötigen deine Bestätigung, dass du Rebekka kennst, damit ihr Freunde/Freundinnen auf ... sein könnt.

Viele Grüße vom ...

Rebekka kennt Daniel, Florian, Lisa, Greta, Sophie, Maria

Daniel kennt Tim, Rebekka, Jonas

Florian kennt Rebekka, Sophie

Lisa kennt Rebekka, Sophie, Jonas

Greta kennt Rebekka, Sophie, Tim

Sophie kennt Rebekka, Florian, Lisa, Greta

Maria kennt Rebekka

Tim kennt Daniel, Greta

Jonas kennt Daniel, Lisa

Martin kennt Markus

Markus kennt MartinAnna liebt Ben

Ben liebt Clara

Clara liebt Daniel

Daniel liebt Anna

13 Graphen in Anwendungssituationen

Aufgabe

Zum Nudelkochen im Ferienlager werden genau 2 Liter Wasser benötigt. Zum Abmessen stehen nur ein kleiner Eimer, der 3 Liter fasst, und einen etwas größerer Eimer, der 4 Liter fasst, zur Verfügung. Kann das funktionieren?

Um systematisch alle durch Umfüllen erzeugbaren Wassermengen zu bestimmen, kann man einen Zustandsgraphen erstellen. Die Knoten des Graphen sind die aktuellen Füllinhalte der beiden Eimer. Die Kanten des Graphen stellen die Umfüllvorgänge dar.

Vervollständige den bereits begonnenen Graphen. Ermittle mit diesem Graphen verschiedene Möglichkeiten, eine 2-Liter-Wassermenge durch Umfüllen zu erzeugen.

14 Graphen in Anwendungssituationen

Aufgabe

Am Flussufer befinden sich ein Wolf, eine Ziege, ein Kohlkopf und ein Fährmann. Der Fährmann soll Wolf, Ziege und Kohlkopf auf die andere Seite des Flusses bringen. Er kann aber immer nur einn der drei mit an das andere Ufer nehmen und muss die beiden anderen so lange allein lassen. Da nun der Wolfe gerne die Ziege frisst und die Ziege auf den Kohlkopf scharf ist, kann der Fährmann diese Paarungen nicht allein lassen. Kann der Fährmann das Transportproblem lösen?

Versuche, das Transportproblem systematisch zu lösen, indem du den bereits begonnenen Transport-Graphen vervollständigst.

15 Graphenterminologie

Je nach Anwendung ist es sinnvoll, Kanten gerichtet oder ungerichtet zu modellieren. Bei gerichteten Graphen werden in der Regel auch sog. Schlingen zugelassen. Werden die Kanten mit zusätzlichen Gewichten versehen, so spricht man von gewichteten oder bewerteten Graphen.

A

B

C

D

E

F

G H

A

B

C

D

E

F

G H

128

17

11

5

3

5

68

gerichteter, unbewerteter Graph

ungerichteter, bewerteter Graph

16 Graphenterminologie

In einem Multigraphen können Knoten über mehrere Kanten miteinander verbunden werden.

Multigraph

17 Graphenterminologie

Ist in einem gerichteten Graphen ein Knoten über eine Kante mit einem anderen Knoten verbunden, so heißen dieser andere knoten Nachbar des Ausgangsknoten. In ungerichteten Graphen sind zwei Knoten Nachbarn, wenn sie über eine Kante miteinander verbunden sind.

Ein Knoten, der keine Nachbarn hat, wird auch isolierter Knoten genannt.

Ein Weg innerhalb eines Graphen ist eine Folge von Knoten des Graphen, die sukzessive über eine Kante miteinander verbunden sind.

Ein einfacher Weg ist ein Weg, in dem - außer gegebenenfalls Startknoten und Endknoten - kein Knoten mehrfach vorkommt.

Ein einfacher Weg heißt Kreis oder Zyklus, wenn der Startknoten des Weges gleichzeitig Endknoten ist.

18 Übungen

Aufgabe

(a) Welche Nachbarn hat Knoten 1 (Knoten 2) im Beispielgraphen?

(b) Gibt es im Beispielgraphen einen isolierten Knoten?

(c) Verdeutliche am Beispielgraphen den Weg [1,4,1,3,2,2].

(d) Gib einen möglichst langen Weg im Beispielgraphen an.

(e) Gib es Kreise im Beispielgraphen? Wenn ja, welche?

19 Übungen

Aufgabe

"Die Leute vom Planeten Chator schreiben gern Schlechtes übereinander.Wer vielen über andere Schlechtes schreibt, gilt als besonders charmant. Aber natürlich nur, wenn die Kompromittierten nichts davon erfahren. Chatonen schreiben nur an Leute, die ihnen sympathisch sind. Doch die können den Tratsch weitertragen, und eventuell genau an den Falschen. Ein Chatone muss also gut aufpassen, dass er keinen Charmefehler macht. Dieses Missgeschick passierte unlängst Ator, als er Btor Schlechtes über Dtor schrieb. Zu dumm: Dtor ist dem Ctor sympathisch, der wiederum Btor sympathisch ist. Und so landete der Tratsch bei Dtor, der über Ator verständlicherweise sehr verärgert war. Dies hätte Ator mit ein wenig Übersicht vermeiden können, denn schließlich wissen alle Chatonen voneinander, wer wem sympathisch ist." (Quelle: Bundeswettbewerb Informatik 2004/2005 - 1. Runde)

(a) Stelle die Sympathiebeziehungen der Chatonen mit einem gerichteten Graphen dar.

(b) Welches Problem muss hier gelöst werden. Beschreibe es mit Hilfe der Graphenterminologie.

20 Teil 2

Implementierung von Graphen

21 Graphen als Daten

Darstellen

Verarbeiten

def sucheWeg(graph, start, ziel): ... return ...

>>> sucheWeg(g, 'A', 'C')['A', 'B', 'C']

Deuten

>>> g =

22 Graphen als Daten

Darstellen

>>> g =

Aufgabe

Betrachte den folgenden (gerichteten) Graphen. Wie könnte man diesen Graphen in Tabellenform / mit Hilfe von Listen beschreiben? Entwickle hierzu selbst Ideen.

23 Nachbarschaftstabelle

Sämtliche Informationen eines Graphen lassen sich in einer Nachbarschaftstabelle darstellen.

Adjazenzmatrix

A

B

C

D

0

0

1

0

A

1

1

1

0

B

0

1

0

0

C

0

1

0

0

D

0

0

1

0

1

1

1

0

0

1

0

0

0

1

0

0

knotenliste = ['A', 'B', 'C', 'D']kantenmatrix = [[0, 1, 0, 0],[0, 1, 1, 1],[1, 1, 0, 0],[0, 0, 0, 0]]testgraph = (knotenliste, kantenmatrix)

Kantenmatrix

Nachbarschaftstabelle

Darstellen

24 Nachbarschaftstabelle

Aufgabe:

(a) (einfach) Entwickle eine Funktion existiertKante(graph, vonKnoten, nachKnoten), die überprüft, ob es eine Kante zwischen den übergebenen Knoten gibt. Ein möglicher Testfall sollte so verlaufen:

Tipp: Mit knotenliste.index('A') kann man den Index des übergebenen Bezeichners in der Knotenliste bestimmen.

>>> existiertKante(testgraph, 'A', 'D')False

(b) (etwas schwieriger) Entwickle eine Funktion getAlleNachbarn(graph, knoten), die sämtliche Nachbarn eines vorgegebenen Knotens ermittelt. Ein möglicher Testfall sollte so verlaufen:>>> getAlleNachbarn(testgraph, 'B')['B', 'C', 'D']

25 Nachbarschaftslisten

Sämtliche Informationen eines Graphen lassen sich in einer Nachbarschaftstabelle darstellen.

A:

B:

C:

D:

B

B

B

C

1

D

0

testgraph = \[ ['A', ['B']], ['B', ['B', 'C', 'D']], ['C', ['A', 'B']], ['D', []]]

Nachbarschaftslisten

Darstellen

Adjazenzlisten

26 Nachbarschaftslisten

Aufgabe:

(a) (einfach) Entwickle eine Funktion getAlleNachbarn(graph, knoten), die sämtliche Nachbarn eines vorgegebenen Knotens ermittelt. Ein möglicher Testfall sollte so verlaufen:

>>> existiertKante(testgraph, 'A', 'D')False

(b) (etwas schwieriger) Entwickle eine Funktion existiertKante(graph, vonKnoten, nachKnoten), die überprüft, ob es eine Kante zwischen den übergebenen Knoten gibt. Ein möglicher Testfall sollte so verlaufen:

>>> getAlleNachbarn(testgraph, 'B')['B', 'C', 'D']

Aufgabe:

(c) (offen) Entwickle weitere Funktionen zur Verwaltung und Verarbeitung von Graphen, z.B.:

addKnoten(...) # fügt einen neuen Knoten hinzudelKnoten(...) # löscht einen KnotenaddKante(...) # fügt eine neue Kante hinzu...

27 Graph als Objekt

Bisher wurde gezeigt, dass man Graphen auf unterschiedliche Weise mit Hilfe elementarer Datenstrukturen repräsentieren kann. Für die Verarbeitung von Graphen ist die gewählte Darstellung durchaus wichtig. Noch wichtiger ist es aber, über geeignete Operationen zur Verwaltung und Veränderung von Graphen zu verfügen, die - unabhängig von der zu Grunde liegenden Darstellung - die erforderiche Verarbeitung der Daten durchführen. Günstig ist es, hier objektoerientiert vorzugehen und eine Klasse Graph zu konzipieren, die die benötigten Operationen bereitstellt.

28 Modellierung der Klasse Graph

Ein Objekt der Klasse Graph soll die Knoten und Kanten eines Graphen verwalten.

Zum einen soll es geeignete Operationen bereit stellen, um einen Graphen aufzubauen und zu verändern. Mit diesen Operationen soll man z.B. neue Knoten hinzufügen oder bereits vorhandene Knoten entfernen können.

Zum anderen soll es Operationen bereit stellen, um an Informationen über den Graphen zu gelangen. So soll man mit einer geeigneten Operation ermitteln können, ob es den Knoten ... gibt oder ob es eine Kante von Knoten ... zu Knoten ... gibt.

Aufgabe:

Erstelle zunächst eine Liste mit den Operationen, die ein Objekt der Klasse Graph zur Verfügung stellen sollte.

Ergänze dann das Klassendiagramm. Beschreibe die gewünschten Operationen möglichst genau.

29 Implementierung der Klasse Graph

Aufgabe:

Ergänze die Implementierung der Klasse Graph. Du kannst auch eine Nachbarschaftstabelle zur Repräsentation des Graphen benutzen.

Teste natürlich auch deine Implementierung der Klasse Graph.

class Graph(object): def __init__(self): self.knotenMitNachbarn = []

def getAlleKnoten(self): knotenListe = [] for eintrag in self.knotenMitNachbarn: knotenListe = knotenListe + [eintrag[0]] return knotenListe

def existiertKnoten(self, nameKnoten): if nameKnoten in self.getAlleKnoten(): return True else: return False # ...

30 Nutzung der Klasse Graph

Das Testprogramm unten zeigt, wie man eine (gegebene) Implementierung der Klasse Graph nutzen kann.

from graph import *# Erzeugung des Graph-Objektsg = Graph()# Hinzufügen von Knoten und Kanteng.addKnoten('A')g.addKnoten('B')g.addKante('A', 'B')# Ausgabe der Nachbarschaftslistenfor knoten in g.getAlleKnoten(): print(knoten, ':', g.getAlleNachbarn(knoten))

Aufgabe:

Nutze die Implementierung der Klasse Graph, um den Graphen in der Abbildung zu erstellen.

Nimm anschließend folgende Veränderungen am Graphen vor und kontrolliere die Ergebnisse: (1) Kante von B nach C löschen (2) Kante von C nach B löschen (3) Kante von C nach C hinzufügen (4) Knoten B löschen (5) Knoten C löschen

31 Erweiterung der Klasse Graph

Erweiterung: Verwaltung zusätzlicher DatenZunächst einmal sind hier alle Kanten mit Gewichten versehen. Die Zahlen an den Kanten repräsentieren die Entfernung zwischen den Autobahnknotenpunkten.

An einer der Kanten ist zusätzlich die Autobahnbezeichnung eingetragen. Auch diese Information ist für praktische Anwendungen oft wichtig.

Interessant könnten auch die Geo-Koordinaten von Autobahnknotenpunkten sein. Diese würde man benötigen, wenn eine Darstellung auf einer Landkarte angestrebt würde. An einem der Knoten sind solche zusätzlichen Geo-Informationen eingetragen.

32 Erweiterung der Klasse Graph

Erweiterung: Speicherung der Daten in einer externen DateiDie Daten von Graphen werden während der Verarbeitung von einem Objekt der Klasse Graph verwaltet. Nach der Verarbeitung (wenn das Programm beendet ist) wird das Objekt vernichtet. Danach sind sämtliche Daten des verwalteten Graphen nicht mehr zugänglich. Wünschenswert ist eine Möglichkeit, die Daten eines Graphen in einer externen Datei abspeichern zu können und Daten einer externen Datei wieder einlesen zu können.

Als externes Speicherformat benutzen wir im Folgenden GraphML, ein XML-basiertes Standardformat zur Repräsentation von Graphen.

<?xml version="1.0" encoding="iso-8859-1"?><graph id="bundesautobahnen Lu Ma"><!--Knoten--><node id="Kreuz Frankenthal"> <data key="lat">49.5534891</data> <data key="lon">8.3199207</data></node>...<!--Kanten--><edge source="Kreuz Frankenthal" target="Viernheimer Dreieck"> <data key="A">A 6</data> <data key="entfernung">19</data></edge>...</graph>

33 Erweiterung der Klasse Graph

Die Klasse Graph wird um geeignete Operationen erweitert.

34 Erweiterung der Klasse Graph

Aufgabe

Teste die erweiterte Klasse mit den Daten zum Autobahnnetz (siehe inf-schule).

Aufgabe

Teste die Klasse GraphMitDaten. Erzeuge ein Objekt, mit dem der folgende gewichtete Graph verwaltet wird. Die Daten des Graphen sollen auch in einer externen Datei gespeichert werden.

35 Teil 3

Kürzeste Wege in Graphen

36 Das Problem

Viele Wege führen vom Kreuz Frankenthal zum Kreuz Heidelberg. Aber welcher dieser Wege ist der kürzeste?

allgemein:Gegeben ist ein (gerichteter oder ungerichtetet, gewichteter) Graph. Gegeben ist zusätzlich ein Start- und ein Zielknoten. Welcher Weg des Graphen vom Startknoten zum Zielknoten ist der kürzeste. Dabei soll die Länge des Weges durch die Summe der Gewichte der Kanten längs des Weges erfasst werden.

37 Ein vereinfachtes Problem

Viele Wege führen vom Kreuz Frankenthal zum Kreuz Heidelberg. Aber welcher dieser Wege benötigt die wenigsten "Hops"?

allgemein:Gegeben ist ein (gerichteter oder ungerichtetet) Graph. Gegeben ist zusätzlich ein Start- und ein Zielknoten. Welcher Weg des Graphen vom Startknoten zum Zielknoten führt über die geringste Anzahl an Zwischenknoten?

38

Lösung des vereinfachten Problems

Im Alltag kommt es gelegentlich vor, dass jemand sagt: "Den kenne ich um mehrere Ecken". Das heißt dann wohl, dass derjenige jemanden kennt, der wiederum jemanden kennt, der ...

Ziel ist es, den "Bekanntheitsabstand" von Adriana zu Betül, Clara, Dominik, ..., Hannah zu bestimmen. Dabei soll direkte Bekanntschaft durch den Bekanntheitsabstand 1 beschrieben werden.

Aufgabe:

Versuche (ohne den Bekanntschaftsgraphen zu zeichnen), die gesuchten Bekannheitsabstände systematisch zu ermitteln. Beschreibe dein Vorgehen.

Adriana kennt Clara, Erik, Greta

Betül kennt Clara, Dominik

Clara kennt Adriane, Dominik, Erik

Dominik kennt Betül, Erik

Erik kennt Dominik, Greta

Fabian kennt Hannah

Greta kennt Dominik, Hannah

Hannah kennt Fabian

39 Lösungsverfahren - Abstand

40 Ein Lösungsverfahren

# Vorbereitungfür alle Knoten knoten des Graphen: knoten.abstand = 'u'startKnoten.abstand = 0füge startKnoten in eine Liste zuVerarbeiten ein (hier grün)

41 Ein Lösungsverfahren

# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme ausgewaehlterKnoten aus zuVerarbeiten entferne ausgewaehlterKnoten aus zuVerarbeiten (hier blau) für alle Nachbarn nachbarKnoten von ausgewaehlterKnoten: wenn nachbarKnoten.abstand == 'u': füge nachbarKnoten in die Liste zuVerarbeiten ein nachbarKnoten.abstand = ausgewaehlterKnoten.abstand + 1

42 Ein Lösungsverfahren

# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme ausgewaehlterKnoten aus zuVerarbeiten entferne ausgewaehlterKnoten aus zuVerarbeiten (hier blau) für alle Nachbarn nachbarKnoten von ausgewaehlterKnoten: wenn nachbarKnoten.abstand == 'u': füge nachbarKnoten in die Liste zuVerarbeiten ein nachbarKnoten.abstand = ausgewaehlterKnoten.abstand + 1

43 Ein Lösungsverfahren

# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme ausgewaehlterKnoten aus zuVerarbeiten entferne ausgewaehlterKnoten aus zuVerarbeiten (hier blau) für alle Nachbarn nachbarKnoten von ausgewaehlterKnoten: wenn nachbarKnoten.abstand == 'u': füge nachbarKnoten in die Liste zuVerarbeiten ein nachbarKnoten.abstand = ausgewaehlterKnoten.abstand + 1

44 Ein Lösungsverfahren

# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme ausgewaehlterKnoten aus zuVerarbeiten entferne ausgewaehlterKnoten aus zuVerarbeiten (hier blau) für alle Nachbarn nachbarKnoten von ausgewaehlterKnoten: wenn nachbarKnoten.abstand == 'u': füge nachbarKnoten in die Liste zuVerarbeiten ein nachbarKnoten.abstand = ausgewaehlterKnoten.abstand + 1

45

Lösungsverfahren - Abstand / Herkunft

46 Algorithmus von MooreALGORITHMUS # von MooreÜbergabedaten: Graph, startKnoten, zielKnoten# Vorbereitung des Graphenfür alle knoten des Graphen: setze abstand auf 'u' setze herkunft auf Nonesetze abstand von startKnoten.abstand auf 0füge startKnoten in eine Liste zuVerarbeiten ein# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme einen Knoten ausgewaehlterKnoten aus zuVerarbeiten (z.B. den ersten in der Liste) entferne ausgewaehlterKnoten aus zuVerarbeiten für alle nachbarKnoten von ausgewaehlterKnoten: wenn abstand von nachbarKnoten == 'u': füge nachbarKnoten in die Liste zuVerarbeiten ein (z.B. am Listenende) neuerAbstand = (abstand von ausgewahlterKnoten) + 1 setze abstand von nachbarKnoten auf neuerAbstand setze herkunft von nachbarKnoten auf ausgewaehlterKnotenweglaenge = abstand von zielKnoten# Erzeugung des Weges zum zielKnotenweg = []knoten = zielKnoten SOLANGE knoten != startKnoten und herkunft von knoten != None: weg = [(herkunft von knoten, knoten)] + weg knoten = herkunft von knotenRückgabedaten: (weg, weglaenge)

47 Exkurs "Graph durchlaufen"

Quelle: http://www.matheprisma.uni-wuppertal.de/Module/Graphen/index.htm

{Eingabe: Graph G; Startknoten s des Graphen}

für alle Knoten w      markiere w als nicht besuchtfüge s in eine (zunächst leere) Datenstruktur D ein solange D nicht leer ist      entnimm einen Knoten w aus D      für alle Kanten {w,u}   falls u nicht markiert ist     markiere u    füge u in D ein

{Ausgabe: Markierungen für alle Knoten w von G; ein Knoten ist genau dann als 'besucht' markiert, wenn er üben einen Weg mit s verbindbar ist}

48 Beispiel

S

C

EA

D

B F

markiere alle Knot. als nicht besucht (hier 0) markiere S als besucht (hier 1) füge s in e. Datenstruktur D (hier grün) ein

S

C

EA

D

B F

1

0

0 0

0

00

S

C

EA

D

B F

1

0

0 0

0

00

entnimm einen Knoten w (hier blau) aus D für alle Kanten {w,u} falls u nicht markiert ist     markiere u    füge u in D ein

S

C

EA

D

B F

1

1

0 0

0

01

Vorbereitungsschritt

Wiederholungsschritt

49 Beispiel

S

C

EA

D

B F

1

1

0 0

1

01

entnimm einen Knoten w (hier blau) aus D für alle Kanten {w,u} falls u nicht markiert ist     markiere u    füge u in D ein

S

C

EA

D

B F

1

1

0 0

0

01 S

C

EA

D

B F

1

1

0 0

1

01

S

C

EA

D

B F

1

1

0 0

1

11

S

C

EA

D

B F

1

1

0 0

1

11

S

C

EA

D

B F

1

1

1 0

1

11

Auswahlstrategie

First InFirst Out

-> Breitensuche

Auswahlstrategie

Last InFirst Out

-> Tiefensuche

50 Beispiel

entnimm einen Knoten w (hier blau) aus D für alle Kanten {w,u} falls u nicht markiert ist     markiere u    füge u in D ein

S

C

EA

D

B F

1

1

1 0

1

11

S

C

EA

D

B F

1

1

1 0

1

11

S

C

EA

D

B F

1

1

1 0

1

11

S

C

EA

D

B F

1

1

1 0

1

11

Ergebnis:Von S aus gibt es Wege zu den folgenden Knoten: A, B, C, D, E.

51 Das verallgemeinerte Problem

Gegeben ist ein (gerichteter oder ungerichtetet, gewichteter) Graph. Gegeben ist zusätzlich ein Startknoten (z.B. A) und ein Zielknoten (z.B. C). Welcher Weg des Graphen vom Startknoten zum Zielknoten ist der kürzeste. Dabei soll die Länge des Weges durch die Summe der Gewichte der Kanten längs des Weges erfasst werden.

52 Lösungsverfahren

Aufgabe: Benutze das Simulationsprogramm "Shortest Path Animation", um die Grundidee des Lösungsverfahrens von Dijkstra herauszufinden.

53

Lösungsverfahren - Abstand / Herkunft

54 Ein Lösungsverfahren

# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme e. Knoten minKnoten a. zuVerarbeiten mit min. Abstand entferne minKnoten aus zuVerarbeiten (hier blau) für alle Nachbarn nachbarKnoten von minKnoten: wenn nachbarKnoten.abstand == 'u': füge nachbarKnoten in zuVerarbeiten ein nachbarKnoten.abstand = minKnoten.abstand+gewicht((minknoten, nachbarKnoten)) nachbarKnoten.herkunft = minKnoten sonst: wenn nachbarKnoten in zuVerarbeiten liegt: wenn minKnoten.abstand+ gewicht((minknoten, nachbarKnoten)) < nachbarKnoten.abstand: aktualisiere nachbarKnoten.abstand aktualisiere nachbarKnoten.herkunft

55 Algorithmus von DijkstraÜbergabedaten: Graph, startKnoten, zielKnoten# Vorbereitung des Graphenfür alle knoten des Graphen: setze abstand auf 'u' setze herkunft auf Nonesetze abstand von startKnoten.abstand auf 0füge startKnoten in eine Liste zuVerarbeiten ein# Verarbeitung der KnotenSOLANGE die Liste zuVerarbeiten nicht leer ist: bestimme einen Knoten minKnoten aus zuVerarbeiten mit minimalem Abstand entferne minKnoten aus zuVerarbeiten für alle nachbarKnoten von minKnoten: gewicht = Gewicht der Kante von minKnoten zu nachbarKnoten neuerAbstand = (abstand von minKnoten) + gewicht WENN abstand von nachbarKnoten == 'u': füge nachbarKnoten in die Liste zuVerarbeiten ein (z.B. am Listenende) setze abstand von nachbarKnoten auf neuerAbstand setze herkunft von nachbarKnoten auf minKnoten SONST: WENN nachbarKnoten in zuVerarbeiten liegt: WENN abstand von nachbarKnoten > neuerAbstand: setze abstand von nachbarKnoten auf neuerAbstand setze herkunft von nachbarKnoten auf minKnotenweglaenge = abstand von zielKnoten# Erzeugung des Weges zum zielKnotenweg = []knoten = zielKnoten SOLANGE knoten != startKnoten und herkunft von knoten != None: weg = [(herkunft von knoten, knoten)] + weg knoten = herkunft von knoten# Rückgabedaten: (weg, weglaenge)

56 Implementierung des Moore-Alg.

Aufgabe:

Die folgende Implementierung dieses Algorithmus beruht auf einer Darstellung von Graphen mit Nachbarschaftlisten. Sie benutzt eine Reihe von Hilfsfunktionen (siehe inf-schule). Teste zunächst die Hilfsfunktionen. Was leisten sie jeweils?

def existiertKnoten(graph, knoten): # ...

def getAlleKnoten(graph): # ...

def getAlleNachbarn(graph, knoten): # ...

def getAbstand(erweiterterGraph, knoten): # ...

def getHerkunft(erweiterterGraph, knoten): # ... def setAbstand(erweiterterGraph, knoten, wert): # ...

def setHerkunft(erweiterterGraph, knoten, wert): # ...

def initErweiterterGraph(graph, startKnoten): # ...

57 Implementierung des Moore-Alg.def kuerzesterWegMoore(graph, startKnoten, zielKnoten): if existiertKnoten(graph, startKnoten) and existiertKnoten(graph, zielKnoten): # Vorbereitung erweiterterGraph = initErweiterterGraph(graph, startKnoten) zuVerarbeiten = [startKnoten] # Verarbeitung der Knoten while zuVerarbeiten != []: # bestimme einen Knoten ausgewaehlterKnoten aus zuVerarbeiten ausgewaehlterKnoten = zuVerarbeiten[0] # entferne ausgewaehlterKnoten aus zuVerarbeiten zuVerarbeiten = zuVerarbeiten[1:] # bearbeite die Nachbarn von ausgewaehlterKnoten for nachbarKnoten in getAlleNachbarn(graph, ausgewaehlterKnoten): if getAbstand(erweiterterGraph, nachbarKnoten) == 'u': zuVerarbeiten = zuVerarbeiten + [nachbarKnoten] neuerAbstand = getAbstand(erweiterterGraph, ausgewaehlterKnoten)+ 1 erweiterterGraph = setAbstand(erweiterterGraph, nachbarKnoten, neuerAbstand) erweiterterGraph = setHerkunft(erweiterterGraph, nachbarKnoten, ausgewaehlterKnoten) weglaenge = getAbstand(erweiterterGraph, zielKnoten) # Erzeugung des Weges zum zielKnoten weg = [] knoten = zielKnoten while knoten != startKnoten and getHerkunft(erweiterterGraph, knoten) != None: weg = [(getHerkunft(erweiterterGraph, knoten), knoten)] + weg knoten = getHerkunft(erweiterterGraph, knoten) else: weg = [] weglaenge = 'u' return (weg, weglaenge)

58 Implementierung des Moore-Alg.# Erzeugung des Testgraphentestgraph_ohne_gewichte = \[['A', ['C', 'E', 'G']],['B', ['C', 'D']],['C', ['A', 'D', 'E']],['D', ['B', 'E']],['E', ['D', 'G']],['F', ['B', 'D', 'H']],['G', ['D']],['H', ['F', 'G']]]

# Test des Moore-Algorithmusstart = 'A'ziel = 'B'print('kürzester Weg von', start, 'nach', ziel, ':')(weg, laenge) = kuerzesterWegMoore(testgraph_ohne_gewichte, start, ziel)for w in weg: print(w)print('Weglänge:', laenge)

Aufgabe:

Ergänze Ausgaben in der Funktion kuerzesterWegMoore so, dass die Verarbeitung des Graphen Schritt für Schritt (wie in den Abbildungen zum Algorithmus von Moore ) nachvollzogen werden kann. Führe auch weitere Tests der Funktion kuerzesterWegMoore aus.

59 Implementierung des Moore-Alg.

Aufgabe:

Eine weitere Implementierung des Algorithmus von Moore findest du in der Klasse GraphMoore (siehe inf-schule). Objekte der Klasse GraphMoore stellen die Operation kuerzesterWegMoore zur Verfügung, mit der man Wege mit geringster Anzahl von Zwischenknoten in Graphen bestimmen kann. Teste auch diese Implementierung.

from graph_moore import *

# Erzeugung des Graph-Objektsg = GraphMoore()# Erzeugung der Knoten und Kanten aus einer GraphML-Dateidatei = open("graph_ohne_gewichte.xml", "r")xml_quelltext = datei.read()g.graphmlToGraph(xml_quelltext) # Kontrollausgabe des Graphenprint('Graph:')for knoten in g.getAlleKnoten(): print(knoten, ':', g.getAlleNachbarn(knoten))print()# Test des Moore-Algorithmusstart = 'A'ziel = 'B'print('kürzester Weg von', start, 'nach', ziel, ':')(weg, laenge) = g.kuerzesterWegMoore(start, ziel)for w in weg: print(w)print('Weglänge:', laenge)

60 Implementierung des Dijkstra-Alg.

Aufgabe:

Mit den Hilfsfunktionen initErweiterterGraph, getAbstand, getHerkunft, setAbstand, setHerkunft, ... lässt sich auch der Algorithmus von Dijkstra implementieren. Du kannst dich an der Implementierung des Algorithmus von Moore orientieren. Zum Testen kannst du das folgende Testprogramm nutzen und variieren.

# Erzeugung des Testgraphentestgraph_mit_gewichten = \[['A', [('C', 20), ('E', 2), ('G', 9)]],['B', [('C', 1), ('D', 8)]],['C', [('A', 20), ('D', 10), ('E', 13)]],['D', [('B', 8), ('E', 16)]],['E', [('D', 16), ('G', 5)]],['F', [('B', 3), ('D', 4), ('H', 5)]],['G', [('D', 2)]],['H', [('F', 5), ('G', 7)]]]

# Test des Dijkstra-Algorithmusstart = 'A'ziel = 'B'print('kürzester Weg von', start, 'nach', ziel, ':')(weg, laenge) = kuerzesterWegDijkstra(testgraph_mit_gewichten, start, ziel)for w in weg: print(w)print('Weglänge:', laenge)

61 Implementierung des Dijkstra-Alg.

Aufgabe:Eine weitere Implementierung des Algorithmus von Dijkstra findest du in der Klasse GraphDijkstra (siehe inf-schule). Objekte der Klasse GraphDijkstra stellen die Operation kuerzesterWegDijkstra zur Verfügung, mit der man kürzeste Wege in gewichteten Graphen bestimmen kann. Teste auch diese Implementierung.

from graph_dijkstra import *

# Erzeugung des Graph-Objektsg = GraphDijkstra()# Erzeugung der Knoten und Kanten aus einer GraphML-Dateidatei = open("graph_mit_gewichten.xml", "r")xml_quelltext = datei.read()g.graphmlToGraph(xml_quelltext) # Kontrollausgabe des Graphenprint('Graph:')for knoten in g.getAlleKnoten(): print(knoten, ':', g.getAlleNachbarn(knoten))print()# Test des Dijkstra-Algorithmusstart = 'A'ziel = 'B'print('kürzester Weg von', start, 'nach', ziel, ':')(weg, laenge) = g.kuerzesterWegDijkstra(start, ziel)for w in weg: print(w)print('Weglänge:', laenge)

62

Routenplanung mit dem Dijkstra-Alg.

Aufgabe:

Zunächst betrachten wir das vereinfachte Autobahnnetz rund um Ludwigshafen und Mannheim.

Benutze die Implementierung des Algorithmus von Dijkstra, um den kürzesten Weg vom Kreuz Frankenthal zum Kreuz Heidelberg zu ermitteln. Die Daten zum Autobahnnetz findest du in der Datei graph_bab_lu_ma.xml (siehe inf-schule).

63

Routenplanung mit dem Dijkstra-Alg.

Aufgabe:

Benutze die Daten zum Autobahnnetz in Deutschland, um den kürzesten Weg vom 'KREUZ FRANKENTHAL' zum 'KREUZ HEIDELBERG' bzw. von 'TRIER - VERTEILERKREIS (A 602)' nach 'KREUZ MÜNCHEN - WEST' zu bestimmen. Vergleiche die Ergebnisse auch mit denen, die ein professioneller Routenplaner liefert.

Die Daten zum Autobahnnetz findest du in der Datei graph_bab.xml (siehe inf-schule).Quelle:http://de.wikipedia.org/wiki/Autobahn_%28Deutschland%29Autor der Karte: M. Stadthaus

64

Routenplanung mit dem Dijkstra-Alg.

Aufgabe:

Teste auch die GUI-Version des Routenplanerprogramms (siehe inf-schule).

Vergleiche auch die vom Simulationsprogramm gelieferten Daten auch mit den Ergebnissen realer Routenplaner.

65

Routenplanung mit dem Dijkstra-Alg.

Aufgabe:

Die Bestimmung kürzester Wege mit dem Algorithmus von Dijstra in der bisher gezeigten Form dauert bei einer großen Datebasis sehr lange. Woran liegt das? Entwickle Ideen, wie man den Suchaufwand verringern könnte. Versuche eventuell auch, diese Ideen umzusetzen.

66

Routenplanung mit dem Dijkstra-Alg.

Aufgabe:

Die Aufbereitung der Ergebnisse (Auflistung der Stationen der Route) kann ebenfalls noch verbessert werden.

('TRIER - VERTEILERKREIS (A 602)', 'TRIER - EHRANG (A 602)') ('A 602', 5.0)('TRIER - EHRANG (A 602)', 'TRIER - RUWER (A 602)') ('A 602', 2.0)('TRIER - RUWER (A 602)', 'SCHWEICH (A 602)') ('A 602', 2.0)('SCHWEICH (A 602)', 'DREIECK MOSELTAL') ('A 602', 1.0)('DREIECK MOSELTAL', 'MEHRING (A 1)') ('A 1', 8.0)('MEHRING (A 1)', 'REINSFELD (A 1)') ('A 1', 14.0)('REINSFELD (A 1)', 'HERMESKEIL (A 1)') ('A 1', 2.0)('HERMESKEIL (A 1)', 'BIERFELD (A 1)') ('A 1', 7.0)('BIERFELD (A 1)', 'DREIECK NONNWEILER') ('A 1', 2.0)('DREIECK NONNWEILER', 'OTZENHAUSEN (A 62)') ('A 62', 0.3)('OTZENHAUSEN (A 62)', 'NOHFELDEN - TÜRKISMÜHLE (A 62)') ('A 62', 8.0)('NOHFELDEN - TÜRKISMÜHLE (A 62)', 'BIRKENFELD (A 62)') ('A 62', 6.0)('BIRKENFELD (A 62)', 'FREISEN (A 62)') ('A 62', 9.0)('FREISEN (A 62)', 'REICHWEILER (A 62)') ('A 62', 4.0)('REICHWEILER (A 62)', 'KUSEL (A 62)') ('A 62', 7.0)('KUSEL (A 62)', 'GLAN - MÜNCHWEILER (A 62)') ('A 62', 9.0)('GLAN - MÜNCHWEILER (A 62)', 'HÜTSCHENHAUSEN (A 62)') ('A 62', 6.0)('HÜTSCHENHAUSEN (A 62)', 'KREUZ LANDSTUHL - WEST') ('A 62', 3.0)...

67 Teil 4

Rundreisen in Graphen

68 Das Problem

Wenn ein neuer Außenminister im Amt ist, dann versucht er (oder sie), möglichst rasch Antrittsbesuche bei den wichtigsten Bündnispartnern zu machen. Zu diesen Partner gehören natürlich auch die Länder der Europäischen Union (EU).

Wir werden hier folgende Situation durchspielen: Nach einer Bundestagswahl soll der neue Außenminister alle Hauptstädte der EU besuchen. Die Reihenfolge soll sich nicht nach der Bedeutung der Länder oder anderen Kriterien richten. Sie soll so gewählt werden, dass der gesamte Reiseweg für den Minister möglichst gering wird.

69 Das Problem

Als Willy Brand 1966 Außenminister wurde, bestand die EU (damals EWG) aus nur 6 Ländern: Deutschland, Frankreich, Italien, Niederlande, Belgien und Luxemburg. Die Tabelle zeigt die Entfernungen der jeweiligen Hauptstädte.

Bonn Paris Rom Den Ha. Brüssel Luxemb.Bonn 0 401 1066 244 195 145Paris 401 0 1108 383 262 287Rom 1066 1108 0 1289 1174 989Den Ha. 245 383 1289 0 137 302Brüssel 195 262 1174 137 0 187Luxemb. 145 287 989 302 187 0

Aufgabe:Versuche, eine möglichst kurze Rundreise mit Start- und Zielort Bonn zu finden. Bestimme auch die Gesamtlänge der Rundreise.

70 Das Problem

Die EU (bzw. EWG bzw. EG) ist seit ihrer Gründung 1957 mehrfach erweitert worden. Zu Beginn bestand sie aus 6 Mitgliedsstaaten. Diese 6-er-Gemeinschaft ist 1973 zu einer 9-er-Gemeinschaft, 1981 bis 1986 zu einer 12-er-Gemeinschaft, 1995 zu einer 15-er-Gemeinschaft, 2004 zu einer 25-er-Gemeinschaft und 2007 zu einer 27-er-Gemeinschaft gewachsen. Weitere Staaten warten auf den baldigen Beitritt zu dieser Gemeinschaft.

Aufgabe:Welche Schwierigkeiten sind bei der Bestimmung der kürzesten Rundreise zu erwarten?

71 Ein einfacher Lösungsalgorithmus

Idee:

Erzeuge alle möglichen Rundreisen und bestimme jeweils die Länge der Rundreise. Ermittle aus den erzeugten Längenwerten die optimale Route.

Aufgabe:

Teste das beschriebene Verfahren mit dem Simulationsprogramm (siehe inf-schule) und bestimme den kürzesten Rundweg bei den vorgegebenen Hauptstädten.

72 Ein einfacher Lösungsalgorithmus

Idee:

Erzeuge alle möglichen Rundreisen und bestimme jeweils die Länge der Rundreise. Ermittle aus den erzeugten Längenwerten die optimale Route.

ALGORITHMUS RundreisestartRouteOhneStartKnoten = Liste aller Knotennamen ohne den startKnotenstartRoute = [startKnoten] + startRouteOhneStartKnoten + [startKnoten]routeOhneStartKnoten = Kopie von startRouteOhneStartKnotenroute = startRouteminLaenge = Länge von routeminRoute = routeendePermutationen = Falsewhile not endePermutationen: routeOhneStartKnoten = naechste_permutation(routeOhneStartKnoten) route = [startKnoten] + routeOhneStartKnoten + [startKnoten] if self.laenge(route) < minLaenge: minLaenge = self.laenge(route) minRoute = route endePermutationen = (routeOhneStartKnoten == startRouteOhneStartKnoten)

73 Erzeugung von Permutationendef naechste_permutation(L): # best. max. Index i mit L[i] < L[i+1] i = len(L)-2 gefunden = False while not gefunden: if i < 0: gefunden = True else: if L[i] < L[i+1]: gefunden = True else: i = i-1 if i >= 0: # best. max. Index j mit L[j] > L[i] j = i+1 m = j while j < len(L)-1: j = j+1 if L[j] > L[i]: m = j j = m ...

... # vertausche L[i] und L[j] h = L[i] L[i] = L[j] L[j] = h # kehre Restliste ab Position i+1 um i = i+1 j = len(L)-1 while i < j: h = L[i] L[i] = L[j] L[j] = h i = i+1 j = j-1 else: # Liste ist absteigend sortiert # kehre Liste um i = 0 j = len(L)-1 while i < j: h = L[i] L[i] = L[j] L[j] = h i = i+1 j = j-1 return L

74 Erzeugung von Permutationen

Aufgabe:

Teste die Funktion naechste_permutation durch Funktionsaufrufe wie die folgenden. Versuche auch zu verstehen, wie die jeweils nächste Permutation gebildet wird.>>> naechste_permutation(['A', 'B', 'C', 'D', 'E'])['A', 'B', 'C', 'E', 'D']>>> naechste_permutation(['A', 'B', 'C', 'E', 'D'])['A', 'B', 'D', 'C', 'E']

Aufgabe:

Entwickle ein Testprogramm, mit dem man ermitteln kann, wie viele verschiedene Permutationen bei einer Liste mit 5 (bzw. 6, ...) verschiedenen Elementen möglich sind.

75

Suche nach der kürzesten Rundreisen

from graph import *

def naechste_permutation(L): # siehe oben

def laenge(g, rundreise): weglaenge = 0 anzahlKnoten = len(rundreise) i = 1 while i < anzahlKnoten: weglaenge = weglaenge + float(g.getGewichtKante(rundreise[i-1], rundreise[i])) i = i+1 return weglaenge def minRundreise(g, startKnoten): # siehe nächste Seite

# Erzeugung des Graph-Objektsg = GraphMitDaten()# Erzeugung der Knoten und Kanten aus einer GraphML-Dateidatei = open("graph_eu_6.xml", "r")xml_quelltext = datei.read()g.graphmlToGraph(xml_quelltext) # Test des Rundreise-Algorithmus(minRoute, minLaenge) = minRundreise(g, 'Bonn')print('Route:', minRoute)print('Länge:', minLaenge)

76

Suche nach der kürzesten Rundreisen

def minRundreise(g, startKnoten): startRouteOhneStartKnoten = [] for knoten in g.getAlleKnoten(): if knoten != startKnoten: startRouteOhneStartKnoten = startRouteOhneStartKnoten + [knoten] startRoute = [startKnoten] + startRouteOhneStartKnoten + [startKnoten] routeOhneStartKnoten = startRouteOhneStartKnoten[:] route = startRoute minLaenge = laenge(g, route) minRoute = route endePermutationen = False while not endePermutationen: routeOhneStartKnoten = naechste_permutation(routeOhneStartKnoten) route = [startKnoten] + routeOhneStartKnoten + [startKnoten] if laenge(g, route) < minLaenge: minLaenge = laenge(g, route) minRoute = route endePermutationen = (routeOhneStartKnoten == startRouteOhneStartKnoten) return (minRoute, minLaenge)

Aufgabe:

Führe das Testprogramm aus. Ändere es auch wie folgt ab: Es sollen alle erzeugten Routen mit ihren Längen ausgegeben werden. Es soll zusätzlich mitgezählt werden, wie viele Routen erzeugt werden (zur Kontrolle: 120).

Bevor du anfängst, bei 27 (bzw. 25) Hauptstädten alle Rundreisen zu erzeugen, berechne erst einmal, wie viele das sind.

77 Aufwandsanalyse

Die Problemgröße wird durch die Anzahl n der Mitgliedsländer der EU (Knoten des Graphen) festgelegt. Je größer n ist, desto größer ist auch der Aufwand zur Berechnung der Problemlösung.

Als Kostenmaß für den Berechnungsaufwand wählen wir die Anzahl der zu erzeugenden und verarbeitenden Rundreisen R(n). Wir gehen dabei davon aus, dass jede zu erzeugende und verarbeitende Rundreise in etwa den gleichen Berechnungsaufwand hat.

Für R(n) kann man einen recht einfachen Berechnungsterm entwickeln:

Bei n Knoten gibt es vom Startknoten aus n-1 Möglichkeiten, den nächsten Knoten zu wählen. Von jedem dieser n-1 Knoten gibt es dann noch n-2 Möglichkeiten, den nächsten Knoten zu wählen, usw.. Insgesamt erhält man die folgende Formel:

R(n) = (n-1)*(n-2)*...*2*1 = (n-1)!

0 ! = 11 ! = 12 ! = 23 ! = 64 ! = 245 ! = 1206 ! = 7207 ! = 50408 ! = 403209 ! = 36288010 ! = 362880011 ! = 3991680012 ! = 47900160013 ! = 622702080014 ! = 8717829120015 ! = 130767436800016 ! = 2092278988800017 ! = 35568742809600018 ! = 640237370572800019 ! = 12164510040883200020 ! = 243290200817664000021 ! = 5109094217170944000022 ! = 112400072777760768000023 ! = 2585201673888497664000024 ! = 62044840173323943936000025 ! = 15511210043330985984000000

78 Anwendbarkeit des Algorithmus

Aufgabe:

Man kann recht einfach ermitteln, wie lange ein Rechner zur Erzeugung und Verarbeitung einer Rundreise benötigt: Ergänze hierzu einen Zähler und eine Ausgabe des Zählers nach z.B. 1000 oder 10000 oder 100000 Zählschritten. Aus der grob gemessenen Zeit kann man dann die gesuchte Zeit abschätzen. Wir gehen im folgenden davon aus, dass man für 1000 Rundreisen etwa 1 Sekunde benötigt.

Schätze mit den oben gezeigten Daten ab, wie lange es dauert, bis die kürzeste Rundreise mit dem vorliegenden Algorithmus bei 25 Knoten gefunden ist. Beurteile mit dem Ergebnis die praktische Anwendbarkeit des Algorithmus.

0 ! = 11 ! = 12 ! = 23 ! = 64 ! = 245 ! = 1206 ! = 7207 ! = 50408 ! = 403209 ! = 36288010 ! = 362880011 ! = 3991680012 ! = 47900160013 ! = 622702080014 ! = 8717829120015 ! = 130767436800016 ! = 2092278988800017 ! = 35568742809600018 ! = 640237370572800019 ! = 12164510040883200020 ! = 243290200817664000021 ! = 5109094217170944000022 ! = 112400072777760768000023 ! = 2585201673888497664000024 ! = 62044840173323943936000025 ! = 15511210043330985984000000

79 Näherungsverfahren

Aufgabe:

Überlege dir eine Strategie, wie man "mit Köpfchen" statt der "Holzhammermethode" bei der Suche nach der kürzesten Rundreise vorgehen könnte.

80

Stategie: zum am nächst lieg. Knoten

Aufgabe:

Eine naheliegende Strategie besteht darin, vom jeweils aktuellen Knoten zum am nächst liegenden Knoten zu gehen.

Die Abbildung zeigt die Route, die nach der Strategie "zum am nächst liegenden Knoten" berechnet wurde. Versuche, die Route / Strategie zu bewerten: Gibt es kürzere Routen? Welche Nachteile hat die Strategie?

81

Stategie: Integration entfernter Knoten

In einem ersten Schritt wird die Stadt gesucht, die am weitesten von Berlin entfernt ist. Im vorliegenden Fall ist es die Hauptstadt Nikosia von Zypern. Das Rundreisegerüst besteht jetzt aus Berlin - Nikosia - Berlin.

82

Stategie: Integration entfernter Knoten

In einem nächsten Schritt wird die Stadt gesucht, die zu den Knoten des aktuellen Rundreisegerüsts den größten Abstand hat. Im vorliegenden Fall ist es die Hauptstadt Lissabon von Portugal. Diese Stadt wird jetzt so in das Rundreisengerüst eingebaut, dass das neue Rundreisegerüst eine möglichst geringe Länge hat. Es ergibt sich Berlin - Nikosia - Lissabon - Berlin.

83

Stategie: Integration entfernter Knoten

Es wird die Stadt gesucht, die zu den Knoten des aktuellen Rundreisegerüsts den größten Abstand hat. Im vorliegenden Fall ist es Dublin, die die Hauptstadt von Irland. Diese Stadt wird jetzt so in das Rundreisengerüst eingebaut, dass das neue Rundreisegerüst eine möglichst geringe Länge hat. Es ergibt sich Berlin - Nikosia - Valetta - Lissabon - Dublin - Berlin.

84

Stategie: Integration entfernter Knoten

Wenn man auf diese Weise weiterverfährt, ergibt sich insgesamt die folgende Rundreise.

Aufgabe:

Vergleiche das Ergebnis der Stategie "Integration der am weitesten entfernten Knoten" mit dem Ergebnis der Strategie "zum am nächst liegenden Knoten". Kann man mit Sicherheit behaupten, dass die Strategie "Integration der am weitesten entfernten Knoten" die kürzeste Rundreise liefert?

85

Näherungslösungen statt exakter Lös.

Bei 27 Hauptstädten ist es unmöglich, die exakte Lösung nach der Holzhammer-Methode in der zur Verfügung stehenden Zeit zu bestimmen. In vertretbarem Aufwand (mehrere Stunden) geht das noch bei 12 Hauptstädten. Hier ist dann ein Vergleich der exakten Lösung mit Näherungslösungen möglich.

Methode: zum am nächst lieg. Knoten

Länge der Rundreise: 10444.6

Methode: Integration entfernter Knoten

Länge der Rundreise: 9012.6

Methode: Erzeugung aller Rundreisen

Länge der Rundreise: 8945.1

86 Literaturhinweise

U. Schöning: Ideen der Informatik. Oldenbourg Verlag 2002.

P. Gritzmann, R. Brandenburg: Das Geheimnis des kürzesten Weges. Springer 2002.

Mathe-Prisma: Graphenhttp://www.matheprisma.uni-wuppertal.de/Module/Graphen/index.htm

D. Jonietz: Graphen http://informatik.bildung-rp.de/fileadmin/user_upload/informatik.bildung-rp.de/Weiterbildung/pdf/WB-VIII-6-Graphen.pdf

...

Die Darstellung hier orientiert sich an den Materialien auf den Webseiten:

http://www.inf-schule.de