algorithmische grundlagen einführung in das programmieren ... · 4.6 das small-world-problem und...

854
Algorithmische Grundlagen Einf¨ uhrung in das Programmieren mit Python (Teil 1) Sommersemester 2019 Martin Mundhenk Uni Jena, Institut f¨ ur Informatik 4. Juli 2019

Upload: others

Post on 27-Jun-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Algorithmische Grundlagen

Einfuhrung in das Programmieren

mit Python

(Teil 1)

Sommersemester 2019

Martin Mundhenk

Uni Jena, Institut fur Informatik

4. Juli 2019

Page 2: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung Algorithmische Grundlagen

(Sommer 2019)

Die Vorlesung/Ubung orientiert sich am Buch

Introduction to Programming in Python – An Interdisciplinary Approach

von Robert Sedgewick, Kevin Wayne und Robert Dondero

(Addison Wesley, 2015)

Auch die Webseite zum Buch

http://introcs.cs.princeton.edu/python/home/

ist fur diese Vorlesung nutzlich.

Page 3: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Organisatorisches zum Erwerb von Leistungspunktenhttp://www.complexity.uni-jena.de/Python1

§ Vorlesung montags, 16-18 Uhr, oder mittwochs, 12-14 Uhr, Raum 3325, Ernst-Abbe-Platz 2.§ Ubung donnerstags, 8-10 Uhr, Raum 3410 (Linux-Pool 2), EAP2.

Zur Teilnahme brauchen Sie eine Nutzerkennung beim KSZ!(KSZ: Kompetenz- und Servicezentrum der Fakultat fur Mathematik und Informatik,

Ernst-Abbe-Platz 2, 4.Stock (ehemals: Fakultatsrechenzentrum))

§ Es gibt ein wochentliches Ubungsblatt (ca. 12).Abgabe ist montags 16 Uhr (an [email protected]).

§ Zur Zulassung zur Modulprufung mussen jeweils mindestens 50% der Punkte derUbungsblatter aus der ersten und der zweiten Semesterhalfte erreicht sein.

§ Die Abschlussprufung ist mundlich und dauert ca. 30 Minuten.Sie besteht aus der Vorstellung eines Programmierprojekts. Alle Dateien dazu mussen bisspatestens 30 Stunden vor Beginn der Prufung per Email bei mir angekommen sein([email protected]).Prufungstermine sind ab August und werden noch bekannt gegeben.

Page 4: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Inhaltsverzeichnis (vorlaufig)

1. Elemente des Programmierens1.2 Grundlegende Daten-Typen1.3 Verzweigungen und Schleifen1.4 Arrays1.5 Ein- und Ausgabe1.6 Dictionaries und Abschluss-Beispiel Page Rank

2. Funktionen und Module2.1 Definition von Funktionen2.2 Module und Klienten2.3 Rekursion

3. Objekt-orientierte Programmierung (erste Schritte)3.1 Benutzung von Daten-Typen

4. Algorithmen4.1 Rechenzeit4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken

Die Nummerierung der Kapitel 1, 2 und 4 entspricht (fast) der Nummerierung im Buch von Sedgewick et al.

0.0.4

Page 5: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Elemente des Programmierens

Ein Programm zu schreiben ist nicht schwieriger,

als einen Aufsatz zu schreiben.

Wir schauen uns die Grundbausteine von Programmen der Programmiersprache Python an und

starten mit dem Programmieren.

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und Schleifen

1.4 Arrays

1.5 Ein- und Ausgabe

1.6 Dictionaries und Abschluss-Beispiel Page Rank

Page 6: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 01

1. Elemente des Programmierens

1.2 Grundlegende Daten-TypenDas erste Programm

Datentyp int – ganze Zahlen

Datentyp str – Zeichenfolgen

Datentyp bool – Wahrheitswerte

Datentyp float – Dezimalbruche

Anhang

1.3 Verzweigungen und Schleifen

1.4 Arrays

1.5 Ein- und Ausgabe

1.6 Dictionaries und Abschluss-Beispiel Page Rank

1.2.1

Page 7: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1.2 Grundlegende Datentypen

Programme dienen der Verarbeitung von Daten.

Die elementaren Arten von Daten fur die Programmiersprache Python sind

§ Zahlen,

§ Texte und

§ Wahrheitswerte.

Zu ihrer Verarbeitung sind verschiedene Grund-Operationen verfugbar

(und sie werden intern unterschiedlich behandelt).

1.2.2

Page 8: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Breite Tiefe

Hoh

e

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache = 2 ¨ Breite ¨ Hohe + 2 ¨ Breite ¨ Tiefe + 2 ¨ Hohe ¨ Tiefe= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 9: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Breite Tiefe

Hoh

e

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache = 2 ¨ Breite ¨ Hohe + 2 ¨ Breite ¨ Tiefe + 2 ¨ Hohe ¨ Tiefe= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 10: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Breite Tiefe

Hoh

e

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache =

2 ¨ Breite ¨ Hohe + 2 ¨ Breite ¨ Tiefe + 2 ¨ Hohe ¨ Tiefe= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 11: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Breite TiefeBreite

Hoh

e

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache = 2 ¨ Breite ¨ Hohe

+ 2 ¨ Breite ¨ Tiefe + 2 ¨ Hohe ¨ Tiefe= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 12: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Breite Tiefe

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache = 2 ¨ Breite ¨ Hohe + 2 ¨ Breite ¨ Tiefe

+ 2 ¨ Hohe ¨ Tiefe= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 13: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Tiefe

Hoh

e

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache = 2 ¨ Breite ¨ Hohe + 2 ¨ Breite ¨ Tiefe + 2 ¨ Hohe ¨ Tiefe

= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 14: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Berechne Volumen und Oberflache eines Quaders

Breite Tiefe

Hoh

e

Volumen = Breite ¨ Hohe ¨ Tiefe (es werden ganze Zahlen benutzt)

Oberflache = 2 ¨ Breite ¨ Hohe + 2 ¨ Breite ¨ Tiefe + 2 ¨ Hohe ¨ Tiefe= 2 ¨ ( Breite ¨ Hohe + Breite ¨ Tiefe + Hohe ¨ Tiefe )

Erstes Programm-Beispiel 1.2.3

Page 15: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

Hoehe = 5

Breite = 12

Tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

Volumen = Breite * Hoehe * Tiefe

Oberflaeche = 2 * ( Breite*Hoehe + Breite*Tiefe + Hoehe*Tiefe )

# Die berechneten Werte werden ausgegeben.

print(Volumen)

print(Oberflaeche)

Erstes Programm-Beispiel 1.2.4

Page 16: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

Hoehe = 5

Breite = 12

Tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

Volumen = Breite * Hoehe * Tiefe

Oberflaeche = 2 * ( Breite*Hoehe + Breite*Tiefe + Hoehe*Tiefe )

# Die berechneten Werte werden ausgegeben.

print(Volumen)

print(Oberflaeche)

Kommentar beginnt mit”#“. Von dort ab wird die Zeile ignoriert (. . . )

Erstes Programm-Beispiel 1.2.4

Page 17: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

Hoehe = 5

Breite = 12

Tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

Volumen = Breite * Hoehe * Tiefe

Oberflaeche = 2 * ( Breite*Hoehe + Breite*Tiefe + Hoehe*Tiefe )

# Die berechneten Werte werden ausgegeben.

print(Volumen)

print(Oberflaeche)

Hoehe, Breite, Tiefe, Oberflaeche und Volumen sind Variablen.Erstes Programm-Beispiel 1.2.4

Page 18: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

Hoehe = 5

Breite = 12

Tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

Volumen = Breite * Hoehe * Tiefe

Oberflaeche = 2 * ( Breite*Hoehe + Breite*Tiefe + Hoehe*Tiefe )

# Die berechneten Werte werden ausgegeben.

print(Volumen)

print(Oberflaeche)

Hoehe = . . . weist der Variablen Hoehe den Wert von . . . zu.Erstes Programm-Beispiel 1.2.4

Page 19: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

Hoehe = 5

Breite = 12

Tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

Volumen = Breite * Hoehe * Tiefe

Oberflaeche = 2 * ( Breite*Hoehe + Breite*Tiefe + Hoehe*Tiefe )

# Die berechneten Werte werden ausgegeben.

print(Volumen)

print(Oberflaeche)

Steht eine Variable nicht links von =, dann wird ihr Wert benutzt.Erstes Programm-Beispiel 1.2.4

Page 20: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

Hoehe = 5

Breite = 12

Tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

Volumen = Breite * Hoehe * Tiefe

Oberflaeche = 2 * ( Breite*Hoehe + Breite*Tiefe + Hoehe*Tiefe )

# Die berechneten Werte werden ausgegeben.

print(Volumen)

print(Oberflaeche)

Das Programm rechnet mit ganzen Zahlen und benutzt die Operatoren + und * .Erstes Programm-Beispiel 1.2.4

Page 21: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein erstes Python-Programm

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = breite * hoehe * tiefe

oberflaeche = 2 * ( breite*hoehe + breite*tiefe + hoehe*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

Konvention: Variablennamen beginnen mit kleinen Buchstaben.Erstes Programm-Beispiel 1.2.5

Page 22: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe

5

breite

12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 23: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe

5

breite

12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 24: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe

5

breite

12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 25: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite

12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 26: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite

12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 27: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 28: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe

32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 29: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 30: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefevolumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen

1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 31: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefevolumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 32: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche

1208

Erstes Programm-Beispiel 1.2.6

Page 33: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche 1208

Erstes Programm-Beispiel 1.2.6

Page 34: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche 1208

Erstes Programm-Beispiel 1.2.6

Page 35: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)print(volumen)

print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche 1208

Erstes Programm-Beispiel 1.2.6

Page 36: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche 1208

Erstes Programm-Beispiel 1.2.6

Page 37: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was beim Start des Programms passiert . . . (sehr grobe Vorstellung)

Das Programm legt eine Folge von Anweisungen fest.Jede Anweisung liest und/oder schreibt im Speicher des Rechners.

hoehe = 5

breite = 12

tiefe = 32

volumen = breite * hoehe * tiefe

oberflaeche = 2*(breite*hoehe + breite*tiefe + hoehe*tiefe)

print(volumen)

print(oberflaeche)print(oberflaeche)

Beim Start des Programms werden die Anweisungen inder vorgegebenen Reihenfolge ausgefuhrtund der Speicher wird entsprechend verandert.

$ python3 oberflaeche v1.py

1920

1208

Einfache Vorstellung vom Speicher:

Variable Wert

hoehe 5

breite 12

tiefe 32

volumen 1920

oberflaeche 1208

Erstes Programm-Beispiel 1.2.6

Page 38: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Der Datentyp intinteger, ganze Zahlen

Literale (vom Typ int in Python-Programmen):

2019

2346283472947294

-1263516

0

Datentyp int 1.2.7

Page 39: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Datentyp intinteger, ganze Zahlen

Operatoren: + Addition 2+3

- Subtraktion, Vorzeichen 2-3, -2

* Multiplikation 2*3

** Potenz 2**3

// ganzzahlige Division 17//4

% Rest bei ganzzahliger Division, modulo 17%4

Funktionen: abs( ) Betrag eines int-Wertes abs(-17)

max( , ) Maximum zweier int-Werte max(17,4)

min( , ) Minimum zweier int-Werte min(17,4)

Datentyp int 1.2.8

Page 40: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ausdrucke vom Typ int

bestehen aus

§ Literalen vom Typ int

§ Variablen, die an Objekte vom Typ int gebunden sind (s.u.)§ den Operatoren + - * ** // %

§ Klammern ( und )

§ Funktionen vom Typ int . . .

und werden zu einem Objekt vom Typ int ausgewertet.

Beispiele fur int-Ausdrucke ohne Variablen:60 * 60 * 24

(52-6)*40

max(32,17) + min(28, max(2,4))

(5+7)**2

5**2 + 2*5*7 + 7**max(9,12)Datentyp int 1.2.9

Page 41: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Operator // (ganzzahlige Division)

a // b ist die großte ganze Zahl kleiner oder gleich ab

:

17 // 6 ist 2 (da 176 “ 2` 5

6 ),

und -17 // 6 ist -3 (da ´176 “ ´3` 1

6 ).

Mathematische Schreibweise fur die ganzzahlige Division:

a // b entspricht t ab u

txu ist die großte ganze Zahl ď x (”untere Gaußklammer“)

Datentyp int 1.2.10

Page 42: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Operator % (modulo-Operator)

a % b ist der Rest bei der ganzzahligen Division von a durch b (fur positive Zahlen).

17 % 6 ist 5 (da 17 “ 2 ¨ 6` 5)und -17 % 6 ist 1 (da ´17 “ ´3 ¨ 6` 1).

Mathematische Schreibweise fur a % b ist a mod b .

Es gilt: a “ b ¨ t ab u` pa mod bq .

Beispiele fur int-Ausdrucke aus Literalen:

abs((16*60+15)-(17*60+45))//60

abs((16*60+15)-(17*60+45))%60

Die Operatoren haben unterschiedliche Bindungsstarke(entsprechend

”Punktrechnung geht vor Strichrechnung“).

Im Zweifel: Klammern setzen . . . Datentyp int 1.2.11

Page 43: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Weitere Beispiele fur int-Ausdrucke (mit int-Variablen (farbig notiert)):

hh * 60 * 60 + mm * 60 + sec

(52 - 6) * 40 // LP_pro_Jahr

(1+5*((jahr-1)%4)+4*((jahr-1)%100)+6*((jahr-1)%400))%7

Datentyp int 1.2.12

Page 44: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

2019jahr

Variable ObjektBindung

(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 45: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

jahr = 2019erzeugt ein Objekt mit Wert 2019 vom Typ int, und bindet jahr daran

2019

jahr

Variable

ObjektBindung

(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 46: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

jahr = 2019erzeugt ein Objekt mit Wert 2019 vom Typ int, und bindet jahr daran

2019jahr

Variable Objekt

Bindung(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 47: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

jahr = 2019erzeugt ein Objekt mit Wert 2019 vom Typ int, und bindet jahr daran

2019jahr

Variable ObjektBindung

(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 48: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

jahr = 2019

jahr = jahr + 1

erzeugt ein Objekt mit Wert jahr+1 vom Typ int, und bindet jahr daran

2019jahr

Variable ObjektBindung

(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 49: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

jahr = 2019

jahr = jahr + 1

erzeugt ein Objekt mit Wert jahr+1 vom Typ int, und bindet jahr daran

2019jahr

Variable ObjektBindung

(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 50: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anweisungen

Eine Anweisung besteht aus einer Variablen, = und einem Ausdruck.

Beispiele: jahr = 2019

jahr = jahr + 1

Beim Abarbeiten einer Anweisung, deren Wert einen grundlegenden Datentyp hat, wird§ zuerst der Ausdruck ausgewertet

und ein Objekt mit Typ und Wert des Ausdrucks erzeugt, und§ danach wird die Variable an das Objekt gebunden.

jahr = 2019

jahr = jahr + 1

erzeugt ein Objekt mit Wert jahr+1 vom Typ int, und bindet jahr daran

2019jahr

Variable ObjektBindung

(Objekt-Referenz)

2020

Datentyp int 1.2.13

Page 51: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Weitere Beispiele fur Anweisungen:

w = (1+5*((jahr-1)%4)+4*((jahr-1)%100)+6*((jahr-1)%400))%7

arbeitsstundenProLP = (52 - 6) * 40 // LP_pro_Jahr

zaehler = zaehler + 1

zaehler += 1

Datentyp int 1.2.14

Page 52: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 53: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 54: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 55: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 56: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 57: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 58: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 59: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 60: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 61: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 62: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------

# oberflaeche_v1.py

#-----------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

#-----------------------------------------------------------------

# Zuerst werden die Maße des Quaders angegeben.

hoehe = 5

breite = 12

tiefe = 32

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print(volumen)

print(oberflaeche)

#-----------------------------------------------------------------

# python3 oberflaeche.py

# 1920

# 1208

hoehe

breite

tiefe

volumen

oberflaeche

5

12

32

1920

1208

Datentyp int 1.2.15

Page 63: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Der Datentyp strstring, Zeichenfolgen

. . . dient dem Verarbeiten von Texten (das betrifft auch Ein- und Ausgabe).

Die Literale vom Typ str sind Folgen von Zeichen,

die durch ' ... ' oder " ... " eingeschlossen sind.

'Das ist ein str-Literal.' '1234'

Es gibt”spezielle“ Zeichen wie z.B. den Zeilenumbruch \n.

print('Zeile 1\nZeile 2')

liefert die Ausgabe

Zeile1

Zeile2

Achtung: das Literal 1234 ist vom Typ int

das Literal '1234' ist vom Typ strDatentyp str 1.2.16

Page 64: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Der Datentyp strstring, Zeichenfolgen

. . . dient dem Verarbeiten von Texten (das betrifft auch Ein- und Ausgabe).

Die Literale vom Typ str sind Folgen von Zeichen,

die durch ' ... ' oder " ... " eingeschlossen sind.

'Das ist ein str-Literal.' '1234'

Es gibt”spezielle“ Zeichen wie z.B. den Zeilenumbruch \n.

print('Zeile 1\nZeile 2')

liefert die Ausgabe

Zeile1

Zeile2

Achtung: das Literal 1234 ist vom Typ int

das Literal '1234' ist vom Typ strDatentyp str 1.2.16

Page 65: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Der Datentyp strstring, Zeichenfolgen

. . . dient dem Verarbeiten von Texten (das betrifft auch Ein- und Ausgabe).

Die Literale vom Typ str sind Folgen von Zeichen,

die durch ' ... ' oder " ... " eingeschlossen sind.

'Das ist ein str-Literal.' '1234'

Es gibt”spezielle“ Zeichen wie z.B. den Zeilenumbruch \n.

print('Zeile 1\nZeile 2')

liefert die Ausgabe

Zeile1

Zeile2

Achtung: das Literal 1234 ist vom Typ int

das Literal '1234' ist vom Typ strDatentyp str 1.2.16

Page 66: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Datentyp strOperatoren + *

Die Operation + schreibt Strings hintereinander (Konkatenation).

Der Ausdruck 'Das ist ' + 'ein Satz.'

ergibt den String 'Das ist ein Satz.' .

Die Operation * ist eine Operation zwischen str und int.

Der Ausdruck 'Ole' * 4

ergibt den String 'OleOleOleOle'.

Datentyp str 1.2.17

Page 67: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Gib die Einteilungsmarken auf einem Zollstock aus

Die Striche sind im Millimeter-Abstand.Alle 5mm ist der Strich langer, und alle 10mm ist der Strich noch langer.

Beispiel fur die ersten 29 Striche:

| |

| | | | |

|||||||||||||||||||||||||||||

Datentyp str 1.2.18

Page 68: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Gib die Einteilungsmarken auf einem Zollstock aus

Die Striche sind im Millimeter-Abstand.Alle 5mm ist der Strich langer, und alle 10mm ist der Strich noch langer.

Beispiel fur die ersten 29 Striche:

| |

| | | | |

|||||||||||||||||||||||||||||

unterste Zeile : male 29 Striche '|' * 29

vorletzte Zeile : male 4 Leerzeichen und einen Strich,bis 29 Zeichen gemalt wurden ' |' * (29//5)

vorvorletzte Zeile : male 9 Leerzeichen und einen Strich,bis 29 Zeichen gemalt wurden ' |' * (29//10)

Datentyp str 1.2.18

Page 69: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------

# einteilungsmarken.py

#--------------------------------------------------------------------------------

# Die Variable laenge gibt die Lange des Zollstocks in Millimeter an.

laenge = 79

# Die Variable untersteZeile besteht aus den Millimeter-Strichen des Zollstocks.

untersteZeile = '|' * laenge

# Die Variable vorletzteZeile besteht aus 5-Millimeter-Strichen.

vorletzteZeile = ' |' * ( laenge//5 )

# Die Variable vorvorletzteZeile besteht aus 10-Millimeter-Strichen.

vorvorletzteZeile = ((' '*9) + '|') * (laenge//10)

# Die Einteilungsmarken werden ausgegeben.

print(vorvorletzteZeile)

print(vorletzteZeile)

print(untersteZeile)

#----------------------------------------------------------------------------------

# python3 einteilungsmarken.py 79

# | | | | | | |

# | | | | | | | | | | | | | | |

# |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

Datentyp str 1.2.19

Page 70: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

int-Werte zu str-Werten umwandeln

Um den Wert eines Ausdrucks a mit print(a) ausgeben zu konnen,muss a vom Typ str sein oder in ein Objekt vom Typ str umgewandelt werden konnen.

Die Funktion str(x) macht aus einem Objekt x eines grundlegenden Datentyps ein Objekt vomTyp str

”mit dem entsprechenden Wert“. Z.B. liefert str(123) den String '123'.

#--------------------------------------------------------------------

# oberflaeche_v2.py

#--------------------------------------------------------------------

hoehe = 5

breite = 12

tiefe = 32

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print('Das Volumen des Quaders ist ' + str(volumen) + '.')

print('Die Oberflache des Quaders ist ' + str(oberflaeche) + '.')

#---------------------------------------------------------------------

# python3 oberflaeche_v2.py

# Das Volumen des Quaders ist 1920.

# Die Oberflache des Quaders ist 1208.Datentyp str 1.2.20

Page 71: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Eingaben von der Kommandozeile lesen

Beim Starten eines Programms konnen Argumente von der Kommandozeile an das Programmubergeben werden – sie sind stets vom Typ str.

#-------------------------------------------------------------------------

# einundausgabe.py

#-------------------------------------------------------------------------

# Lies drei (durch Leerzeichen getrennte) Strings von der Kommandozeile

# und gib sie in umgekehrter Reihenfolge wieder aus (auf standard output).

#-------------------------------------------------------------------------

import sys

a = sys.argv[1]

b = sys.argv[2]

c = sys.argv[3]

print( c + ' ' + b + ' ' + a )

#------------------------------------------------------

# python3 einundausgabe.py Hallo Martin .

# . Martin Hallo

#

Datentyp str 1.2.21

Page 72: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Eingaben von der Kommandozeile lesen

Beim Starten eines Programms konnen Argumente von der Kommandozeile an das Programmubergeben werden – sie sind stets vom Typ str.

#-------------------------------------------------------------------------

# einundausgabe.py

#-------------------------------------------------------------------------

# Lies drei (durch Leerzeichen getrennte) Strings von der Kommandozeile

# und gib sie in umgekehrter Reihenfolge wieder aus (auf standard output).

#-------------------------------------------------------------------------

import sys

a = sys.argv[1]

b = sys.argv[2]

c = sys.argv[3]

print( c + ' ' + b + ' ' + a )

#------------------------------------------------------

# python3 einundausgabe.py Hallo Martin .

# . Martin Hallo

#

# python3 einundausgabe.py 1 zwei 3.0

# 3.0 zwei 1

#

# python3 einundausgabe.py 1 2 3 4

# 3 2 1

#

# python3 einundausgabe.py 1 2

# Traceback (most recent call last):

# File "einundausgabe.py", line 12, in <module>

# c = sys.argv[3]

# IndexError: list index out of range

Datentyp str 1.2.21

Page 73: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

str-Werte zu int-Werten umwandeln

Entsprechend str( ) macht die Funktion int( ) aus einem Objekt ein int-Objekt.Z.B. liefert int('123') ein int-Objekt mit Wert 123.

#--------------------------------------------------------------------------

# oberflaeche_v3.py

#--------------------------------------------------------------------------

# Lies Hohe, Breite und Tiefe (int) eines Quaders von der Kommandozeile ein

# und gib das Volumen und die Oberflache des Quaders aus.

#--------------------------------------------------------------------------

import sys

# Die Maße des Quaders werden von der Kommandozeile eingelesen.

hoehe = int(sys.argv[1])

breite = int(sys.argv[2])

tiefe = int(sys.argv[3])

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print('Das Volumen des Quaders ist ' + str(volumen) + '.')

print('Die Oberflache des Quaders ist ' + str(oberflaeche) + '.')

# python3 oberflaeche_v3.py 5 12 32

# Das Volumen des Quaders ist 1920.

# Die Oberflache des Quaders ist 1208.

#

# python3 oberflaeche_v3.py 12 34 56

# Das Volumen des Quaders ist 22848.

# Die Oberflache des Quaders ist 5968.

Datentyp str 1.2.22

Page 74: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4 Der Datentyp boolboolean, Wahrheitswerte (George Boole, 1815-1864)

. . . dient dem Rechnen mit Wahrheitswerten True und False.

Literale sind True (fur den Wahrheitswert wahr)

False (fur den Wahrheitswert falsch)

Datentyp bool 1.2.23

Page 75: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Operationen fur Ausdrucke vom Typ bool

Es gibt die 2-stelligen Operation and und or, und die 1-stellige Operation not auf bool-Objekten.

Das Ergebnis ist vom Typ bool.

Die folgenden Tabellen beschreiben die Operationen.

a b a and b

False False False

False True False

True False False

True True True

a b a or b

False False False

False True True

True False True

True True True

a not a

False True

True False

Beispiele fur Ausdrucke und deren Werte:

True and (False or True) hat den Wert True.

(False or not (True and False)) and False hat den Wert False.Datentyp bool 1.2.24

Page 76: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: bestimme, ob ein Jahr ein Schaltjahr ist

Schaltjahre werden nach dem Gregorianischen Kalender wie folgt bestimmt:

1. Die (ohne Rest) durch 4 teilbaren Jahre sind Schaltjahre.

2. Die (ohne Rest) durch 100 teilbaren Jahre sind keine Schaltjahre.Damit sind z.B. 1800, 1900, 2000, 2100 und 2200 keine Schaltjahre.

3. Aber die (ohne Rest) durch 400 teilbaren Jahre sind doch Schaltjahre.Damit sind z.B. 1600, 2000 und 2400 doch wieder Schaltjahre.

Jahr x ist also ein Schaltjahr genau dann, wenn

§ x ist durch 4 teilbar und nicht durch 100 teilbar, oder

§ x ist durch 400 teilbar.

Datentyp bool 1.2.25

Page 77: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

Lies das Jahr von der Kommandozeile.Berechne, ob das Jahr durch 4, durch 100 bzw. durch 400 teilbar ist.Berechne, ob das Jahr die Bedingungs-Kombination fur ein Schaltjahr erfullt.

Ist das Jahr ein Schaltjahr?

Gib aus, dass das Jahr ein Schaltjahr ist. Gib aus, dass das Jahr kein Schaltjahr ist.

Gib noch eine Leerzeile aus.

ja nein

Datentyp bool 1.2.26

Page 78: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

Berechne, ob das Jahr durch 4, durch 100 bzw. durch 400 teilbar ist.Berechne, ob das Jahr die Bedingungs-Kombination fur ein Schaltjahr erfullt.

Ist das Jahr ein Schaltjahr?

Gib aus, dass das Jahr ein Schaltjahr ist. Gib aus, dass das Jahr kein Schaltjahr ist.

Gib noch eine Leerzeile aus.

ja nein

Datentyp bool 1.2.26

Page 79: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

bedingung1 = (jahr % 4 == 0)

bedingung2 = (jahr % 100 == 0)

bedingung3 = (jahr % 400 == 0)

Berechne, ob das Jahr die Bedingungs-Kombination fur ein Schaltjahr erfullt.

Ist das Jahr ein Schaltjahr?

Gib aus, dass das Jahr ein Schaltjahr ist. Gib aus, dass das Jahr kein Schaltjahr ist.

Gib noch eine Leerzeile aus.

ja nein

Datentyp bool 1.2.26

Page 80: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

bedingung1 = (jahr % 4 == 0)

bedingung2 = (jahr % 100 == 0)

bedingung3 = (jahr % 400 == 0)

istSchaltjahr = ( bedingung1 and not bedingung2 ) or bedingung3

Ist das Jahr ein Schaltjahr?

Gib aus, dass das Jahr ein Schaltjahr ist. Gib aus, dass das Jahr kein Schaltjahr ist.

Gib noch eine Leerzeile aus.

ja nein

Datentyp bool 1.2.26

Page 81: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

bedingung1 = (jahr % 4 == 0)

bedingung2 = (jahr % 100 == 0)

bedingung3 = (jahr % 400 == 0)

istSchaltjahr = ( bedingung1 and not bedingung2 ) or bedingung3

istSchaltjahr

Gib aus, dass das Jahr ein Schaltjahr ist. Gib aus, dass das Jahr kein Schaltjahr ist.

Gib noch eine Leerzeile aus.

True False

Datentyp bool 1.2.26

Page 82: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

bedingung1 = (jahr % 4 == 0)

bedingung2 = (jahr % 100 == 0)

bedingung3 = (jahr % 400 == 0)

istSchaltjahr = ( bedingung1 and not bedingung2 ) or bedingung3

istSchaltjahr

print(str(jahr) + ’ ist ein Schaltjahr.’) Gib aus, dass das Jahr kein Schaltjahr ist.

Gib noch eine Leerzeile aus.

True False

Datentyp bool 1.2.26

Page 83: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

bedingung1 = (jahr % 4 == 0)

bedingung2 = (jahr % 100 == 0)

bedingung3 = (jahr % 400 == 0)

istSchaltjahr = ( bedingung1 and not bedingung2 ) or bedingung3

istSchaltjahr

print(str(jahr) + ’ ist ein Schaltjahr.’) print(str(jahr) + ’ ist kein Schaltjahr.’)

Gib noch eine Leerzeile aus.

True False

Datentyp bool 1.2.26

Page 84: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Verzweigung des Programmflusses – if

jahr = int(sys.argv[1])

bedingung1 = (jahr % 4 == 0)

bedingung2 = (jahr % 100 == 0)

bedingung3 = (jahr % 400 == 0)

istSchaltjahr = ( bedingung1 and not bedingung2 ) or bedingung3

istSchaltjahr

print(str(jahr) + ’ ist ein Schaltjahr.’) print(str(jahr) + ’ ist kein Schaltjahr.’)

print()

True False

Datentyp bool 1.2.26

Page 85: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# schaltjahr.py

#-------------------------------------------------------------------------

# Liest int jahr von der Kommandozeile

# und gibt aus, ob das Jahr jahr ein Schaltjahr ist.

#-------------------------------------------------------------------------

import sys

# Lies das Jahr von der Kommandozeile

# und speichere es in Variable jahr (Typ int).

jahr = int(sys.argv[1])

# Bestimme, welche der 3 Bedingungen erfullt werden

# und speichere die Ergebnisse in den Variablen

# bedingung1, bedingung2 und bedingung3 (alle vom Typ bool).

bedingung1 = (jahr % 4 == 0) # jahr ist durch 4 teilbar

bedingung2 = (jahr % 100 == 0) # jahr ist durch 100 teilbar

bedingung3 = (jahr % 400 == 0) # jahr ist durch 400 teilbar

# Bestimme, ob jahr ein Schaltjahr ist

# und speichere das Ergebnis in Variable istSchaltjahr (Typ bool).

istSchaltjahr = ( bedingung1 and not bedingung2 ) or bedingung3

# Gib das Ergebnis aus.

if istSchaltjahr:

print( str(jahr) + ' ist ein Schaltjahr.' )

else:

print( str(jahr) + ' ist kein Schaltjahr.' )

print()

# python3 schaltjahr.py 2019

# 2019 ist kein Schaltjahr.

#

# python3 schaltjahr.py 2100

# 2100 ist kein Schaltjahr.

#

# python3 schaltjahr.py 2000

# 2000 ist kein Schaltjahr.

Datentyp bool 1.2.27

Page 86: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vergleichsoperationen fur Zahlenwerte liefern bool-Werte

Operator Bedeutung Beispiel

True False

== gleich 3==3 2==3

!= ungleich 2!=3 3!=3

< kleiner als 2<3 3<3

<= kleiner oder gleich 3<=3 4<=3

> großer als 4>3 3>4

>= großer oder gleich 4>=3 3>=4

Datentyp bool 1.2.28

Page 87: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

5 Der Datentyp floatfloating point numbers, Fließkommazahlen

. . . dient dem Rechnen mit Dezimalbruchen.

Literale sind z.B. 4.0 (hat den Wert 4)

123.45 (hat den Wert 123, 45)

3.141e+6 (hat den Wert 3,141 ¨ 106 “ 3141000 )

1.234e-6 (hat den Wert 1,234 ¨ 10´6 “ 0, 000001234 )

Operatoren: + Addition- Subtraktion, Vorzeichen* Multiplikation/ Division** Potenz

Datentyp float 1.2.29

Page 88: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ausdrucke vom Typ float

Kommt in einem Ausdruck mit ints ein float-Wert oder eine float-Operation vor,

dann hat das Ergebnis Typ float (und nicht Typ int).

Beispiel: i = 15 # Variable i hat Typ int

f = 1.0 * i # Variable f hat Typ float

a = 4/2 # Variable a hat Typ float, da / nur fur float definiert ist

print(i) # erzeugt Ausgabe 15

print(a) # erzeugt Ausgabe 2.0

float-Werte haben nur beschrankte Genauigkeit.

print(1.234567890123456789e+18) hat Ausgabe

1.2345678901234568e+18 (in Python3),

1.23456789012e+18 (in Python2).

Datentyp float 1.2.30

Page 89: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

float-Werte konnen ungenau sein

int-Werte konnen beliebig groß sein — float-Werte haben nur beschrankte Stellenzahl.Das fuhrt schnell zu falschen Rechenergebnissen – also Augen auf mit float!

#----------------------------------------------------------

# fehler_mit_float.py

#----------------------------------------------------------

# Liest s (int) von der Komandozeile,

# berechnet 10**s+1 (int),

# berechnet 10.0**s+1 (float)

# und die Differenz der beiden Zahlen.

import sys

s = int(sys.argv[1])

intZahl = 10**s + 1

floatZahl = 10.0**s + 1

differenz = intZahl - floatZahl

# Die beiden Zahlen und ihre Differenz werden ausgegeben.

print( 'int Zahl: ' + str(intZahl) )

print( 'float Zahl: ' + str(floatZahl) )

print( 'Differenz : ' + str(differenz) )

#----------------------------------------------------------

#------------------------------------

# python3 fehler_mit_float.py 15

# int Zahl: 1000000000000001

# float Zahl: 1000000000000001.0

# Differenz : 0.0

#

# python3 fehler_mit_float.py 16

# int Zahl: 10000000000000001

# float Zahl: 1e+16

# Differenz : 0.0

#

# python3 fehler_mit_float.py 22

# int Zahl: 10000000000000000000001

# float Zahl: 1e+22

# Differenz : 0.0

#

# python3 fehler_mit_float.py 23

# int Zahl: 100000000000000000000001

# float Zahl: 1e+23

# Differenz : 16777216.0Datentyp float 1.2.31

Page 90: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Funktionen fur float

”Eingebaute“ Funktionen:

abs(x) der Betrag von x

max(x,y), min(x,y) Maximum bzw. Minimum von x und y

round(x) nachster int-Wert zu x (in Python3),nachster ganzzahliger float-Wert zu x (in Python2).

str(x), int(x), bool(x) Umwandlung in Objekt des jeweiligen Typs

Funktionen aus dem Modul math von Python:math.sqrt(x) Wurzelfunktionmath.log(x,b) Logarithmus von x zur Basis b

Funktion aus dem Modul random von Python:random.random() eine zufallige float-Zahl x mit 0 ď x ă 1

Datentyp float 1.2.32

Page 91: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

§ Wir haben die elementaren Daten-Typen int, float, str und bool von Python

kennengelernt.

§ Wir konnen Ausdrucke aus Literalen, Variablen, Operatoren und Funktionen schreiben und

deren Typen bestimmen.

§ Wir konnen sehr einfache Programme mit

Eingabe von Argumenten (von der Kommandozeile)

Abarbeitung einer festen Folge von Anweisungen

Ausgabe von Ergebnissen (auf dem Bildschirm)

schreiben und deren Ausfuhrung nachvollziehen.

1.2.33

Page 92: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Eingabe von der Tastatur

Die Funktion input(s) gibt String s auf dem Bildschirm aus (standard output)

und hat als Wert die nachste auf der Tastatur eingegebene Zeile (Typ str),

die mit <return> beendet wird.# oberflaeche_v4.py

#--------------------------------------------------------------------

# Berechne das Volumen und die Oberflache eines Quaders.

# Die Seitenlangen des Quaders werden uber die Tastatur eingegeben.

#--------------------------------------------------------------------

# Zuerst werden die Maße des Quaders uber die Tastatur eingegeben.

print('Bitte geben Sie die Seitenlangen des Quaders an.')

hoehe = int(input('Hohe: '))

breite = int(input('Breite: '))

tiefe = int(input('Tiefe: '))

# Daraus konnen nach den bekannten Formeln

# das Volumen und die Oberflache berechnet werden.

volumen = hoehe * breite * tiefe

oberflaeche = 2 * ( hoehe*breite + hoehe*tiefe + breite*tiefe )

# Die berechneten Werte werden ausgegeben.

print('Das Volumen des Quaders ist ' + str(volumen) + '.')

print('Die Oberflache des Quaders ist ' + str(oberflaeche) + '.')

#---------------------------------------------------------------------

# python3 oberflaeche_v4.py

# Bitte geben Sie die Seitenlangen des Quaders an.

# Hohe: 123

# Breite: 456

# Tiefe: 789

# Das Volumen des Quaders ist 44253432.

# Die Oberflache des Quaders ist 1025838.

Anhang: Eingabe von der Tastatur 1.2.34

Page 93: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: berechne die Losungen der quadratischen

Gleichung a ¨ x2 ` b ¨ x ` c “ 0

Die quadratische Gleichung a ¨ x2 ` b ¨ x ` c “ 0 hat die Losungen

x1 “´b `

?b2 ´ 4 ¨ a ¨ c

2 ¨ aund

x2 “´b ´

?b2 ´ 4 ¨ a ¨ c

2 ¨ a.

Anhang: Berechnung der Mitternachtsformel 1.2.35

Page 94: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die quadratische Gleichung a ¨ x2` b ¨ x ` c “ 0 hat die Losungen x1,2 “

´b ˘

Diskriminantehkkkkkkkkikkkkkkkkj

a

b2 ´ 4 ¨ a ¨ c

2 ¨ a.

#----------------------------------------------------------------------------

# mitternacht.py

# Liest float-Werte a, b und c von der Kommandozeile ein

# und gibt die beiden durch die Mitternachtsformel bestimmten Losungen aus.

#----------------------------------------------------------------------------

import sys

import math

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

diskriminante = math.sqrt(b**2 - 4 * a * c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

#----------------------------------------------------------------------------

# python3 mitternacht.py 4 -20.3 3.141

# 4.915241838383638

# 0.15975816161636258

Anhang: Berechnung der Mitternachtsformel 1.2.36

Page 95: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1.3 Verzweigungen und Schleifen

Die bisher betrachteten Programme (bis auf schaltjahr.py) bestanden aus Anweisungen,

die der Reihe nach von der ersten bis zur letzten ausgefuhrt werden.

Nun werden wir sehen, wie man diese Reihenfolge beeinflussen kann.

Abhangig von Bedingungen konnen Anweisungs-Blocke ausgefuhrt oder nicht ausgefuhrt werden

(Verzweigungen),

oder Anweisungs-Blocke konnen mehrfach ausgefuhrt werden (Schleifen).

Mittels Verzweigungen und Schleifen werden wir bereits viel machtigere Programme schreiben

konnen als bisher.

Anhang: Berechnung der Mitternachtsformel 1.3.1

Page 96: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 02

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und SchleifenVerzweigungen – if

Schleifen – while

Schleifen – for

Abschließendes Beispiel: Was Euler nicht wusste . . .

1.4 Arrays

1.5 Ein- und Ausgabe

1.6 Dictionaries und Abschluss-Beispiel Page Rank

2. Funktionen und Module

3. Objekt-orientierte Programmierung (erste Schritte)

4. Algorithmen

Anhang: Berechnung der Mitternachtsformel 1.3.2

Page 97: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Verzweigungen – ifberechne die Losungen der quadratischen Gleichung a ¨ x2

` b ¨ x ` c “ 0

Die quadratische Gleichung a ¨ x2 ` b ¨ x ` c “ 0 hat die Losungen

x “´b `

?b2 ´ 4 ¨ a ¨ c

2 ¨ aund

x “´b ´

?b2 ´ 4 ¨ a ¨ c

2 ¨ a.

if-Verzweigung 1.3.3

Page 98: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die quadratische Gleichung a ¨ x2` b ¨ x ` c “ 0 hat die Losungen x “

´b ˘

Diskriminantehkkkkkkkkikkkkkkkkj

a

b2 ´ 4 ¨ a ¨ c

2 ¨ a.

#----------------------------------------------------------------------------

# mitternacht_v0.py

# Liest float-Werte a, b und c von der Kommandozeile ein

# und gibt die beiden durch die Mitternachtsformel bestimmten Losungen aus.

#----------------------------------------------------------------------------

import sys

import math

# Lies float-Werte a, b und c von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Berechne die Diskriminante.

diskriminante = math.sqrt(b**2 - 4 * a * c)

# Gib die Ergebnisse fur x aus.

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

#----------------------------------------------------------------------------if-Verzweigung 1.3.4

Page 99: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die quadratische Gleichung a ¨ x2` b ¨ x ` c “ 0 hat die Losungen x “

´b ˘

Diskriminantehkkkkkkkkikkkkkkkkj

a

b2 ´ 4 ¨ a ¨ c

2 ¨ a.

#----------------------------------------------------------------------------

# mitternacht_v0.py

# Liest float-Werte a, b und c von der Kommandozeile ein

# und gibt die beiden durch die Mitternachtsformel bestimmten Losungen aus.

#----------------------------------------------------------------------------

import sys

import math

# Lies float-Werte a, b und c von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Berechne die Diskriminante.

diskriminante = math.sqrt(b**2 - 4 * a * c)

# Gib die Ergebnisse fur x aus.

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

#----------------------------------------------------------------------------

# python3 mitternacht_v0.py 4 -20.3 3.141

# 4.915241838383638

# 0.15975816161636258

#

# python3 mitternacht_v0.py 22 56.78 -11.11

# 0.1827300776950099

# -2.763639168604101

if-Verzweigung 1.3.4

Page 100: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Programmfluss . . .

Der Programmfluss besteht bei jeder Eingabe aus der gleichen Folge von Anweisungen.

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

# mitternacht.py

#---------------------------------------------------------------

# Lies a, b und c (float) von der Kommandozeile ein und

# gib die durch die Mitternachtsformel bestimmten Losungen aus.

#---------------------------------------------------------------

import sys, math

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

diskriminante = math.sqrt(b**2 - 4 * a * c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

if-Verzweigung 1.3.5

Page 101: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Programmfluss . . .

Der Programmfluss besteht bei jeder Eingabe aus der gleichen Folge von Anweisungen.

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

# python3 mitternacht.py 4 15 2

# -0.1384445013187745

# -3.6115554986812253

if-Verzweigung 1.3.5

Page 102: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Programmfluss . . .

Der Programmfluss besteht bei jeder Eingabe aus der gleichen Folge von Anweisungen.

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

# python3 mitternacht.py 4 15 2

# -0.1384445013187745

# -3.6115554986812253

# python3 mitternacht.py 0 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 17, in <module>

# print( (-b + diskriminante) / (2*a) )

# ZeroDivisionError: float division by zero

if-Verzweigung 1.3.5

Page 103: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Programmfluss . . .

Der Programmfluss besteht bei jeder Eingabe aus der gleichen Folge von Anweisungen.

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

# python3 mitternacht.py 0 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 17, in <module>

# print( (-b + diskriminante) / (2*a) )

# ZeroDivisionError: float division by zero

# python3 mitternacht.py 4 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 15, in <module>

# diskriminante = math.sqrt(b**2 - 4*a*c)

# ValueError: math domain error

if-Verzweigung 1.3.5

Page 104: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Programmfluss . . .

Der Programmfluss besteht bei jeder Eingabe aus der gleichen Folge von Anweisungen.

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

# python3 mitternacht.py 0 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 17, in <module>

# print( (-b + diskriminante) / (2*a) )

# ZeroDivisionError: float division by zero

# python3 mitternacht.py 4 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 15, in <module>

# diskriminante = math.sqrt(b**2 - 4*a*c)

# ValueError: math domain error

# python3 mitternacht.py 4 4 1

# -0.5

# -0.5

if-Verzweigung 1.3.5

Page 105: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Programmfluss . . .

Der Programmfluss besteht bei jeder Eingabe aus der gleichen Folge von Anweisungen.

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

# python3 mitternacht.py 0 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 17, in <module>

# print( (-b + diskriminante) / (2*a) )

# ZeroDivisionError: float division by zero

# python3 mitternacht.py 4 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 15, in <module>

# diskriminante = math.sqrt(b**2 - 4*a*c)

# ValueError: math domain error

# python3 mitternacht.py 4 4 1

# -0.5

# -0.5

Kann man die Programmabsturze etc. vermeiden?

if-Verzweigung 1.3.5

Page 106: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Drei Falle, die mitternacht.py nicht berucksichtigt

Fall 1:Durch 0 kann man nicht teilen.Dieser Fall tritt ein,wenn fur a auf der Kommandozeile 0 eingegeben wird.

# python3 mitternacht.py 0 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 17, in <module>

# print( (-b + diskriminante) / (2*a) )

# ZeroDivisionError: float division by zero

# mitternacht.py

#-------------------------------------------

import sys, math

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

diskriminante = math.sqrt(b**2 - 4 * a * c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

if-Verzweigung 1.3.6

Page 107: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Drei Falle, die mitternacht.py nicht berucksichtigt

Fall 1:Durch 0 kann man nicht teilen.Dieser Fall tritt ein,wenn fur a auf der Kommandozeile 0 eingegeben wird.

Fall 2:Aus negativen Zahlen kann man keine Wurzel ziehen.Dieser Fall tritt ein, wenn b**2 - 4*a*c kleiner als 0 ist.

# python3 mitternacht.py 4 2 4

# Traceback (most recent call last):

# File "mitternacht.py", line 15, in <module>

# diskriminante = math.sqrt(b**2 - 4*a*c)

# ValueError: math domain error

# mitternacht.py

#-------------------------------------------

import sys, math

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

diskriminante = math.sqrt(b**2 - 4 * a * c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

if-Verzweigung 1.3.6

Page 108: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Drei Falle, die mitternacht.py nicht berucksichtigt

Fall 1:Durch 0 kann man nicht teilen.Dieser Fall tritt ein,wenn fur a auf der Kommandozeile 0 eingegeben wird.

Fall 2:Aus negativen Zahlen kann man keine Wurzel ziehen.Dieser Fall tritt ein, wenn b**2 - 4*a*c kleiner als 0 ist.

Fall 3:Es gibt nur eine Losung der quadratischen Gleichung.Dieser Fall tritt ein, wenn die Diskriminante 0 ist.

# python3 mitternacht.py 4 4 1

# -0.5

# -0.5

# mitternacht.py

#-------------------------------------------

import sys, math

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

diskriminante = math.sqrt(b**2 - 4 * a * c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

if-Verzweigung 1.3.6

Page 109: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

a != 0 ?

print('Die Gleichung hat keine Losung!')

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

ja nein

if-Verzweigung 1.3.7

Page 110: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

a != 0 ?

print('Die Gleichung hat keine Losung!')

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

ja nein

# mitternacht_v1.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

if-Verzweigung 1.3.7

Page 111: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

# mitternacht_v1.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

Zeile-1

Zeile-2...

if Bedingung b:

Zeile-b-1

Zeile-b-2...

else:

Zeile-not-b-1

Zeile-not-b-2...

Zeile-x...

Block

Block

Block

Blockstruktur einer if-Anweisungif-Verzweigung 1.3.7

Page 112: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

# mitternacht_v1.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

Zeile-1

Zeile-2...

if Bedingung b:

Zeile-b-1

Zeile-b-2...

else:

Zeile-not-b-1

Zeile-not-b-2...

Zeile-x...

Block

Block

Block

Blockstruktur einer if-Anweisungif-Verzweigung 1.3.7

Page 113: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

# mitternacht_v1.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

Zeile-1

Zeile-2...

if Bedingung b:

Zeile-b-1

Zeile-b-2...

else:

Zeile-not-b-1

Zeile-not-b-2...

Zeile-x...

Block

Block

Block

Blockstruktur einer if-Anweisungif-Verzweigung 1.3.7

Page 114: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

# mitternacht_v1.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

Zeile-1

Zeile-2...

if Bedingung b:

Zeile-b-1

Zeile-b-2...

else:

Zeile-not-b-1

Zeile-not-b-2...

Zeile-x...

Block

Block

Block

Blockstruktur einer if-Anweisungif-Verzweigung 1.3.7

Page 115: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”

Eingabe 0 fur a“Verzweigung des Programmflusses – if

# mitternacht_v1.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

Zeile-1

Zeile-2...

if Bedingung b:

Zeile-b-1

Zeile-b-2...

else:

Zeile-not-b-1

Zeile-not-b-2...

Zeile-x...

Block

Block

Block

Blockstruktur einer if-Anweisungif-Verzweigung 1.3.7

Page 116: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”b**2 - 4*a*c ist negativ“

Verzweigung des Programmflusses – if

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

a != 0 and b**2 - 4*a*c >= 0?

print('Die Gleichung hat keine Losung!')

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

ja nein

if-Verzweigung 1.3.8

Page 117: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung des Fehlers bei”b**2 - 4*a*c ist negativ“

Verzweigung des Programmflusses – if

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

a != 0 and b**2 - 4*a*c >= 0?

print('Die Gleichung hat keine Losung!')

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b+diskriminante) / (2*a) )

print( (-b-diskriminante) / (2*a) )

ja nein

# mitternacht_v2.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 und b**2 - 4*a*c >= 0 ist.

if a != 0 and b**2 - 4*a*c >= 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print('Die Gleichung hat keine Losung!')

if-Verzweigung 1.3.8

Page 118: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung der zweiten Ausgabe, wenn diskriminante Wert 0 hat

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

a != 0 and b**2 - 4*a*c >= 0?

print('Die Gleichung hat keine Losung!')

diskriminante = math.sqrt(b**2 - 4*a*c)

diskriminante != 0 ?

print( (-b+diskriminante) / (2*a) )

print( -b / (2*a) )

print( (-b-diskriminante) / (2*a) )

ja nein

ja nein

if-Verzweigung 1.3.9

Page 119: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vermeidung der zweiten Ausgabe, wenn diskriminante Wert 0 hat

a = float(sys.argv[1])

b = float(sys.argv[2])

c = float(sys.argv[3])

a != 0 and b**2 - 4*a*c >= 0?

print('Die Gleichung hat keine Losung!')

diskriminante = math.sqrt(b**2 - 4*a*c)

diskriminante != 0 ?

print( (-b+diskriminante) / (2*a) )

print( -b / (2*a) )

print( (-b-diskriminante) / (2*a) )

ja nein

ja nein

# mitternacht_v3.py

#-------------------------------------------

import sys, math

# Lies a, b und c (float)

# von der Kommandozeile ein.

a = float( sys.argv[1] )

b = float( sys.argv[2] )

c = float( sys.argv[3] )

# Es gibt nur dann Ergebnisse,

# wenn a ungleich 0 ist.

if a != 0 and b**2 - 4*a*c >= 0:

diskriminante = math.sqrt(b**2 - 4*a*c)

# Wenn diskriminante nicht 0 ist, dann

# gibt es zwei Ergebnisse, sonst nur eines.

if diskriminante != 0:

print( (-b + diskriminante) / (2*a) )

print( (-b - diskriminante) / (2*a) )

else:

print( -b/(2*a) )

else:

print('Die Gleichung hat keine Losung!')if-Verzweigung 1.3.9

Page 120: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schleifen im Programmfluss

Ublicherweise bestehen Programme aus Anweisungen,

die haufig wiederholt werden.

Die while-Schleife erlaubt die Wiederholung eines Anweisungs-Blocks,

solange eine vorgegebene Bedingung erfullt ist.

Die for-Schleife erlaubt die Wiederholung eines Anweisungs-Blocks

mit mitlaufender Veranderung eines Zahlers.

1.3.10

Page 121: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Schleifen – while

Aufgabe: Ein Schuldner hat 1000 ¿ Schulden.Der Zinssatz ist 5% pro Jahr und er zahlt eine Jahresrate von 100 ¿.Wieviele Jahre muss er zahlen, bis die Schulden abbezahlt sind?

Zinsen alte Schulden + Zinsen - Rate = Schuldenstand

Anfang 2001 1000.00Ende 2001 50.00 950.00Ende 2002 47.50 897.50Ende 2003 44.87 842.37Ende 2004 42.12 784.49Ende 2005 39.22 723.71Ende 2006 36.19 659.90Ende 2007 32.99 592.89Ende 2008 29.65 522.54Ende 2009 26.13 448.67Ende 2010 22.43 371.10Ende 2011 18.56 289.66Ende 2012 14.48 204.14Ende 2013 10.21 114.35Ende 2014 5.71 20.06Ende 2015 1.00 -78.92

while-Schleife 1.3.11

Page 122: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schleifen – while

Wieviele Jahre dauert die Ruckzahlung der Schulden beider Jahresrate und dem Zinssatz?

Um diese Jahreszahl zu berechnen,berechnet man Jahr fur Jahr den Schuldenstand,bis der Schuldenstand ď 0 ist.Dabei zahlt man mit, wieviele Jahre das ging.Der Endstand dieses Zahlers

ist die gesuchte Jahreszahl.

Lies die Eingabe.

Sind die Schulden ą 0 ?

Berechne den Schuldenstand nach Ablauf eines Jahres.

Zahle mit, dass ein weiteres Jahr vergangen ist.

Gib aus, wieviele Jahre vergangen sind.

ja

nein

while-Schleife 1.3.12

Page 123: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schleifen – while

Wieviele Jahre dauert die Ruckzahlung der Schulden beider Jahresrate und dem Zinssatz?

Um diese Jahreszahl zu berechnen,berechnet man Jahr fur Jahr den Schuldenstand,bis der Schuldenstand ď 0 ist.Dabei zahlt man mit, wieviele Jahre das ging.Der Endstand dieses Zahlers

ist die gesuchte Jahreszahl.

schulden = int(sys.argv[1])

zinssatz = float(sys.argv[2])

jahresrate = int(sys.argv[3])

jahreZaehler = 0

schulden > 0 ?

zinsen = schulden * zinssatz / 100

schulden = schulden + zinsen - jahresrate

jahreZaehler = jahreZaehler+1

print('Die Ruckzahlung dauert ' + str(jahreZaehler) + ' Jahre.')

ja

nein

while-Schleife 1.3.13

Page 124: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schleifen – while

Wieviele Jahre dauert die Ruckzahlung der Schulden beider Jahresrate und dem Zinssatz?

Schleifenbedingung

schulden = int(sys.argv[1])

zinssatz = float(sys.argv[2])

jahresrate = int(sys.argv[3])

jahreZaehler = 0

schulden > 0 ?

zinsen = schulden * zinssatz / 100

schulden = schulden + zinsen - jahresrate

jahreZaehler = jahreZaehler+1

print('Die Ruckzahlung dauert ' + str(jahreZaehler) + ' Jahre.')

ja

nein

while-Schleife 1.3.13

Page 125: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schleifen – while

Wieviele Jahre dauert die Ruckzahlung der Schulden beider Jahresrate und dem Zinssatz?

Schleifenbedingung

Schleifenrumpf (Block)

schulden = int(sys.argv[1])

zinssatz = float(sys.argv[2])

jahresrate = int(sys.argv[3])

jahreZaehler = 0

schulden > 0 ?

zinsen = schulden * zinssatz / 100

schulden = schulden + zinsen - jahresrate

jahreZaehler = jahreZaehler+1

print('Die Ruckzahlung dauert ' + str(jahreZaehler) + ' Jahre.')

ja

nein

while-Schleife 1.3.13

Page 126: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schleifen – while

Wieviele Jahre dauert die Ruckzahlung der Schulden beider Jahresrate und dem Zinssatz?

import sys

schulden = int(sys.argv[1])

zinssatz = float(sys.argv[2])

jahresrate = int(sys.argv[3])

jahreZaehler = 0 # Zahler fur die Jahre mit Ratenzahlungen

while schulden > 0 :

# Berechnung des Schuldenstandes nach einem weiteren Jahr.

zinsen = schulden * zinssatz / 100

schulden = schulden + zinsen - jahresrate

jahreZaehler += 1

print('Die Ruckzahlung dauert ' + str(jahreZaehler) + ' Jahre.')

schulden = int(sys.argv[1])

zinssatz = float(sys.argv[2])

jahresrate = int(sys.argv[3])

jahreZaehler = 0

schulden > 0 ?

zinsen = schulden * zinssatz / 100

schulden = schulden + zinsen - jahresrate

jahreZaehler = jahreZaehler+1

print('Die Ruckzahlung dauert ' + str(jahreZaehler) + ' Jahre.')

ja

nein

while-Schleife 1.3.13

Page 127: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Blockstruktur von while-Schleifen#-----------------------------------------------------------------------

# rueckzahlungsdauer.py

#-----------------------------------------------------------------------

# Das Programm liest von der Kommandozeile die Werte

# schulden (int), zinssatz (float) und jahresrate (int).

# Es wird berechnet, wieviele Jahre die jahresrate bezahlt werden muss,

# bis die schulden beim angegebenen zinssatz beglichen sind.

#-----------------------------------------------------------------------

import sys

schulden = int(sys.argv[1])

zinssatz = float(sys.argv[2])

jahresrate = int(sys.argv[3])

jahreZaehler = 0 # Zahler fur die Jahre mit Ratenzahlungen

while schulden > 0 :

# Berechnung des Schuldenstandes nach einem weiteren Jahr.

zinsen = schulden * zinssatz / 100

schulden = schulden + zinsen - jahresrate

jahreZaehler += 1

print('Die Ruckzahlung dauert ' + str(jahreZaehler) + ' Jahre.')

#------------------------------------------------------------------------

# python rueckzahlungsdauer.py 200000 3.5 12000

# Die Ruckzahlung dauert 26 Jahre.

Zeile-1

Zeile-2...

while Bedingung b:

Zeile-b-1

Zeile-b-2...

Zeile-x...

Block

Block

while-Schleife 1.3.14

Page 128: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 129: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 130: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 131: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 132: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 133: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 134: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 135: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 136: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 137: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 138: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 139: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 140: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 141: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 142: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 143: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 144: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 145: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 146: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 147: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bestimmung aller Teiler einer Zahl

Bestimmung aller Teiler von 18:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18X X X ˆ ˆ X ˆ ˆ X ˆ ˆ ˆ ˆ ˆ ˆ ˆ ˆ X

Idee fur den Algorithmus:

zur Bestimmung aller Teiler einer ganzen Zahl n:

gehe alle Zahlen z von 1 bis n durch

falls z ein Teiler von n ist (d.h. n%z == 0), dann gib z aus

while-Schleife 1.3.15

Page 148: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# alleteiler1.py

#------------------------------------------------------------------------------------

# Das Programm liest int-Wert n von der Kommandozeile ein

# und gibt alle Teiler von n aus.

#------------------------------------------------------------------------------------

import sys

# Lies n von der Kommandozeile.

n = int( sys.argv[1] )

print('Die Teiler von ' + str(n) + ' sind:')

# zaehler soll alle Werte im Bereich 1...n durchlaufen.

zaehler = 1

while zaehler <= n:

# Falls zaehler ein Teiler von n ist, dann wird zaehler ausgegeben.

if n%zaehler == 0:

print(zaehler)

# Nimm den nachsten Wert fur zaehler.

zaehler = zaehler + 1

#------------------------------------------------------------------------------------

# python alleteiler1.py 8

# Die Teiler von 8 sind:

# 1

# 2

# 4

# 8while-Schleife 1.3.16

Page 149: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Schleifen – for

Haufig wird in einer Schleife u.a. eine Variable hochgezahlt

und die Schleifen-Wiederholung endet, wenn ein bestimmter Wert erreicht wurde.

Die for-Schleife erleichtert das Aufschreiben solcher Schleifen.

for-Schleife 1.3.17

Page 150: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# alleteiler2.py

#------------------------------------------------------------------------------------

# Das Programm liest int-Wert n von der Kommandozeile ein

# und gibt alle Teiler von n aus.

#------------------------------------------------------------------------------------

import sys

# Lies n (int) von der Kommandozeile.

n = int( sys.argv[1] )

# zaehler soll alle Werte im Bereich 1..n durchlaufen.

for zaehler in range(1, n+1):

# Falls zaehler ein Teiler von n ist, dann wird zaehler ausgegeben.

if n%zaehler == 0:

print(zaehler)

#------------------------------------------------------------------------------------

# python alleteiler2.py 8

# Die Teiler von 8 sind:

# 1

# 2

# 4

# 8

zaehler in range(1,9) durchlauft fur zaehler die Werte 1, 2, 3, 4, 5, 6, 7, 8.

zaehler in range(a,b) durchlauft fur zaehler die Werte a, a` 1, a` 2, . . . , b ´ 1.for-Schleife 1.3.18

Page 151: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Simulation von Zufallsexperimenten

Zwei Wurfel werden geworfen. Wie wahrscheinlich ist es, dass die Augensumme 7 ist?

Statt die Wahrscheinlichkeit exakt auszurechnen,simulieren wir ein Experiment mit einem Programm.

Das Experiment besteht aus dem Wurf von zwei Wurfeln.Das Experiment ist erfolgreich, wenn die Wurfelsumme 7 ist.Anderenfalls ist das Experiment nicht erfolgreich.

Dieses Experiment wiederholen wir z.B. 100000-malund zahlen, wie oft das Experiment erfolgreich ist.

Die experimentell bestimmte Wahrscheinlichkeit, die Wurfelsumme 7 zu wurfeln,ist dann der Quotient

Anzahl der erfolgreichen Experimente

Anzahl aller Experimente.

Je ofter das Experiment wiederholt wird,desto wahrscheinlicher ist es, die

”richtige“ Wahrscheinlichkeit herauszubekommen.

Bestimmung einer Wahrscheinlichkeit durch Simulation 1.3.19

Page 152: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie wurfelt Python?

Schreibweise fur Intervalle: ra, bq fur int-Werte istdas Intervall mit den Zahlen a, a` 1, a` 2, . . . , b ´ 1 (entspricht range(a,b)).

Z.B. ist r1, 7q das Intervall 1, 2, 3, 4, 5, 6.

ra, bq fur float-Werte istdas Intervall mit den Zahlen r mit a ď r ă b.

Z.B. ist r0, 1q das Intervall mit allen reellen Zahlen x mit 0 ď x ă 1,das sind alle Dezimalbruche 0, xyz . . . mit 0 vor dem Komma.

Standardfunktionen aus Pythons Modul random:

randrange(a,b) ein zufallig gewahlter int-Wert aus [a,b) fur int-Werte a und b

random() ein zufallig gewahlter float-Wert aus dem Intervall r0, 1q

Die Funktionswerte sind gleichverteilt.

Ein Wurf mit einem Wurfel entspricht einem Aufruf von random.randrange(1,7) in Python.

Bestimmung einer Wahrscheinlichkeit durch Simulation 1.3.20

Page 153: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufgabe:

bestimme die Wahrscheinlichkeit,

dass beim Wurf mit zwei Wurfeln Augensumme 7 geworfen wird,

mittels Simulation.

Idee fur den Algorithmus:

wiederhole n-mal:

Experiment: wurfele mit zwei Wurfeln

Auswertung: das Experiment war erfolgreich, falls Augensumme 7 gewurfelt wurde

gib”Anzahl erfolgreicher Experimente / n“ aus

Bestimmung einer Wahrscheinlichkeit durch Simulation 1.3.21

Page 154: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------

# siebenwuerfeln.py

#----------------------------------------------------------------------------------------------------------

import sys, random

# Die Experimentreihe wird vorbereitet. n ist die Anzahl der Wiederholungen des Experiments.

n = int( sys.argv[1] )

erfolgsZaehler = 0 # zahlt die erfolgreichen Experimente

# Die Experimentreihe wird durchgefuhrt.

for i in range(0,n): # es werden n Experimente durchgefuhrt

# Das Experiment: zwei Wurfel werden geworfen.

wuerfel1 = random.randrange(1,7)

wuerfel2 = random.randrange(1,7)

# Die Auswertung des Experiments: das Experiment ist erfolgreich, wenn die Wurfelsumme 7 ist.

if wuerfel1 + wuerfel2 == 7: erfolgsZaehler += 1

# Das Ergebnis der Experimentreihe wird ausgegeben.

erfolgsWkeit = erfolgsZaehler/n

print('Die Wahrscheinlichkeit fur ein erfolgreiches Experiment ist ' + str(float(erfolgsWkeit)) + '.' )

print('D.h. etwa einer von ' + str(round(1/erfolgsWkeit)) + ' Wurfen ist erfolgreich.' )

#-----------------------------------------------------------------------------------------------------------

# python siebenwuerfeln.py 100

# Die Wahrscheinlichkeit fur ein erfolgreiches Experiment ist 0.2.

# D.h. etwa einer von 5 Wurfen ist erfolgreich.

#

# python siebenwuerfeln.py 100

# Die Wahrscheinlichkeit fur ein erfolgreiches Experiment ist 0.15.

# D.h. etwa einer von 7 Wurfen ist erfolgreich. Bestimmung einer Wahrscheinlichkeit durch Simulation 1.3.22

Page 155: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------

# siebenwuerfeln.py

#----------------------------------------------------------------------------------------------------------

import sys, random

# Die Experimentreihe wird vorbereitet. n ist die Anzahl der Wiederholungen des Experiments.

n = int( sys.argv[1] )

erfolgsZaehler = 0 # zahlt die erfolgreichen Experimente

# Die Experimentreihe wird durchgefuhrt.

for i in range(0,n): # es werden n Experimente durchgefuhrt

# Das Experiment: zwei Wurfel werden geworfen.

wuerfel1 = random.randrange(1,7)

wuerfel2 = random.randrange(1,7)

# Die Auswertung des Experiments: das Experiment ist erfolgreich, wenn die Wurfelsumme 7 ist.

if wuerfel1 + wuerfel2 == 7: erfolgsZaehler += 1

# Das Ergebnis der Experimentreihe wird ausgegeben.

erfolgsWkeit = erfolgsZaehler/n

print('Die Wahrscheinlichkeit fur ein erfolgreiches Experiment ist ' + str(float(erfolgsWkeit)) + '.' )

print('D.h. etwa einer von ' + str(round(1/erfolgsWkeit)) + ' Wurfen ist erfolgreich.' )

#-----------------------------------------------------------------------------------------------------------

# python siebenwuerfeln.py 1000000

# Die Wahrscheinlichkeit fur ein erfolgreiches Experiment ist 0.166619.

# D.h. etwa einer von 6 Wurfen ist erfolgreich.

#

# python siebenwuerfeln.py 1000000

# Die Wahrscheinlichkeit fur ein erfolgreiches Experiment ist 0.166767.

# D.h. etwa einer von 6 Wurfen ist erfolgreich. Bestimmung einer Wahrscheinlichkeit durch Simulation 1.3.22

Page 156: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4 Zum Abschluss: Jetzt konnen wir schon mehr als Euler . . .

Euler hat 1769 vermutet,

dass es z.B. keine ganzen Zahlen a, b, c , d , e ě 1 gibt, so dass

a5 ` b5 ` c5 ` d5 “ e5 .

Die Vermutung wurde 1966 von L.J.Lander und T.R.Parkin widerlegt:

fur a “ 133, b “ 110, c “ 84, d “ 27 und e “ 144 gilt

a5 ` b5 ` c5 ` d5 “ e5 (1335 ` 1105 ` 845 ` 275 “ 1445).

Beantwortung einer Frage von Euler 1.3.23

Page 157: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4 Zum Abschluss: Jetzt konnen wir schon mehr als Euler . . .

Euler hat 1769 vermutet,

dass es z.B. keine ganzen Zahlen a, b, c , d , e ě 1 gibt, so dass

a5 ` b5 ` c5 ` d5 “ e5 .

Die Vermutung wurde 1966 von L.J.Lander und T.R.Parkin widerlegt:

fur a “ 133, b “ 110, c “ 84, d “ 27 und e “ 144 gilt

a5 ` b5 ` c5 ` d5 “ e5 (1335 ` 1105 ` 845 ` 275 “ 1445).

Die Zahlen wurden mit einem Programm gefunden, das auf einer CDC 6600 lief.Sie war 1964–1969 der schnellste Rechner der Welt.

CDC 6600: 3 megaFLOPS, d.h. 3 ¨ 106 floating point operations per secondheutiger PC: 100 gigaFLOPS, d.h. 100 ¨ 109

Summit (IBM): 122 petaFLOPS, d.h. 122 ¨ 1015

Beantwortung einer Frage von Euler 1.3.23

Page 158: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4 Zum Abschluss: Jetzt konnen wir schon mehr als Euler . . .

Euler hat 1769 vermutet,

dass es z.B. keine ganzen Zahlen a, b, c , d , e ě 1 gibt, so dass

a5 ` b5 ` c5 ` d5 “ e5 .

Die Vermutung wurde 1966 von L.J.Lander und T.R.Parkin widerlegt:

fur a “ 133, b “ 110, c “ 84, d “ 27 und e “ 144 gilt

a5 ` b5 ` c5 ` d5 “ e5 (1335 ` 1105 ` 845 ` 275 “ 1445).

Wir konnen ein Programm schreiben,

das systematisch durch die moglichen Werte von a, b, c , d , e geht

und uberpruft, ob sie die gewunschte Eigenschaft haben.

Da wir bereits wissen, dass es Werte a, b, c , d , e mit a5 ` b5 ` c5 ` d5 “ e5 gibt,

mussen wir nur warten, bis das Programm sie gefunden hat.

Wenn wir das nicht wussten, konnte das Programm endlos laufen . . .

Beantwortung einer Frage von Euler 1.3.23

Page 159: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gibt es ganze Zahlen a, b, c , d , e ě 1 mit a5 ` b5 ` c5 ` d5 “ e5 ?

Nur”brutal“ alle moglichen Werte von a, b, c , d , e durchzugehen,

dauert selbst auf einem schnellen Rechner sehr lange.

Mein”brutales“ Programm durchlauft etwa 65 Milliarden Kombinationen a, b, c , d , e,

bis es die Losung gefunden hat.

Das dauert langer als 28 Stunden (auf meinem Rechner im Buro).

Ein Problem dabei ist es, dass viele Kombinationen vielfach durchlaufen werden.

Um das zu vermeiden, hatte ich (mit unseren bisherigen Programmierkenntnissen)

ein Programm von etwa 300 Programmzeilen schreiben mussen.

Das hatte die Rechendauer halbiert . . .

Beantwortung einer Frage von Euler 1.3.24

Page 160: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gibt es ganze Zahlen a, b, c , d , e ě 1 mit a5 ` b5 ` c5 ` d5 “ e5 ?

Nur”brutal“ alle moglichen Werte von a, b, c , d , e durchzugehen,

dauert selbst auf einem schnellen Rechner sehr lange.

Mein”brutales“ Programm durchlauft etwa 65 Milliarden Kombinationen a, b, c , d , e,

bis es die Losung gefunden hat.

Das dauert langer als 28 Stunden (auf meinem Rechner im Buro).

Ein Problem dabei ist es, dass viele Kombinationen vielfach durchlaufen werden.

Um das zu vermeiden, hatte ich (mit unseren bisherigen Programmierkenntnissen)

ein Programm von etwa 300 Programmzeilen schreiben mussen.

Das hatte die Rechendauer halbiert . . .

Beantwortung einer Frage von Euler 1.3.24

Page 161: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gibt es ganze Zahlen a, b, c , d , e ě 1 mit a5 ` b5 ` c5 ` d5 “ e5 ?

Also mussen wir die Frage analysieren und versuchen, sie so umzuformulieren,

dass man sie”schneller“ losen kann.

Euler fragt ja, ob es ganze Zahlen a, b, c , d ě 1 gibt,

so dass die Summe a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Um das festzustellen, reicht es, alle moglichen Kombinationen von a, b, c , d zu durchsuchen

und jeweils zu uberprufen, a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Bei meinem Brutalo-Programm sind das nur noch 26 Milliarden Kombinationen.

Kann man diese Zahl noch verringern?

Insgesamt mussen wir zwei Teilaufgaben losen.

(F1) Wenn wir eine ganze Zahl x haben,

wie konnen wir feststellen, ob x die 5te Potenz einer ganzen Zahl ist?

(F2) Wie konnen wir systematisch alle notigen Werte fur a, b, c , d durchsuchen?Beantwortung einer Frage von Euler 1.3.25

Page 162: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gibt es ganze Zahlen a, b, c , d , e ě 1 mit a5 ` b5 ` c5 ` d5 “ e5 ?

Also mussen wir die Frage analysieren und versuchen, sie so umzuformulieren,

dass man sie”schneller“ losen kann.

Euler fragt ja, ob es ganze Zahlen a, b, c , d ě 1 gibt,

so dass die Summe a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Um das festzustellen, reicht es, alle moglichen Kombinationen von a, b, c , d zu durchsuchen

und jeweils zu uberprufen, a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Bei meinem Brutalo-Programm sind das nur noch 26 Milliarden Kombinationen.

Kann man diese Zahl noch verringern?

Insgesamt mussen wir zwei Teilaufgaben losen.

(F1) Wenn wir eine ganze Zahl x haben,

wie konnen wir feststellen, ob x die 5te Potenz einer ganzen Zahl ist?

(F2) Wie konnen wir systematisch alle notigen Werte fur a, b, c , d durchsuchen?Beantwortung einer Frage von Euler 1.3.25

Page 163: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gibt es ganze Zahlen a, b, c , d , e ě 1 mit a5 ` b5 ` c5 ` d5 “ e5 ?

Also mussen wir die Frage analysieren und versuchen, sie so umzuformulieren,

dass man sie”schneller“ losen kann.

Euler fragt ja, ob es ganze Zahlen a, b, c , d ě 1 gibt,

so dass die Summe a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Um das festzustellen, reicht es, alle moglichen Kombinationen von a, b, c , d zu durchsuchen

und jeweils zu uberprufen, a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Bei meinem Brutalo-Programm sind das nur noch 26 Milliarden Kombinationen.

Kann man diese Zahl noch verringern?

Insgesamt mussen wir zwei Teilaufgaben losen.

(F1) Wenn wir eine ganze Zahl x haben,

wie konnen wir feststellen, ob x die 5te Potenz einer ganzen Zahl ist?

(F2) Wie konnen wir systematisch alle notigen Werte fur a, b, c , d durchsuchen?Beantwortung einer Frage von Euler 1.3.25

Page 164: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gibt es ganze Zahlen a, b, c , d , e ě 1 mit a5 ` b5 ` c5 ` d5 “ e5 ?

Also mussen wir die Frage analysieren und versuchen, sie so umzuformulieren,

dass man sie”schneller“ losen kann.

Euler fragt ja, ob es ganze Zahlen a, b, c , d ě 1 gibt,

so dass die Summe a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Um das festzustellen, reicht es, alle moglichen Kombinationen von a, b, c , d zu durchsuchen

und jeweils zu uberprufen, a5 ` b5 ` c5 ` d5 die 5te Potenz einer ganzen Zahl ist.

Bei meinem Brutalo-Programm sind das nur noch 26 Milliarden Kombinationen.

Kann man diese Zahl noch verringern?

Insgesamt mussen wir zwei Teilaufgaben losen.

(F1) Wenn wir eine ganze Zahl x haben,

wie konnen wir feststellen, ob x die 5te Potenz einer ganzen Zahl ist?

(F2) Wie konnen wir systematisch alle notigen Werte fur a, b, c , d durchsuchen?Beantwortung einer Frage von Euler 1.3.25

Page 165: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F1) Ist x die 5te Potenz einer ganzen Zahl?

Um das festzustellen, berechnen wir die 5te Wurzel von x :wurzel = x**0.2

Da im Ausdruck x**0.2 ein float-Wert vorkommt,ist das Ergebnis ebenfalls vom Typ float.

float-Werte enthalten oft Rundungsfehler (Berechnungsungenauigkeiten).

Obwohl p 5?

2q5 mathematisch das Ergebnis 2 hat,macht print((2**0.2)**5) Ausgabe 2.000000000000001 !

Deshalb liefert der Ausdruck (2**0.2)**5 == 2 (also 5?

25“ 2?)

den Wert False.

Wie umgehen wir diesen Fehler?

Beantwortung einer Frage von Euler 1.3.26

Page 166: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F1) Ist x die 5te Potenz einer ganzen Zahl?

Zuerst berechnen wir die funfte Wurzel von x (mit moglichem Rundungsfehler):fWurzel = x**0.2

fWurzel hat den Typ float.Da wir nur an ganzzahligen funften Wurzeln interessiert sind,runden wir fWurzel zur nachsten ganzen Zahl.

fuenfteWurzel = round(fWurzel)

fuenfteWurzel hat den Typ int (das ist nur in Python3 so),und fuenfteWurzel**5 ist die korrekte 5te Potenz von fuenfteWurzel.

Wenn nun x == fuenfteWurzel**5 den Wert True hat,dann haben wir festgestellt, dass x die 5te Potenz einer ganzen Zahl ist.

Wenn aber x == fuenfteWurzel**5 den Wert False hat,dann ist x nicht die 5te Potenz einer ganzen Zahl

oder beim Wurzelziehen ist ein Rundungsfehler aufgetreten, der das Ergebnis verfalscht.(Hier gehen wir davon aus, dass der Rundungsfehler nicht zu groß ist . . . In diesem Beispiel geht das gut . . . )

Beantwortung einer Frage von Euler 1.3.27

Page 167: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F1) Ist x die 5te Potenz einer ganzen Zahl?

Zuerst berechnen wir die funfte Wurzel von x (mit moglichem Rundungsfehler):fWurzel = x**0.2

fWurzel hat den Typ float.Da wir nur an ganzzahligen funften Wurzeln interessiert sind,runden wir fWurzel zur nachsten ganzen Zahl.

fuenfteWurzel = round(fWurzel)

fuenfteWurzel hat den Typ int (das ist nur in Python3 so),und fuenfteWurzel**5 ist die korrekte 5te Potenz von fuenfteWurzel.

Wenn nun x == fuenfteWurzel**5 den Wert True hat,dann haben wir festgestellt, dass x die 5te Potenz einer ganzen Zahl ist.

Wenn aber x == fuenfteWurzel**5 den Wert False hat,dann ist x nicht die 5te Potenz einer ganzen Zahl

oder beim Wurzelziehen ist ein Rundungsfehler aufgetreten, der das Ergebnis verfalscht.(Hier gehen wir davon aus, dass der Rundungsfehler nicht zu groß ist . . . In diesem Beispiel geht das gut . . . )

Beantwortung einer Frage von Euler 1.3.27

Page 168: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F1) Ist x die 5te Potenz einer ganzen Zahl?

Zuerst berechnen wir die funfte Wurzel von x (mit moglichem Rundungsfehler):fWurzel = x**0.2

fWurzel hat den Typ float.Da wir nur an ganzzahligen funften Wurzeln interessiert sind,runden wir fWurzel zur nachsten ganzen Zahl.

fuenfteWurzel = round(fWurzel)

fuenfteWurzel hat den Typ int (das ist nur in Python3 so),und fuenfteWurzel**5 ist die korrekte 5te Potenz von fuenfteWurzel.

Wenn nun x == fuenfteWurzel**5 den Wert True hat,dann haben wir festgestellt, dass x die 5te Potenz einer ganzen Zahl ist.

Wenn aber x == fuenfteWurzel**5 den Wert False hat,dann ist x nicht die 5te Potenz einer ganzen Zahl

oder beim Wurzelziehen ist ein Rundungsfehler aufgetreten, der das Ergebnis verfalscht.(Hier gehen wir davon aus, dass der Rundungsfehler nicht zu groß ist . . . In diesem Beispiel geht das gut . . . )

Beantwortung einer Frage von Euler 1.3.27

Page 169: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F1) Ist x die 5te Potenz einer ganzen Zahl?

Zuerst berechnen wir die funfte Wurzel von x (mit moglichem Rundungsfehler):fWurzel = x**0.2

fWurzel hat den Typ float.Da wir nur an ganzzahligen funften Wurzeln interessiert sind,runden wir fWurzel zur nachsten ganzen Zahl.

fuenfteWurzel = round(fWurzel)

fuenfteWurzel hat den Typ int (das ist nur in Python3 so),und fuenfteWurzel**5 ist die korrekte 5te Potenz von fuenfteWurzel.

Wenn nun x == fuenfteWurzel**5 den Wert True hat,dann haben wir festgestellt, dass x die 5te Potenz einer ganzen Zahl ist.

Wenn aber x == fuenfteWurzel**5 den Wert False hat,dann ist x nicht die 5te Potenz einer ganzen Zahl

oder beim Wurzelziehen ist ein Rundungsfehler aufgetreten, der das Ergebnis verfalscht.(Hier gehen wir davon aus, dass der Rundungsfehler nicht zu groß ist . . . In diesem Beispiel geht das gut . . . )

Beantwortung einer Frage von Euler 1.3.27

Page 170: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F1) Ist x die 5te Potenz einer ganzen Zahl?

Zuerst berechnen wir die funfte Wurzel von x (mit moglichem Rundungsfehler):fWurzel = x**0.2

fWurzel hat den Typ float.Da wir nur an ganzzahligen funften Wurzeln interessiert sind,runden wir fWurzel zur nachsten ganzen Zahl.

fuenfteWurzel = round(fWurzel)

fuenfteWurzel hat den Typ int (das ist nur in Python3 so),und fuenfteWurzel**5 ist die korrekte 5te Potenz von fuenfteWurzel.

Wenn nun x == fuenfteWurzel**5 den Wert True hat,dann haben wir festgestellt, dass x die 5te Potenz einer ganzen Zahl ist.

Wenn aber x == fuenfteWurzel**5 den Wert False hat,dann ist x nicht die 5te Potenz einer ganzen Zahl

oder beim Wurzelziehen ist ein Rundungsfehler aufgetreten, der das Ergebnis verfalscht.(Hier gehen wir davon aus, dass der Rundungsfehler nicht zu groß ist . . . In diesem Beispiel geht das gut . . . )

Beantwortung einer Frage von Euler 1.3.27

Page 171: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F2) Wie konnen wir alle notigen Werte fur a, b, c , d (schnell?) durchsuchen?

Die brutale Idee ist es, alle moglichen Werte fur a, b, c, d zu durchsuchen.

Das ist hier aber nicht notig.

Z.B. ist 25 ` 85 ` 65 ` 45 “ 85 ` 65 ` 45 ` 25.

Es reicht also, die Werte fur a, b, c , d zu durchsuchen,

bei denen a ě b ě c ě d ist.

Dazu zahlen wir a “ 1, 2, 3, . . . hoch

und gehen systematisch alle passenden Moglichkeiten fur b, c , d durch,

also b, c , d “ 1, 2, . . . , a und b ě c ě d .

a = 0

while True:

a = a+1

for b in range(1,a+1):

for c in range(1,b+1):

for d in range(1,c+1):

# teste die Euler-Bedingung fur a,b,c,d

Beantwortung einer Frage von Euler 1.3.28

Page 172: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(F2) Wie konnen wir alle notigen Werte fur a, b, c , d (schnell?) durchsuchen?

Die brutale Idee ist es, alle moglichen Werte fur a, b, c, d zu durchsuchen.

Das ist hier aber nicht notig.

Z.B. ist 25 ` 85 ` 65 ` 45 “ 85 ` 65 ` 45 ` 25.

Es reicht also, die Werte fur a, b, c , d zu durchsuchen,

bei denen a ě b ě c ě d ist.

Dazu zahlen wir a “ 1, 2, 3, . . . hoch

und gehen systematisch alle passenden Moglichkeiten fur b, c , d durch,

also b, c , d “ 1, 2, . . . , a und b ě c ě d .

a = 0

while True:

a = a+1

for b in range(1,a+1):

for c in range(1,b+1):

for d in range(1,c+1):

# teste die Euler-Bedingung fur a,b,c,d

Beantwortung einer Frage von Euler 1.3.28

Page 173: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gib alle 2-Tupel pa, bq aus mit a ě b ě 1

#--------------------------------------------------------

# alle2Tupel.py

#--------------------------------------------------------

# Gib alle 2-Tupel (a,b) aus mit a>=b>=1.

#--------------------------------------------------------

a = 0

while True:

a = a+1

for b in range(1,a+1):

print(a,b)

#--------------------------------------------------------

# python3 alle2Tupel.py

# 1 1

# 2 1

# 2 2

# 3 1

# 3 2

# 3 3

# 4 1

# 4 2

# 4 3

# 4 4

# 5 1

# 5 2

# 5 3

# 5 4

# 5 5

# 6 1

# 6 2

# ...

Beantwortung einer Frage von Euler 1.3.29

Page 174: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gib alle 3-Tupel pa, b, cq aus mit a ě b ě c ě 1

#------------------------------------------------------

# alle3Tupel.py

#------------------------------------------------------

# Gib alle 3-Tupel (a,b,c) aus mit a>=b>=c>=1.

#------------------------------------------------------

a = 0

while True:

a = a+1

for b in range(1,a+1):

for c in range(1,b+1):

print(a,b,c)

#------------------------------------------------------

# python3 alle3Tupel.py

# 1 1 1

# 2 1 1

# 2 2 1

# 2 2 2

# 3 1 1

# 3 2 1

# 3 2 2

# 3 3 1

# 3 3 2

# 3 3 3

# 4 1 1

# 4 2 1

# 4 2 2

# 4 3 1

# 4 3 2

# 4 3 3

# 4 4 1

# ...

Beantwortung einer Frage von Euler 1.3.30

Page 175: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gib alle 4-Tupel pa, b, c , dq aus mit a ě b ě c ě d ě 1

#----------------------------------------------------------

# alle4Tupel.py

#----------------------------------------------------------

# Gib alle 4-Tupel (a,b,c,d) aus mit a>=b>=c>=d>=1.

#----------------------------------------------------------

a = 0

while True:

a = a+1

for b in range(1,a+1):

for c in range(1,b+1):

for d in range(1,c+1):

print(a,b,c,d)

#---------------------------------------------------------

# python3 alle4Tupel.py

# 1 1 1 1

# 2 1 1 1

# 2 2 1 1

# 2 2 2 1

# 2 2 2 2

# 3 1 1 1

# 3 2 1 1

# 3 2 2 1

# 3 2 2 2

# 3 3 1 1

# 3 3 2 1

# 3 3 2 2

# 3 3 3 1

# 3 3 3 2

# 3 3 3 3

# 4 1 1 1

# 4 2 1 1

# ...

Nun konnen wir beide Teile zu einem Programm zusammenbauen,

das die Vermutung von Euler widerlegt. Beantwortung einer Frage von Euler 1.3.31

Page 176: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#------------------------------------------------------------------------------------------------

# euler-vermutung.py

#------------------------------------------------------------------------------------------------

zaehler = 0 # wir zahlen, wieviele Zahlenkombinationen durchprobiert werden

erfolg = False # wird auf True gesetzt, wenn die gesuchte Kombination gefunden wurde

a = 0

while not erfolg: # teste alle Tupel a,b,c,d mit a>=b>=c>=d>=1, bis ein Test erfolgreich war

a += 1

print(a) # damit wir sehen, wie weit das Programm gekommen ist

for b in range(1,a+1):

for c in range(1,b+1):

for d in range(1,c+1):

zaehler += 1

summe = a**5 + b**5 + c**5 + d**5

fuenfteWurzel = round(summe**0.2)

if summe == fuenfteWurzel**5:

print('Versuch ' + str(zaehler) + ' war erfolgreich: ')

print(str(a) + '**5 + ' + str(b) + '**5 + ' + str(c) + '**5 + '

+ str(d) + '**5 == ' + str(fuenfteWurzel) + '**5')

print('Die Summe ist ' + str(summe) + '.')

erfolg = True

#------------------------------------------------------------------------------------------------

Beantwortung einer Frage von Euler 1.3.32

Page 177: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# python3 euler-vermutung.py

# 1

# 2

# 3

# 4

# ...

# 130

# 131

# 132

# 133

# Versuch 13458163 war erfolgreich:

# 133**5 + 110**5 + 84**5 + 27**5 == 144**5

# Die Summe ist 61917364224.

Beantwortung einer Frage von Euler 1.3.33

Page 178: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

§ Wir haben if-Anweisungen, while-Schleifen und for-Schleifen kennengelernt.

§ Wir kennen die Strukturierung von Programmen in Blocke.

§ Wir konnen einfache Programme mit

Eingabe von Argumenten (von der Konsole)

Abarbeitung von Anweisungs-Blocken,

die in Schleifen wiederholt oder

durch if-Anweisungen ausgefuhrt oder ubersprungen werden

Ausgabe von Ergebnissen (auf der Konsole)

schreiben und deren Ausfuhrung nachvollziehen.

1.3.34

Page 179: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 180: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 181: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 182: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 183: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 184: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 185: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 186: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 187: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 188: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 189: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 190: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 191: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 192: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 193: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus

Um den ganzzahligen Logarithmus einer Zahl zur Basis 2 zu berechnen,

teilt man die Zahl immer wieder ganzzahlig durch 2,

bis die Zahl 1 erreicht wird.

Der ganzzahlige Logarithmus der Zahl zur Basis 2 ist dann die Anzahl,

wie oft man durch 2 teilen konnte.

Beispiele:

Berechnung des ganzzahligen Logarithmus von 18 zur Basis 2:

18 9 4 2 1 : das Ergebnis ist 4 (24 ď 18 ă 25)

35 17 8 4 2 1 : das Ergebnis ist 5 (25 ď 35 ă 26)

Idee fur den Algorithmus:

teile die Zahl solange durch 2, wie sie ą 1 ist

und erhohe bei jedem Teilen einen Zahler um 1.

1.3.35

Page 194: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus zur Basis 2

zahl = int( sys.argv[1] )

zaehler = 0

zahl > 1 ?

zaehler = zaehler + 1

zahl = zahl // 2

print('Der Logarithmus von ' + str(zahl) + ' zur Basis 2 ist ' + str(zaehler) + '.')

ja

nein

1.3.36

Page 195: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus zur Basis 2

zahl = int( sys.argv[1] )

zaehler = 0

zahl > 1 ?

zaehler = zaehler + 1

zahl = zahl // 2

print('Der Logarithmus von ' + str(zahl) + ' zur Basis 2 ist ' + str(zaehler) + '.')

ja

neinSchleifenbedingung

1.3.36

Page 196: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Berechnung des ganzzahligen Logarithmus zur Basis 2

zahl = int( sys.argv[1] )

zaehler = 0

zahl > 1 ?

zaehler = zaehler + 1

zahl = zahl // 2

print('Der Logarithmus von ' + str(zahl) + ' zur Basis 2 ist ' + str(zaehler) + '.')

ja

neinSchleifenbedingung

Schleifenrumpf (Block)

1.3.36

Page 197: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------------

# ganzlog.py

#--------------------------------------------------------------------------------------

# Das Programm liest int-Wert n von der Kommandozeile ein

# und gibt den ganzzahligen Logarithmus von n zur Basis 2 aus.

import sys

zahl = int( sys.argv[1] )

zaehler = 0 # zaehler zahlt, wie oft durch 2 geteilt werden kann.

while zahl > 1:

print('zahl ist ' + str(zahl) + ', zaehler ist ' + str(zaehler))

zaehler = zaehler + 1

zahl = zahl//2

print('Der ganzzahlige Logarithmus von ' + str(zahl) + ' zur Basis 2 ist ' +

str(zaehler) + '.')

#------------------------------------------------------------------------------------

# python ganzlog.py 538

# zahl ist 538, zaehler ist 0

# zahl ist 269, zaehler ist 1

# zahl ist 134, zaehler ist 2

# zahl ist 67, zaehler ist 3

# zahl ist 33, zaehler ist 4

# zahl ist 16, zaehler ist 5

# zahl ist 8, zaehler ist 6

# zahl ist 4, zaehler ist 7

# zahl ist 2, zaehler ist 8

# Der ganzzahlige Logarithmus von 538 zur Basis 2 ist 9.

1.3.37

Page 198: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Jetzt wissen wir ungefahr die Wahrscheinlichkeit, mit zwei Wurfeln die Wurfelsumme 7 zu wurfeln.

Wie sind die Wahrscheinlichkeiten fur andere Wurfelsummen 2, 3, . . . , 12?

Wir erweitern das Programm so,

dass nacheinander alle Wurfelsummen durchprobiert werden.

Idee fur den Algorithmus:

fur alle Wurfelsummen 2, 3, . . . , 12:bestimme die Wkeit,mit zwei Wurfeln diese Wurfelsumme zu wurfeln und gib sie aus(das konnen wir wie in siebenwuerfeln.py machen)

1.3.38

Page 199: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#------------------------------------------------------------------------------------

# wuerfelsummen.py

#------------------------------------------------------------------------------------

# Ermittle die Wahrscheinlichkeit, dass mit zwei Wurfeln

# eine bestimmte Zahl gewurfelt wird, mittels Simulation.

# Die Anzahl der Experimente, die bei jeder Simulation durchgefuhrt werden,

# wird von der Kommandozeile eingelesen.

import sys, random

versuchszahl = int( sys.argv[1] ) # die Anzahl der Wiederholungen jedes Experiments

# Fur jede Wurfelsumme von 2 bis 12 wird das Experiment durchgefuhrt

for wuerfelsumme in range(2,13):

erfolgsZaehler = 0 # Zahler fur die erfolgreichen Experimente

# Das Experiment fur summe wird versuchszahl mal wiederholt.

for i in range(0,versuchszahl):

# Zwei Wurfel werden geworfen.

# Der Wurf ist erfolgreich, wenn summe die Wurfelsumme ist.

if random.randrange(1,7) + random.randrange(1,7) == summe:

erfolgsZaehler += 1

# Ausgabe der Erfolgswahrscheinlichkeit (mit gut lesbarer Darstellung).

print('Summe ' + ' '*(summe<10) + str(summe) + ': Wkeit. 1/'

+ str(int(round(1/(float(erfolgsZahler)/versuchszahl)))))

1.3.39

Page 200: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# python wuerfelsummen.py 100

# Summe 2: Wkeit. 1/33

# Summe 3: Wkeit. 1/50

# Summe 4: Wkeit. 1/11

# Summe 5: Wkeit. 1/10

# Summe 6: Wkeit. 1/6

# Summe 7: Wkeit. 1/10

# Summe 8: Wkeit. 1/10

# Summe 9: Wkeit. 1/8

# Summe 10: Wkeit. 1/11

# Summe 11: Wkeit. 1/13

# Summe 12: Wkeit. 1/50

# python wuerfelsummen.py 100000

# Summe 2: Wkeit. 1/36

# Summe 3: Wkeit. 1/18

# Summe 4: Wkeit. 1/12

# Summe 5: Wkeit. 1/9

# Summe 6: Wkeit. 1/7

# Summe 7: Wkeit. 1/6

# Summe 8: Wkeit. 1/7

# Summe 9: Wkeit. 1/9

# Summe 10: Wkeit. 1/12

# Summe 11: Wkeit. 1/18

# Summe 12: Wkeit. 1/36

1.3.40

Page 201: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

17 und 4

Wir spielen 17+4 mit Wurfeln.

Zwei Spieler spielen.

Jeder wurfelt, ohne dass es der andere sehen kann.

Ziel des Spiels ist es, den Wert 21 zu erreichen.

Dazu wurfelt der Spieler mit seinem Wurfel und summiert die gewurfelten Zahlen.

Man kann jederzeit aufhoren zu wurfeln.

Das Ergebnis des Spielers ist seine Summe der gewurfelten Zahlen.

Ein Spieler mit einem Ergebnis ą 21 hat verloren.

Haben beide Spieler ein Ergebnis ď 21,

dann gewinnt der Spieler mit dem hoheren Ergebnis.

Wir wollen ein Programm entwickeln, mit dem man eine gute Strategie fur das Spiel finden kann.

1.3.41

Page 202: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 03

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und Schleifen

1.4 ArraysEindimensionale Arrays

Allgemeines uber Objekte in Python

Zweidimensionale Arrays

1.5 Ein- und Ausgabe

1.6 Dictionaries und Abschluss-Beispiel Page Rank

1.4.1

Page 203: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1.4 Arrays

Bisher haben wir Variablen benutzt,

um ein einfaches”Datum“ zu speichern und darauf zuzugreifen –

eine Zahl, einen Text oder einen Wahrheitswert.

Was macht man, wenn man”sehr viele“ Daten speichern muss,

um daraus ein Ergebnis zu berechnen?

Das geht mit einer entsprechenden Datenstruktur.

Sie dient der Organisation von Daten zur Verarbeitung mit einem Computer-Programm.

Eine einfache Datenstruktur ist das Array (in Python list genannt),

mit dem man z.B. beliebig lange Folgen von Zahlen/Strings/Arrays etc. verarbeiten kann.

1.4.2

Page 204: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung der mittleren absoluten Abweichung vom Mittelwert

Bsp.: die Zahlen 17, 23, 16, 22, 7 haben Mittelwert 17`23`16`22`75 “ 17.

Die absoluten Abweichungen vom Mittelwert der Zahlen sind

Zahl: 17 23 16 22 7

absolute Abweichung von 17: 0 6 1 5 10

Also ist 0`6`1`5`105 “ 22

5 die mittlere absolute Abweichung der Zahlen von ihrem Mittelwert.

Idee fur den Algorithmus:

lies Zahlen von der Kommandozeile/Konsole und speichere sie (aber wie?)

berechne den Mittelwert der Zahlen

summiere die absoluten Abweichungen vom Mittelwert der Zahlen auf

das Ergebnis ist der Quotient aus dieser Summe und der Anzahl der Zahlen

Um die beliebig vielen Zahlen zu speichern, kann man ein Array benutzen . . .1.4.3

Page 205: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung der mittleren absoluten Abweichung vom Mittelwert

Bsp.: die Zahlen 17, 23, 16, 22, 7 haben Mittelwert 17`23`16`22`75 “ 17.

Die absoluten Abweichungen vom Mittelwert der Zahlen sind

Zahl: 17 23 16 22 7

absolute Abweichung von 17: 0 6 1 5 10

Also ist 0`6`1`5`105 “ 22

5 die mittlere absolute Abweichung der Zahlen von ihrem Mittelwert.

Idee fur den Algorithmus:

lies Zahlen von der Kommandozeile/Konsole und speichere sie (aber wie?)

berechne den Mittelwert der Zahlen

summiere die absoluten Abweichungen vom Mittelwert der Zahlen auf

das Ergebnis ist der Quotient aus dieser Summe und der Anzahl der Zahlen

Um die beliebig vielen Zahlen zu speichern, kann man ein Array benutzen . . .1.4.3

Page 206: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung der mittleren absoluten Abweichung vom Mittelwert

Bsp.: die Zahlen 17, 23, 16, 22, 7 haben Mittelwert 17`23`16`22`75 “ 17.

Die absoluten Abweichungen vom Mittelwert der Zahlen sind

Zahl: 17 23 16 22 7

absolute Abweichung von 17: 0 6 1 5 10

Also ist 0`6`1`5`105 “ 22

5 die mittlere absolute Abweichung der Zahlen von ihrem Mittelwert.

Idee fur den Algorithmus:

lies Zahlen von der Kommandozeile/Konsole und speichere sie (aber wie?)

berechne den Mittelwert der Zahlen

summiere die absoluten Abweichungen vom Mittelwert der Zahlen auf

das Ergebnis ist der Quotient aus dieser Summe und der Anzahl der Zahlen

Um die beliebig vielen Zahlen zu speichern, kann man ein Array benutzen . . .1.4.3

Page 207: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Datentyp list (Array) – Folge von Objekten

Die einfachste Vorstellung von einem Array ist eine Zuordnung von Indizes zu Werten.

Literal Vorstellung

['Gallia', 'est', 'div', 'omnis'] Index 0 1 2 3

Wert 'Gallia' 'est' 'div' 'omnis'

Die Programmzeilen

a = ['Gallia', 'est','div', 'omnis']

print(a)

print(a[3])

a[3] = a[2] + 'isa'

print(a[3])

a[2] = 'omnis'

print(a)

print(len(a))

erzeugen die Ausgabe

['Gallia', 'est', 'div', 'omnis']

omnis

divisa

['Gallia', 'est', 'omnis', 'divisa']

4

Die Lange von Array a[] ist 4. Sie ist der Funktionswert von len(a).Arrays 1.4.4

Page 208: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Datentyp list (Array) – Folge von Objekten

Die einfachste Vorstellung von einem Array ist eine Zuordnung von Indizes zu Werten.

Literal Vorstellung

['Gallia', 'est', 'div', 'omnis'] Index 0 1 2 3

Wert 'Gallia' 'est' 'div' 'omnis'

Die Programmzeilen

a = ['Gallia', 'est','div', 'omnis']

print(a)

print(a[3])

a[3] = a[2] + 'isa'

print(a[3])

a[2] = 'omnis'

print(a)

print(len(a))

erzeugen die Ausgabe

['Gallia', 'est', 'div', 'omnis']

omnis

divisa

['Gallia', 'est', 'omnis', 'divisa']

4

Die Lange von Array a[] ist 4. Sie ist der Funktionswert von len(a).Arrays 1.4.4

Page 209: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

summe = summe + zahlen[0]

summe = summe + zahlen[1]

summe = summe + zahlen[2]

summe = summe + zahlen[3]

summe = summe + zahlen[4]

print(summe/5)Arrays durchlaufen 1.4.5

Page 210: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

summe = summe + zahlen[0]

summe = summe + zahlen[1]

summe = summe + zahlen[2]

summe = summe + zahlen[3]

summe = summe + zahlen[4]

print(summe/5)Arrays durchlaufen 1.4.5

Page 211: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

summe = summe + zahlen[0]

summe = summe + zahlen[1]

summe = summe + zahlen[2]

summe = summe + zahlen[3]

summe = summe + zahlen[4]

print(summe/5)

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for i in range(0,5):

summe = summe + zahlen[i]

print(summe/5)Arrays durchlaufen 1.4.5

Page 212: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

summe = summe + zahlen[0]

summe = summe + zahlen[1]

summe = summe + zahlen[2]

summe = summe + zahlen[3]

summe = summe + zahlen[4]

print(summe/5)

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for i in range(5):

summe = summe + zahlen[i]

print(summe/5)Arrays durchlaufen 1.4.5

Page 213: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

summe = summe + zahlen[0]

summe = summe + zahlen[1]

summe = summe + zahlen[2]

summe = summe + zahlen[3]

summe = summe + zahlen[4]

print(summe/5)

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for i in range(len(zahlen)):

summe = summe + zahlen[i]

print(summe/len(zahlen))Arrays durchlaufen 1.4.5

Page 214: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

summe = summe + zahlen[0]

summe = summe + zahlen[1]

summe = summe + zahlen[2]

summe = summe + zahlen[3]

summe = summe + zahlen[4]

print(summe/5)

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for i in range(len(zahlen)):

summe += zahlen[i]

print(summe/len(zahlen))Arrays durchlaufen 1.4.5

Page 215: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for z in zahlen:

summe += z

print(summe/len(zahlen))

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for i in range(len(zahlen)):

summe += zahlen[i]

print(summe/len(zahlen))Arrays durchlaufen 1.4.5

Page 216: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

Literal Vorstellung

[ 17, 14, 23, 32, 25 ] Index 0 1 2 3 4

Wert 17 14 23 32 25

Aufgabe: berechne den Mittelwert der Werte eines Arrays

Idee fur den Algorithmus: Alle Zahlenwerte des Arrays werden summiert.Abschließend wird die Summe geteilt durch die Anzahl der Zahlen ausgegeben.

zahlen = [ 17, 14, 23, 32, 25 ]

summe = 0

for z in zahlen:

summe += z

print(summe/len(zahlen))

zahlen = [ 17, 14, 23, 32, 25 ]

print(sum(zahlen)/len(zahlen))Arrays durchlaufen 1.4.5

Page 217: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Berechnung des Mittelwertes der Werte eines Arrays

#-------------------------------------------------------------------------------

# mittelwert1.py

#-------------------------------------------------------------------------------

# Berechne den Mittelwert der Werte, die im Array zahlen[] gespeichert sind.

#-------------------------------------------------------------------------------

# Erzeuge das Array mit den Zahlen.

zahlen = [17, 4, 23, 999, 46, 24, 1, 1, 13, 18]

# summe ist die Summe der bisher aufsummierten Werte.

summe = 0

# Durchlaufe alle Indizes des Arrays zahlen[] und

# summiere die zugeordneten Zahlenwerte auf.

for i in range(len(zahlen)):

summe = summe + zahlen[i]

print('i: ' + str(i) + ' summe: ' + str(summe))

# Gib die berechnete Summe geteilt durch die Anzahl der aufsummierten Zahlenwerte aus.

print( 'Der Mittelwert ist ' + str(summe/len(zahlen)) + ' .' )

#----------------------------

# python3 mittelwert1.py

# i: 0 summe: 17

# i: 1 summe: 21

# i: 2 summe: 44

# i: 3 summe: 1043

# i: 4 summe: 1089

# i: 5 summe: 1113

# i: 6 summe: 1114

# i: 7 summe: 1115

# i: 8 summe: 1128

# i: 9 summe: 1146

# Der Mittelwert ist 114.6 .

zahlen[] ist ein Array der Lange 10.

Die Elemente von zahlen[] sind mit zahlen[0], zahlen[1],zahlen[2],. . . , zahlen[9] ansprechbar.

len(zahlen) ist die Lange des Arrays zahlen.Arrays durchlaufen 1.4.6

Page 218: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das gleiche nochmal – aber anders aufgeschrieben

#-----------------------------------------------------------------------------

# mittelwert2.py

#-----------------------------------------------------------------------------

# Berechne den Mittelwert der Werte, die im Array zahlen[] gespeichert sind.

#-----------------------------------------------------------------------------

zahlen = [17, 4, 23, 999, 46, 24, 1, 1, 13, 18]

summe = 0 # Die Summe der bisher aufsummierten Zahlenwerte.

# Durchlaufe alle Werte, die im Array zahlen[] gespeichert

# sind, und summiere sie auf.

for i in zahlen:

summe += i

print('i: ' + str(i) + ' summe: ' + str(summe))

# Gib die berechnete Summe geteilt durch die Anzahl der aufsummierten Zahlenwerte aus.

print('Der Mittelwert ist ' + str(summe/len(zahlen)) + ' .')

#------------------------

# python3 mittelwert2.py

# i: 17 summe: 17

# i: 4 summe: 21

# i: 23 summe: 44

# i: 999 summe: 1043

# i: 46 summe: 1089

# i: 24 summe: 1113

# i: 1 summe: 1114

# i: 1 summe: 1115

# i: 13 summe: 1128

# i: 8 summe: 1146

# Der Mittelwert ist 114.6 .

Arrays durchlaufen 1.4.7

Page 219: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel:

Berechnung des Mittelwertes der uber die Kommandozeile eingegebenen Werte

Die Variable sys.argv ist ein Array.

sys.argv[0] ist der Name des aufgerufenen Python-Programms.sys.argv[1], sys.argv[2], . . . sind die beim Programmaufruf ubergebenen Argumente.

#--------------------------------------------------------------------------------------------

# mittelwert3.py

#--------------------------------------------------------------------------------------------

# Berechne den Mittelwert der Werte, die uber die Kommandozeile eingegeben werden.

# Sie stehen im Array sys.argv[] unter den Indizes 1,2,...,len(sys.argv)-1 .

#--------------------------------------------------------------------------------------------

import sys

summe = 0

for i in range(1,len(sys.argv)): # for i in sys.argv[1:] :

summe = summe + int(sys.argv[i]) # summe = summe + int(i)

print('Der Mittelwert der eingegebenen Zahlen ist ' + str(summe/(len(sys.argv)-1)) + ' .')

#--------------------------------------------------------------------------------------------

# python3 mittelwert3.py 1 2 3 4 5 6 7 8 9 10

# Der Mittelwert der eingegebenen Zahlen ist 5.5 .

Arrays durchlaufen 1.4.8

Page 220: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bisherige Zusammenfassung: Benutzung des Datentyps list

Erzeugen eines Arrays:

[a0, a1, ... , an´1] ein Array der Lange n mit den Elementen a0, a1, ... , an´1

[ ] ein Array der Lange 0 (ohne Elemente)

Zugriff auf Elemente von Arrays:

a[i] das i-te Element von a[] (indizierter Zugriff)

a[i] = x ersetze das i-te Element von a[] durch x (indizierte Zuweisung)

for v in a: weise v jedes Element von a[] zu (Durchlaufen)

a[i:j] ein neues Array [a[i], a[i+1], ..., a[j-1]],

i hat Default 0 und j hat Default len(a) (Slicing)

v in a ergibt True, falls Element v in Array a vorkommt, sonst False

Funktionen zum Arbeiten mit Arrays:

len(a) die Anzahl der Elemente von a[]

sum(a) die Summe der Elemente von a[] (sie mussen summierbar sein)

min(a) ein kleinstes Element von a[] (sie mussen vergleichbar sein)

max(a) ein großtes Element von a[] (sie mussen vergleichbar sein) Operationen auf Arrays 1.4.9

Page 221: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Mehr uber den Datentyp listOperatoren + *

Die Operation + zwischen list und list schreibt Arrays hintereinander (Konkatenation).

Der Ausdruck [2, 4, 6] + [170, 14]

ergibt das neue Array [2, 4, 6, 170, 14] .

a += [3,4] hangt die Eintrage 3,4 an das Array a an (ahnlich zu a = a + [3,4]).

Die Operation * ist eine Operation zwischen list und int.

Der Ausdruck [10, 20, 30] * 4

ergibt das neue Array [10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30] .

a *= 4 hangt das Array a 3mal an a an.

Operationen auf Arrays 1.4.10

Page 222: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Mehr uber den Datentyp listOperatoren + *

Die Operation + zwischen list und list schreibt Arrays hintereinander (Konkatenation).

Der Ausdruck [2, 4, 6] + [170, 14]

ergibt das neue Array [2, 4, 6, 170, 14] .

a += [3,4] hangt die Eintrage 3,4 an das Array a an (ahnlich zu a = a + [3,4]).

Die Operation * ist eine Operation zwischen list und int.

Der Ausdruck [10, 20, 30] * 4

ergibt das neue Array [10, 20, 30, 10, 20, 30, 10, 20, 30, 10, 20, 30] .

a *= 4 hangt das Array a 3mal an a an.

Operationen auf Arrays 1.4.10

Page 223: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zuruck zum Anfangsbeispiel:

Berechnung der mittleren absoluten Abweichung vom Mittelwert

Bsp.: die Zahlen 17, 23, 16, 22, 7 haben Mittelwert 17`23`16`22`75 “ 17.

Die absoluten Abweichungen der einzelnen Zahlen vom Mittelwert sind

Zahl: 17 23 16 22 7

absolute Abweichung von 17: 0 6 1 5 10

Also ist 0`6`1`5`105 “ 22

5 die mittlere absolute Abweichung der Zahlen von ihrem Mittelwert.

Idee fur den Algorithmus:

lies Zahlen von der Konsole und speichere sie in einem Array

berechne den Mittelwert der Zahlen

summiere die absoluten Abweichungen vom Mittelwert der Zahlen auf

das Ergebnis ist der Quotient aus dieser Summe und der Anzahl der Zahlenmittlere Abweichung vom Mittelwert 1.4.11

Page 224: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zuruck zum Anfangsbeispiel:

Berechnung der mittleren absoluten Abweichung vom Mittelwert

Bsp.: die Zahlen 17, 23, 16, 22, 7 haben Mittelwert 17`23`16`22`75 “ 17.

Die absoluten Abweichungen der einzelnen Zahlen vom Mittelwert sind

Zahl: 17 23 16 22 7

absolute Abweichung von 17: 0 6 1 5 10

Also ist 0`6`1`5`105 “ 22

5 die mittlere absolute Abweichung der Zahlen von ihrem Mittelwert.

Idee fur den Algorithmus:

lies Zahlen von der Konsole und speichere sie in einem Array

berechne den Mittelwert der Zahlen

summiere die absoluten Abweichungen vom Mittelwert der Zahlen auf

das Ergebnis ist der Quotient aus dieser Summe und der Anzahl der Zahlenmittlere Abweichung vom Mittelwert 1.4.11

Page 225: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------

# mittlere-abweichung.py

#----------------------------------------------------------------------------------------

# Berechne die mittlere absolute Abweichung vom Mittelwert der Werte,

# die von standard input gelesen werden.

#----------------------------------------------------------------------------------------

import sys

print('Bitte geben Sie zeilenweise ganze Zahlen ein.\nDie Eingabe endet mit <Strg+d>.')

# Die eingegebenen Zahlen werden

# im Array zahlen gespeichert.

zahlen = []

# Lies Zahlen von standard input und

# fuge sie zum Array zahlen hinzu.

for z in sys.stdin:

zahlen += [int(z)]

# Berechne den Mittelwert der eingegebenen Zahlen.

mittelwert = sum(zahlen)/len(zahlen)

# Summiere die absoluten Abweichungen der eingegebenen Zahlen vom Mittelwert auf.

summe = 0

for z in zahlen:

summe += abs(z-mittelwert)

# Gib den Mittelwert der aufsummierten Werte aus.

print('Die mittlere absolute Abweichung vom Mittelwert ist ' + str(summe/len(zahlen)) + ' .')mittlere Abweichung vom Mittelwert 1.4.12

Page 226: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------

# mittlere-abweichung.py

#----------------------------------------------------------------------------------------

# Berechne die mittlere absolute Abweichung vom Mittelwert der Werte,

# die von standard input gelesen werden.

#----------------------------------------------------------------------------------------

import sys

print('Bitte geben Sie zeilenweise ganze Zahlen ein.\nDie Eingabe endet mit <Strg+d>.')

# Die eingegebenen Zahlen werden

# im Array zahlen gespeichert.

zahlen = []

# Lies Zahlen von standard input und

# fuge sie zum Array zahlen hinzu.

for z in sys.stdin:

zahlen += [int(z)]

# Berechne den Mittelwert der eingegebenen Zahlen.

mittelwert = sum(zahlen)/len(zahlen)

# Summiere die absoluten Abweichungen der eingegebenen Zahlen vom Mittelwert auf.

summe = 0

for z in zahlen:

summe += abs(z-mittelwert)

# Gib den Mittelwert der aufsummierten Werte aus.

print('Die mittlere absolute Abweichung vom Mittelwert ist ' + str(summe/len(zahlen)) + ' .')

#----------------------------------------------------------

# python3 mittlere-abweichung.py

# Bitte geben Sie zeilenweise ganze Zahlen ein.

# Die Eingabe endet mit <Strg+d>.

# 1

# 2

# 3

# 4

# 5

# 6

## Strg+d

# Die mittlere absolute Abweichung vom Mittelwert ist 1.5 .

mittlere Abweichung vom Mittelwert 1.4.12

Page 227: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Wie oft wurfelt man Summe i “ 2, 3, . . . , 7, . . . , 12 mit zwei Wurfeln?

Um die Erwartungswerte zu bestimmen, fuhren wir das Experiment

wurfele mit 2 Wurfelndas Ergebnis des Experiments ist die Summe der Wurfelzahle mit, wie oft jede Summe gewurfelt wurde

haufig durch und berechnen fur jede Summe die relative Haufigkeit, mit der sie gewurfelt wurde.

Die Idee zur Durchfuhrung des Experiments:

Daten: wir speichern die Zahler fur die gewurfelten Summen im Array wuerfe[]

wenn i gewurfelt wurde, wird wuerfe[i] um 1 hochgezahlt

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

Wurfelwahrscheinlichkeiten 1.4.13

Page 228: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 229: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 230: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 231: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 232: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 233: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 234: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 235: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 236: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 237: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 238: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 239: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 240: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 241: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 242: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 243: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf der Experimentreihe

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei iwuerfe[i] = wuerfe[i] + 1

”Aktion“ i wuerfe

Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 0 0 0 0 0 0 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 0 0 0 0 0

wurfele 8 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 1 0 0 0 0 1 0 0 0 0

wurfele 3 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 0 2 0 0 0 0 1 0 0 0 0...

......

wurfele 9 Index 0 1 2 3 4 5 6 7 8 9 10 11 12

Wert 0 0 10 20 30 40 50 60 50 40 30 20 10

Wurfelwahrscheinlichkeiten 1.4.14

Page 244: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------------------------------

# wuerfeln.py

#--------------------------------------------------------------------------------------------------------

# Das Programm bestimmt fur alle Zahlen i=2,3,...12,

# mit welcher Wahrscheinlichkeit sie mit 2 Wurfeln gewurfelt werden.

#--------------------------------------------------------------------------------------------------------

import sys, random

# Die Experimentreihe wird vorbereitet.

n = int( sys.argv[1] ) # Die Anzahl der Experimente wird von der Kommandozeile eingelesen.

wuerfe = [0]*13 # wuerfe[i] speichert, wieoft i gewurfelt wurde

# Die Experimentreihe wird durchgefuhrt.

for e in range(0,n): # es werden n Experimente durchgefuhrt

# Das Experiment: zwei Wurfel werden geworfen und ihre Summe wird berechnet.

wuerfelsumme = random.randrange(1,7) + random.randrange(1,7)

# Auswertung des Experiments:

wuerfe[ wuerfelsumme ] += 1

# Das Ergebnis der Experimentreihe wird ausgegeben.

for i in range(2,13):

erfolgsWkeit = wuerfe[i]/n

print('Die Wahrscheinlichkeit, eine '+str(i)+' zu wurfeln, ist ' + str(erfolgsWkeit) + '.' )

print(' D.h. etwa einer von ' + str(round(1/erfolgsWkeit)) + ' Wurfen ist ' +str(i)+'.' )

Wurfelwahrscheinlichkeiten 1.4.15

Page 245: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------------------------------

# python3 wuerfeln.py 1000000

# Die Wahrscheinlichkeit, eine 2 zu wurfeln, ist 0.027759.

# D.h. etwa einer von 36 Wurfen ist 2.

# Die Wahrscheinlichkeit, eine 3 zu wurfeln, ist 0.055723.

# D.h. etwa einer von 18 Wurfen ist 3.

# Die Wahrscheinlichkeit, eine 4 zu wurfeln, ist 0.083432.

# D.h. etwa einer von 12 Wurfen ist 4.

# Die Wahrscheinlichkeit, eine 5 zu wurfeln, ist 0.110923.

# D.h. etwa einer von 9 Wurfen ist 5.

# Die Wahrscheinlichkeit, eine 6 zu wurfeln, ist 0.138998.

# D.h. etwa einer von 7 Wurfen ist 6.

# Die Wahrscheinlichkeit, eine 7 zu wurfeln, ist 0.166332.

# D.h. etwa einer von 6 Wurfen ist 7.

# Die Wahrscheinlichkeit, eine 8 zu wurfeln, ist 0.138795.

# D.h. etwa einer von 7 Wurfen ist 8.

# Die Wahrscheinlichkeit, eine 9 zu wurfeln, ist 0.111227.

# D.h. etwa einer von 9 Wurfen ist 9.

# Die Wahrscheinlichkeit, eine 10 zu wurfeln, ist 0.083128.

# D.h. etwa einer von 12 Wurfen ist 10.

# Die Wahrscheinlichkeit, eine 11 zu wurfeln, ist 0.055919.

# D.h. etwa einer von 18 Wurfen ist 11.

# Die Wahrscheinlichkeit, eine 12 zu wurfeln, ist 0.027764.

# D.h. etwa einer von 36 Wurfen ist 12.

Wurfelwahrscheinlichkeiten 1.4.16

Page 246: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: Wie oft muss man wurfeln . . .

Wie oft muss man wurfeln, bis man erstmals eine Zahl zum zweiten Mal wurfelt?

Um den Erwartungswert zu bestimmen, fuhren wir das Experiment

wurfele solange, bis erstmals eine Zahl zum zweiten Mal gewurfelt wird;das Ergebnis des Experiments ist die Anzahl der Wurfe

haufig durch und berechnen den Mittelwert der Ergebnisse.

Die Idee zur Durchfuhrung des Experiments:

Daten: wir speichern False fur jede wurfelbare Zahl 1 . . . 6 im Array gewuerfelt[]

wenn i gewurfelt wurde, wird gewuerfelt[i] auf True gesetzt

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

Geburtstagsparadoxon 1.4.17

Page 247: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 248: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 249: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 250: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 251: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 252: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 253: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 254: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 255: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 256: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 257: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 258: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 259: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 260: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 261: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 262: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wzahle, wie oft gewurfelt wurdefalls gewuerfelt[w],

dann beende das Experimentsonst setze gewuerfelt[w] = True

und wurfele weiter (s.o.)

”Aktion“ i zaehler gewuerfelt

0Index 0 1 2 3 4 5 6

Wert False False False False False False False

wurfele 3 1 Index 0 1 2 3 4 5 6

Wert False False False True False False False

wurfele 5 2 Index 0 1 2 3 4 5 6

Wert False False False True False True False

wurfele 2 3 Index 0 1 2 3 4 5 6

Wert False False True True False True False

wurfele 5 4Geburtstagsparadoxon 1.4.18

Page 263: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#---------------------------------------------------------------------------------------------

# doppeltgewuerfelt_v1.py

#---------------------------------------------------------------------------------------------

# Es wird experimentell bestimmt, wie oft man mit einem 6er-Wurfel

# wurfeln muss, bis man eine Zahl doppelt gewurfelt hat.

#---------------------------------------------------------------------------------------------

import random

# Das Experiment wird vorbereitet.

runden = 100000 # die Anzahl der Wiederholungen des Experiments

wurfzaehler = 0 # die Anzahl, wie oft insgesamt gewurfelt wurde

# Das Experiment wird runden mal ausgefuhrt.

# Es besteht darin, solange zu wurfeln, bis eine Zahl zweimal gewurfelt wurde.

for i in range(runden):

# gewuerfelt[i] ist zu Beginn False und wird auf True gesetzt, wenn i gewurfelt wurde

gewuerfelt = [False]*7

# Es wird wiederholt gewurfelt, bis erstmals eine bereits gewurfelte Zahl gewurfelt wird.

wurf = random.randrange(1,7)

wurfzaehler += 1

while not gewuerfelt[wurf]:

gewuerfelt[wurf] = True # speichere den Wurf in gewuerfelt

wurf = random.randrange(1,7) # wurfele nochmal

wurfzaehler += 1

# Die Experimente werden ausgewertet.

print('Um eine Zahl zweimal zu wurfeln, braucht man im Mittel ' + str(wurfzaehler/runden) + ' Wurfe.')

print('Das wurde mit ' + str(runden) + ' Experimenten ermittelt.')

Geburtstagsparadoxon 1.4.19

Page 264: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# python3 doppeltgewuerfelt_v1.py

Um eine Zahl zweimal zu wurfeln, braucht man im Mittel 3.78344 Wurfe.

Das wurde mit 100000 Experimenten ermittelt.

# python3 doppeltgewuerfelt_v1.py

Um eine Zahl zweimal zu wurfeln, braucht man im Mittel 3.77197 Wurfe.

Das wurde mit 100000 Experimenten ermittelt.

# python3 doppeltgewuerfelt_v1.py

Um eine Zahl zweimal zu wurfeln, braucht man im Mittel 3.77012 Wurfe.

Das wurde mit 100000 Experimenten ermittelt.

Geburtstagsparadoxon 1.4.20

Page 265: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Eine andere Idee zum Speichern der Wurfe

Die Idee zur Durchfuhrung des Experiments:

Daten: wir speichern die gewurfelten Zahlen im Array gewuerfelt[]

jede gewurfelte Zahl wird an gewuerfelt[] angehangt

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

Geburtstagsparadoxon 1.4.21

Page 266: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 267: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 268: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 269: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 270: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 271: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 272: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 273: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 274: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 275: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 276: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 277: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 278: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 279: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 280: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 281: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 282: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 283: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 284: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 285: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorstellung vom Ablauf eines Experiments

Algorithmus zur Durchfuhrung des Experiments: wurfele – das Ergebnis sei wfalls w in gewuerfelt,

dann beende das Experimentsonst hange w an gewuerfelt[] an

und setze das Experiment fort

”Aktion“ w w in gewuerfelt gewuerfelt[]

[]

wurfele 3 False [3]

wurfele 1 False [3,1]

wurfele 4 False [3,1,4]

wurfele 5 False [3,1,4,5]

wurfele 4 True

Ergebnis: es wurde 5mal gewurfelt, bis erstmals eine Zahl zum zweiten Mal gewurfelt wurde.Geburtstagsparadoxon 1.4.22

Page 286: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#------------------------------------------------------------------------------------------

# doppeltgewuerfelt_v2.py

#------------------------------------------------------------------------------------------

import random

# Das Experiment wird vorbereitet.

runden = 100000 # die Anzahl der Wiederholungen des Experiments

wurfzaehler = 0 # die Anzahl, wie oft insgesamt gewurfelt wurde

# Das Experiment wird runden mal ausgefuhrt.

# Es besteht darin, solange zu wurfeln, bis eine Zahl zweimal gewurfelt wurde.

for i in range(runden):

# gewuerfelt speichert die bereits gewurfelten Zahlen

gewuerfelt = []

# Es wird wiederholt gewurfelt, bis erstmals eine bereits gewurfelte Zahl gewurfelt wird.

wurf = random.randrange(1,7)

wurfzaehler += 1

while wurf not in gewuerfelt:

gewuerfelt += [wurf] # speichere den Wurf in gewuerfelt

wurf = random.randrange(1,7) # wurfele nochmal

wurfzaehler += 1

# Die Experimente werden ausgewertet.

print('Um eine Zahl zweimal zu wurfeln, braucht man im Mittel ' + str(wurfzaehler/runden) + ' Wurfe.')

print('Das wurde mit ' + str(runden) + ' Experimenten ermittelt.')

Geburtstagsparadoxon 1.4.23

Page 287: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# python3 doppeltgewuerfelt_v2.py

Um eine Zahl zweimal zu wurfeln, braucht man im Mittel 3.77905 Wurfe.

Das wurde mit 100000 Experimenten ermittelt.

# python3 doppeltgewuerfelt_v2.py

Um eine Zahl zweimal zu wurfeln, braucht man im Mittel 3.77618 Wurfe.

Das wurde mit 100000 Experimenten ermittelt.

# python3 doppeltgewuerfelt_v2.py

Um eine Zahl zweimal zu wurfeln, braucht man im Mittel 3.77245 Wurfe.

Das wurde mit 100000 Experimenten ermittelt.

Geburtstagsparadoxon 1.4.24

Page 288: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wieviele Leute muss man fragen . . . ?

Wir verallgemeinern das Programm zum Wurfeln fur Wurfel mit beliebig vielen Zahlen.

Damit kann man auch das als Geburtstagsparadoxon bekannte Experiment ausfuhren.

Es fragt, was die erwartete Anzahl von Personen ist,die ich nach ihrem Geburtstag fragen muss,

bis ich zwei Personen gefunden habe, die am gleichen Tag des Jahres Geburtstag haben.

Abstrakter ausgedruckt: man wurfelt mit einem Wurfel mit den Zahlen 0..364.Wie lange muss man wurfeln, bis man eine Zahl zweimal gewurfelt hat?

Dazu mussen wir doppeltgewuerfelt.py so andern,dass man mit beliebig großen Wurfeln wurfeln kann.

Die Große des Wurfels wird von der Kommandozeile gelesen.

Geburtstagsparadoxon 1.4.25

Page 289: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# geburtstagsparadoxon.py

#------------------------------------------------------------------------------------------

import random, sys

# Die Versuchsreihe wird vorbereitet.

n = int(sys.argv[1]) # lies die Anzahl n der Tage eines Jahres von der Kommandozeile

runden = 100000 # die Anzahl der Wiederholungen des Experiments

fragenzaehler = 0 # die Anzahl, wie viele Personen gefragt wurden

# Das Experiment wird runden mal ausgefuhrt.

# Es besteht darin, solange zu fragen, bis zwei gleiche Geburstage geantwortet wurden.

# Die Geburtstage stammen aus dem Bereich 0...n-1.

for i in range(runden):

# genannt enthalt die bereits genannten Geburtstage

genannt = []

# Es wird wiederholt gefragt, bis erstmals eine bereits genannte Zahl auftaucht.

fragenzaehler += 1

antwort = random.randrange(n)

while not antwort in genannt:

# Speichere, dass die Antwort genannt wurde.

genannt += [antwort]

# Frage nach der nachsten Antwort.

fragenzaehler += 1

antwort = random.randrange(n)

# Die Versuchsreihe wird ausgewertet.

print('Um auf einem Planeten mit einem ' + str(n) + '-Tage-Jahr zwei Personen mit gleichem')

print('Geburtstag zu finden, braucht man im Mittel ' + str(fragenzaehler/runden) + ' Personen.')

print('Das wurde mit ' + str(runden) + ' Experimenten ermittelt.') Geburtstagsparadoxon 1.4.26

Page 290: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir konnen jetzt das Geburtstagsparadoxon fur Erden-, Merkur-, Mars- und Neptunbewohner

experimentell ausprobieren . . .

# python3 geburtstagsparadoxon.py 365

Um auf einem Planeten mit einem 365-Tage-Jahr zwei Personen mit gleichem

Geburtstag zu finden, braucht man im Mittel 24.54053 Personen.

Das wurde mit 100000 Experimenten ermittelt.

# python3 geburtstagsparadoxon.py 88

Um auf einem Planeten mit einem 88-Tage-Jahr zwei Personen mit gleichem

Geburtstag zu finden, braucht man im Mittel 12.40962 Personen.

Das wurde mit 100000 Experimenten ermittelt.

# python3 geburtstagsparadoxon.py 687

Um auf einem Planeten mit einem 687-Tage-Jahr zwei Personen mit gleichem

Geburtstag zu finden, braucht man im Mittel 33.44678 Personen.

Das wurde mit 100000 Experimenten ermittelt.

# python3 geburtstagsparadoxon.py 60265

Um auf einem Planeten mit einem 60265-Tage-Jahr zwei Personen mit gleichem

Geburtstag zu finden, braucht man im Mittel 309.387 Personen.

Das wurde mit 10000 Experimenten ermittelt.

Geburtstagsparadoxon 1.4.27

Page 291: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Allgemeines uber Objekte in Python

Die”grobe Vorstellung“ bei den informellen Programmablaufen uber die Speicherung von Daten stimmt

naturlich nicht – wir verfeinern die Vorstellung jetzt.

Die Daten werden durch Objekte reprasentiert.Jedes Objekt hat eine Identitat, einen Typ und einen Wert.

§ Die Identitat bestimmt das Objekt eindeutig.(Vorstellung: Adresse des Objektes im Speicher des Computers.)

§ Der Typ beschreibt das Verhalten des Objektes(d.h. die Werte, die es annehmen kann, und die Operationen, die auf ihm erlaubt sind).

§ Der Wert ist der Datentyp-Wert, den es reprasentiert/speichert.Bsp.: ein Objekt vom Typ int kann den Wert 99 speichern.

Eine Objekt-Referenz ist eine konkrete Darstellung der Identitat des Objektes.Python-Programme benutzen Objekt-Referenzen um

§ auf den Wert des Objektes zuzugreifen oder ihn zu andern,

§ auf die Objekt-Referenz zuzugreifen oder sie zu andern.Objekte in Python 1.4.28

Page 292: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

§ Ein Literal weist Python an, ein Objekt mit einem bestimmten Wert zu erzeugen.Bsp.: das Literal 99 weist Python an, ein int-Objekt mit Wert 99 zu erzeugen.

§ Eine Variable ist ein Name fur eine Objekt-Referenz.

§ Ein Ausdruck weist Python an, ein Objekt mit dem Wert des Ausdrucks zu erzeugen.Bsp.: wenn das an die Variable a gebundene Objekt den Wert 3 hat, dann weist der Ausdruck 4*a+2

Python an, ein int-Objekt mit Wert 14 zu erzeugen.

§ Eine Zuweisung xVariabley=xAusdrucky weist Python an, ein Objekt mit dem Wert des Ausdrucks zuerzeugen und die Variable daran zu binden.Falls der Ausdruck nur eine Variable ist, dann wird kein neues Objekt erzeugt, sondern das an dieVariable gebundene Objekt genommen.Bsp.: wenn das an die Variable a gebundene Objekt den Wert 3 hat, dann wird fur die Zuweisungb = 4*a+2 ein Objekt mit dem Wert 14 erzeugt und dieses Objekt wird an die Variable b gebunden.

a = 3 3a

b = 4*a + 2 14b

Variable Objekt-Referenz ObjektObjekte in Python 1.4.29

Page 293: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Programmablauf auf dem Objekt-Level

Ein 3-zeiliges Python-Programm und dessen Wirkung auf dem Objekt-Level:

a = 1234 1234a

b = 47 47b

c = a + b 1281c

Objekte in Python 1.4.30

Page 294: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Programmablauf auf dem Objekt-Level

Ein 3-zeiliges Python-Programm und dessen Wirkung auf dem Objekt-Level:

a = 1234 1234a

b = 47 47b

c = a + b 1281c

Objekte in Python 1.4.30

Page 295: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Programmablauf auf dem Objekt-Level

Ein 3-zeiliges Python-Programm und dessen Wirkung auf dem Objekt-Level:

a = 1234 1234a

b = 47 47b

c = a + b 1281c

Objekte in Python 1.4.30

Page 296: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Programmablauf auf dem Objekt-Level

Ein 3-zeiliges Python-Programm und dessen Wirkung auf dem Objekt-Level:

a = 1234 1234a

b = 47 47b

c = a + b 1281c

Objekte in Python 1.4.30

Page 297: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Programmablauf auf dem Objekt-Level

Ein 3-zeiliges Python-Programm und dessen Wirkung auf dem Objekt-Level:

a = 1234 1234a

b = 47 47b

c = a + b 1281c

Objekte in Python 1.4.30

Page 298: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Programmablauf auf dem Objekt-Level

Ein 3-zeiliges Python-Programm und dessen Wirkung auf dem Objekt-Level:

a = 1234 1234a

b = 47 47b

c = a + b 1281c

Objekte in Python 1.4.30

Page 299: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vertauschung der Werte zweier Variablen. 1234a

47b

t = a 1234a

47b

t

a = b 1234

47b

t

a

b = t 1234

47b

t

a

Objekte in Python 1.4.31

Page 300: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vertauschung der Werte zweier Variablen. 1234a

47b

t = a 1234a

47b

t

a = b 1234

47b

t

a

b = t 1234

47b

t

a

Objekte in Python 1.4.31

Page 301: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vertauschung der Werte zweier Variablen. 1234a

47b

t = a 1234a

47b

t

a = b 1234

47b

t

a

b = t 1234

47b

t

a

Objekte in Python 1.4.31

Page 302: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vertauschung der Werte zweier Variablen. 1234a

47b

t = a 1234a

47b

t

a = b 1234

47b

t

a

b = t 1234

47b

t

a

Objekte in Python 1.4.31

Page 303: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nicht-veranderbare Datentypen

Objekte der Standard-Typen int, float, string und bool sind nicht veranderbar.

Wenn einer Variablen ein Wert eines Ausdrucks einer dieser Typen zugewiesen wird,dann wird ein neues Objekt mit diesem Wert erzeugt.

s = 'Abcd' ’Abcd’s

s = s + ' ef' ’Abcd’

’ ef’

’Abcd ef’

s

i = 15 15i

i = i + 1 15

1

16

i

Objekte in Python 1.4.32

Page 304: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nicht-veranderbare Datentypen

Objekte der Standard-Typen int, float, string und bool sind nicht veranderbar.

Wenn einer Variablen ein Wert eines Ausdrucks einer dieser Typen zugewiesen wird,dann wird ein neues Objekt mit diesem Wert erzeugt.

s = 'Abcd' ’Abcd’s

s = s + ' ef' ’Abcd’

’ ef’

’Abcd ef’

s

i = 15 15i

i = i + 1 15

1

16

i

Objekte in Python 1.4.32

Page 305: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nicht-veranderbare Datentypen

Objekte der Standard-Typen int, float, string und bool sind nicht veranderbar.

Wenn einer Variablen ein Wert eines Ausdrucks einer dieser Typen zugewiesen wird,dann wird ein neues Objekt mit diesem Wert erzeugt.

s = 'Abcd' ’Abcd’s

s = s + ' ef' ’Abcd’

’ ef’

’Abcd ef’

s

i = 15 15i

i = i + 1 15

1

16

i

Objekte in Python 1.4.32

Page 306: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nicht-veranderbare Datentypen

Objekte der Standard-Typen int, float, string und bool sind nicht veranderbar.

Wenn einer Variablen ein Wert eines Ausdrucks einer dieser Typen zugewiesen wird,dann wird ein neues Objekt mit diesem Wert erzeugt.

s = 'Abcd' ’Abcd’s

s = s + ' ef' ’Abcd’

’ ef’

’Abcd ef’

s

i = 15 15i

i = i + 1 15

1

16

i

Objekte in Python 1.4.32

Page 307: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Arrays

a = [5, 9, 11]0 1 2

3

5 9 11

a

b = a

5 9 11

0 1 2

3a

b

b[1] = 17

5 9 11 17

0 1 2

3a

b

Objekte vom Typ array sind veranderbar (mutable)(anders als Objekte der Standard-Typen int, float, string und bool)!

Objekte in Python 1.4.33

Page 308: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Arrays

a = [5, 9, 11]0 1 2

3

5 9 11

a

b = a

5 9 11

0 1 2

3a

b

b[1] = 17

5 9 11 17

0 1 2

3a

b

Objekte vom Typ array sind veranderbar (mutable)(anders als Objekte der Standard-Typen int, float, string und bool)!

Objekte in Python 1.4.33

Page 309: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Arrays

a = [5, 9, 11]0 1 2

3

5 9 11

a

b = a

5 9 11

0 1 2

3a

b

b[1] = 17

5 9 11 17

0 1 2

3a

b

Objekte vom Typ array sind veranderbar (mutable)(anders als Objekte der Standard-Typen int, float, string und bool)!

Objekte in Python 1.4.33

Page 310: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Arrays

a = [5, 9, 11]0 1 2

3

5 9 11

a

b = a

5 9 11

0 1 2

3a

b

b[1] = 17

5 9 11 17

0 1 2

3a

b

Objekte vom Typ array sind veranderbar (mutable)(anders als Objekte der Standard-Typen int, float, string und bool)!

Objekte in Python 1.4.33

Page 311: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

0

1d-Array kopieren 1.4.34

Page 312: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

0

1d-Array kopieren 1.4.34

Page 313: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

0

1d-Array kopieren 1.4.34

Page 314: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

0

1d-Array kopieren 1.4.34

Page 315: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

0

1d-Array kopieren 1.4.34

Page 316: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

1d-Array kopieren 1.4.34

Page 317: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

0 1 2

3b

1d-Array kopieren 1.4.34

Page 318: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

17

0 1 2

3b

1d-Array kopieren 1.4.34

Page 319: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Kopieren eines Arrays mit nicht-veranderbaren Elementen

a = [5, 9, 11]

5 9 11

0 1 2

3a

b = [0]*len(a)

for i in range(len(a)):

b[i] = a[i]

b[1] = 17

17

0 1 2

3b

1d-Array kopieren 1.4.34

Page 320: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-------------------------------------------------------------

# array-1d-kopieren.py Drei Wege, ein 1d-Array zu kopieren.

#-------------------------------------------------------------

a = [1, 2, 3, 4, 5]

# Kopiere Array a ins Array b.

# Dazu wird zuerst ein Array der Lange len(a) erzeugt.

b = [0] * len(a)

print('Lange von b: ' + str(len(b)))

# Anschließend wird fur jeden Index der Wert eingetragen.

for i in range(len(a)): b[i] = a[i]

print('b: ' + str(b))

# Kopiere Array a ins Array c.

# Dazu wird zuerst ein Array der Lange 0 erzeugt.

c = []

# Anschließend wird das Array fur jeden Index i um den Wert a[i] verlangert.

for i in range(len(a)):

print('Lange von c: ' + str(len(c)))

c += [a[i]] # hange Wert a[i] an das Array c an

print('c: ' + str(c))

# Abschließend die kurzeste Variante.

d = a[:] # das ist Abkurzung von d = a[0:len(a)]

print('d: ' + str(d))

#----------------------------

# python3 array-1d-kopieren.py

# Lange von b: 5

# b: [1, 2, 3, 4, 5]

# Lange von c: 0

# Lange von c: 1

# Lange von c: 2

# Lange von c: 3

# Lange von c: 4

# c: [1, 2, 3, 4, 5]

# d: [1, 2, 3, 4, 5]

1d-Array kopieren 1.4.35

Page 321: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Datentyp tuple – Tupel

tuple ist wie list (Array), aber nicht-veranderbar.

Literale vom Typ tuple werden mit runden Klammern beschrieben:

( 17, 4, 23, 12 ) ( 'a', )

Benutzung von Elementen von Tupeln geht wie bei Arrays:

t = ('a', 1, 'b')

b = t[2]

Da Objekte vom Typ tuple nicht-veranderbar sind, geht Folgendes nicht:

t[2] = 42

tuple 1.4.36

Page 322: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gerne benutzt wird das Unpacking (geht auch bei Arrays):

a = 15

b = 'hello'

( b, a ) = ( a, b )

vertauscht die Werte von a und b.

(a,b) auf der rechten Seite der Zuweisung

erzeugt ein Tupel mit den Werten von a und b (packing).

(b,a) auf der linken Seite der Zuweisung

packt das Tupel von der rechten Seite aus (unpacking):

Variable b wird als Wert das erste Element des”rechten“ Tupels zugewiesen

Variable a erhalt als Wert das nachste Element des”rechten“ Tupels.

Als Kurzschreibweise konnen die Klammern weggelassen werden.

b, a = a, b tuple 1.4.37

Page 323: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nochmal was zum Datentyp string

Ein String ist wie ein Tupel aus Zeichen.

Also ist Folgendes mit String-Variable s moglich:

§ s[i] das Zeichen mit Index i

§ s[i:j] die Zeichen mit Indizes i...j-1

§ c in s ergibt True, falls Zeichen c in s vorkommt

§ for c in s: ... durchlauft alle Zeichen in s

string 1.4.38

Page 324: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

Wir kennen den Datentyp list (Array),

kennen den Unterschied zwischen veranderbaren und nicht-veranderbaren Datentypen,

konnen 1-dimensionale Arrays erzeugen und auf ihre Elemente zugreifen,

kennen die Probleme beim Kopieren von Arrays,

und kennen die”Variante“ tuple (Tupel).

Wir haben gesehen, dass es beim Entwickeln von Programmen

einfacher sein kann, erst ein Programm fur ein einfaches Beispiel zu schreiben

und das dann zu verallgemeinern.

1.4.39

Page 325: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 04

Das Kapitel uber Arrays wird fortgesetzt.

In der letzten Vorlesung wurden 1-dimensionale Arrays betrachtet.

Jetzt geht es weiter mit 2-dimensionalen Arrays.

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und Schleifen

1.4 ArraysEindimensionale Arrays

Allgemeines uber Objekte in Python

Zweidimensionale Arrays

1.5 Ein- und Ausgabe

1.6 Dictionaries und Abschluss-Beispiel Page Rank

1.4.40

Page 326: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2-dimensionale Arrays

Beispiel-Aufgabe: Uber die Ergebnisse der Ubungsblatter fuhren wir Buch mittels einer Tabelle.

Zei

len

SpaltenName Blatt 1 Blatt 2 Blatt 3 Blatt 4 Blatt 5

A 20 15 12 8 13B 12 0 20 20 8C 13 12 15 11 9D 18 19 17 18 20E 11 12 0 12 13F 16 13 15 18 20

Wir mochten die mittlere Punktzahl jedes Studenten in allen Ubungsblatternund die mittlere Punktzahl jedes Ubungsblattes wissen.

Dazu speichern wir die Zahlenwerte der Tabelle als 2-dimensionales Array.Jeder Eintrag im Array tabelle ist ein Array, das fur eine Zeile der Tabelle steht.

tabelle = [ [ 20, 15, 12, 8, 13],

[ 12, 0, 20, 20, 8 ],

[ 13, 12, 15, 11, 9 ],

[ 18, 19, 17, 18, 20],

[ 11, 12, 0, 12, 13],

[ 16, 13, 15, 18, 20] ]

tabelle[2] ist [ 13, 12, 15, 11, 9 ].

tabelle[2][3] ist 11.

2d-Arrays benutzen 1.4.41

Page 327: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2-dimensionale Arrays

Beispiel-Aufgabe: Uber die Ergebnisse der Ubungsblatter fuhren wir Buch mittels einer Tabelle.

Zei

len

SpaltenName Blatt 1 Blatt 2 Blatt 3 Blatt 4 Blatt 5

A 20 15 12 8 13B 12 0 20 20 8C 13 12 15 11 9D 18 19 17 18 20E 11 12 0 12 13F 16 13 15 18 20

Wir mochten die mittlere Punktzahl jedes Studenten in allen Ubungsblatternund die mittlere Punktzahl jedes Ubungsblattes wissen.

Dazu speichern wir die Zahlenwerte der Tabelle als 2-dimensionales Array.Jeder Eintrag im Array tabelle ist ein Array, das fur eine Zeile der Tabelle steht.

tabelle = [ [ 20, 15, 12, 8, 13],

[ 12, 0, 20, 20, 8 ],

[ 13, 12, 15, 11, 9 ],

[ 18, 19, 17, 18, 20],

[ 11, 12, 0, 12, 13],

[ 16, 13, 15, 18, 20] ]

tabelle[2] ist [ 13, 12, 15, 11, 9 ].

tabelle[2][3] ist 11.

2d-Arrays benutzen 1.4.41

Page 328: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------------------

# tabelle-auswerten.py

#-----------------------------------------------------------------------------------------------------

# Berechne die Mittelwerte jeder Zeile und

# die Mittelwerte jeder Spalte der angegebenen Tabelle (d.h. des angegebenen 2-dimensionalen Arrays).

tabelle = [ [ 20, 15, 12, 8, 13],

[ 12, 0, 20, 20, 8 ],

[ 13, 12, 15, 11, 9 ],

[ 18, 19, 17, 20, 12],

[ 11, 12, 0, 12, 13],

[ 16, 13, 15, 18, 20] ]

# Berechne den Mittelwert jeder Zeile der Tabelle und gib ihn aus.

for zeilennr in range(len(tabelle)):

m = sum(tabelle[zeilennr])/len(tabelle[zeilennr])

print( 'Zeile ' + str(zeilennr) + ' hat Mittelwert ' + str(m) + ' .' )

# Berechne den Mittelwert jeder Spalte der Tabelle und gib ihn aus.

# Dabei gehen wir davon aus, dass alle Zeilen gleichviele Spalten haben.

for spaltennr in range(len(tabelle[0])):

spaltensumme = 0

for zeilennr in range(len(tabelle)):

spaltensumme += tabelle[zeilennr][spaltennr]

print('Spalte ' + str(spaltennr) + ' hat Mittelwert ' + str(spaltensumme/len(tabelle)) + ' .')

2d-Arrays benutzen 1.4.42

Page 329: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 tabelle-auswerten.py

Zeile 0 hat Mittelwert 13.6 .

Zeile 1 hat Mittelwert 12.0 .

Zeile 2 hat Mittelwert 12.0 .

Zeile 3 hat Mittelwert 17.2 .

Zeile 4 hat Mittelwert 9.6 .

Zeile 5 hat Mittelwert 16.4 .

Spalte 0 hat Mittelwert 15.0 .

Spalte 1 hat Mittelwert 11.833333333333334 .

Spalte 2 hat Mittelwert 13.166666666666666 .

Spalte 3 hat Mittelwert 14.833333333333334 .

Spalte 4 hat Mittelwert 12.5 .

tabelle = [ [ 20, 15, 12, 8, 13],

[ 12, 0, 20, 20, 8 ],

[ 13, 12, 15, 11, 9 ],

[ 18, 19, 17, 20, 12],

[ 11, 12, 0, 12, 13],

[ 16, 13, 15, 18, 20] ]

2d-Arrays benutzen 1.4.43

Page 330: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Erzeugung eines 2-dimensionalen Arrays

Erzeuge ein Array mit z Zeilen und s Spalten.Der Eintrag mit Zeilen-Index i und Spalten-Index j soll 'i,j' sein.

Zei

len

din

diz

es

Spaltenindizes0 1 2 3 4

0 '0,0' '0,1' '0,2' '0,3' '0,4'

1 '1,0' '1,1' '1,2' '1,3' '1,4'

2 '2,0' '2,1' '2,2' '2,3' '2,4'

3 '3,0' '3,1' '3,2' '3,3' '3,4'

Erzeuge zuerst ein Array b mit der gewunschten Anzahl von”Platzen“ fur die Zeilen.

Trage dann an jedem Platz von b die entsprechende Zeile ein.

b = [0]*z # Erzeuge Array b mit z Platzen fur die Zeilen.

for zeilennr in range(z): # Gehe durch alle Indizes zeilennr im Array b.

b[zeilennr] = [0]*s # Erzeuge ein Array mit s Platzen als zeilennr-te Zeile von b.

for spaltennr in range(s): # Fulle jeden Eintrag in der zeilennr-ten Zeile von b.

b[zeilennr][spaltennr] = str(zeilennr) + ',' + str(spaltennr)

2d-Arrays erzeugen 1.4.44

Page 331: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Erzeugung eines 2-dimensionalen Arrays

Erzeuge ein Array mit z Zeilen und s Spalten.Der Eintrag mit Zeilen-Index i und Spalten-Index j soll 'i,j' sein.

Zei

len

din

diz

es

Spaltenindizes0 1 2 3 4

0 '0,0' '0,1' '0,2' '0,3' '0,4'

1 '1,0' '1,1' '1,2' '1,3' '1,4'

2 '2,0' '2,1' '2,2' '2,3' '2,4'

3 '3,0' '3,1' '3,2' '3,3' '3,4'

Erzeuge zuerst ein Array b mit der gewunschten Anzahl von”Platzen“ fur die Zeilen.

Trage dann an jedem Platz von b die entsprechende Zeile ein.

b = [0]*z # Erzeuge Array b mit z Platzen fur die Zeilen.

for zeilennr in range(z): # Gehe durch alle Indizes zeilennr im Array b.

b[zeilennr] = [0]*s # Erzeuge ein Array mit s Platzen als zeilennr-te Zeile von b.

for spaltennr in range(s): # Fulle jeden Eintrag in der zeilennr-ten Zeile von b.

b[zeilennr][spaltennr] = str(zeilennr) + ',' + str(spaltennr)

[['0,0', '0,1', '0,2', '0,3', '0,4'], ['1,0', '1,1', '1,2', '1,3', '1,4'],

['2,0', '2,1', '2,2', '2,3', '2,4'], ['3,0', '3,1', '3,2', '3,3', '3,4']]2d-Arrays erzeugen 1.4.44

Page 332: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Modul stdarray.py

Zu den Modulen zum Buch gehort das Modul stdarray.py.

Es enthalt Funktionen zum Erzeugen von Arrays.

stdarray.create1D(n, val) Array der Lange n, jedes Element hat Wert valstdarray.create2D(n, m, val) n-mal-m Array, jedes Element hat Wert val

Modul stdarray.py 1.4.45

Page 333: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 334: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 335: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 336: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 337: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 338: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 339: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 340: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2von 3 0.15 0.25 0.2 0.3 0.1

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 341: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2von 3 0.15 0.25 0.2 0.3 0.1

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 342: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2von 3 0.15 0.25 0.2 0.3 0.1von 4 0.1 0.3 0.05 0.1 0.45

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 343: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

[ 0.1, 0.3, 0.05, 0.1, 0.45] ]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2von 3 0.15 0.25 0.2 0.3 0.1von 4 0.1 0.3 0.05 0.1 0.45

0.1

0.35

0.05

0.2

Frisbee 1.4.46

Page 344: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

[ 0.1, 0.3, 0.05, 0.1, 0.45] ]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2von 3 0.15 0.25 0.2 0.3 0.1von 4 0.1 0.3 0.05 0.1 0.45

0.1

0.35

0.05

0.2

Die Wahrscheinlichkeit, dass das Frisbee den Weg 0 – 1 – 4 – 2 – 1 geworfen wird,

ist 0.1 ¨ 0.35 ¨ 0.05 ¨ 0.2 “ 0.00035.Frisbee 1.4.46

Page 345: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee

5 Kinder werfen sich ein Frisbee zu.Die

”Zielwahrscheinlichkeiten“ sind in der Grafik angegeben und werden in das Array m eingetragen.

0

1

2

3

4

0.1

0.3

0.3

0.2

0.1

0.050.1

0.2

0.35

0.3

0.2

0.2

0.2

0.2

0.2

0.3

0.25

0.2

0.1

0.15

0.45

0.3

0.05

0.10.1

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

[ 0.1, 0.3, 0.05, 0.1, 0.45] ]

zu 0 zu 1 zu 2 zu 3 zu 4von 0 0.1 0.1 0.3 0.3 0.2von 1 0.3 0.05 0.1 0.2 0.35von 2 0.2 0.2 0.2 0.2 0.2von 3 0.15 0.25 0.2 0.3 0.1von 4 0.1 0.3 0.05 0.1 0.45

0.1

0.35

0.05

0.2

Mit welcher Wahrscheinlichkeit landet das Frisbee mit Start 0 nach 4 Wurfen bei 1?

Frisbee 1.4.46

Page 346: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Frisbee-Problem: die Berechnung der Wahrscheinlichkeiten fur n Wurfe

Wir haben das 2d-Array m mit den Wahrscheinlichkeiten m[z][s],

dass das Frisbee von Spieler z mit einem Wurf zu Spieler s kommt.

Wir wollen ein 2d-Array e mit den Wahrscheinlichkeiten e[z][s] berechnen,

dass das Frisbee von Spieler z mit n Wurfen zu Spieler s kommt.

Zum Beispiel:

Start:Das 2d-Array m mit

”m[z][s] ist die Wkeit, dass

das Frisbee von z mit einem Wurf zu s kommt“.

[ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

[ 0.1, 0.3, 0.05, 0.1, 0.45] ]

Ziel:Das 2d-Array e mit

”e[z][s] ist die Wkeit, dass

das Frisbee von z mit vier Wurfen zu s kommt“.

[ [ 0.1648, 0.1926, 0.1581, 0.2116, 0.2735 ],

[ 0.1651, 0.1921, 0.1577, 0.2098, 0.2780 ],

[ 0.1642, 0.1923, 0.1566, 0.2112, 0.2751 ],

[ 0.1625, 0.1929, 0.1582, 0.2156, 0.2718 ],

[ 0.1630, 0.1943, 0.1513, 0.2060, 0.2841 ] ]

Das Frisbee-Problem 1.4.47

Page 347: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir werden drei Losungen fur das Problem betrachten.

§ exakte Losung mit einem”brute force“-Algorithmus,

der durch alle moglichen Wurffolgen geht und deren Wahrscheinlichkeiten aufsummiert

(bei 5 Spielern und Wurffolgen aus 16 Wurfen braucht der Algorithmus 16 ¨ 517 (« 12 Milliarden)

Multiplikationen)

die Losung ist exakt, aber ihre Berechnung dauert sehr lange

§ Losung mittels Simulation der Wurffolgen der Spieler

(die Rechenzeit hangt von der erwunschten Exaktheit ab,

ist aber recht lang fur einigermaßen exakte Ergebnisse)

die Losung ist nicht exakt, aber die Berechnung kann recht schnell gehen

§ exakte Losung mittels”Dynamischem Programmieren“

dabei wird vermieden, mehrfach vorkommende Teil-Wurffolgen wiederholt zu berechnen

(bei 5 Spielern und Wurffolgen aus 16 Wurfen braucht der Algorithmus 4 ¨ 53 (=500) Multiplikationen)

die Losung ist exakt (bis auf Rundungsfehler . . . ) und schnell

Das Frisbee-Problem 1.4.48

Page 348: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems”

brute force“

Wir haben das 2d-Array m mit den Wahrscheinlichkeiten m[z][s],

dass das Frisbee von Spieler z mit einem Wurf zu Spieler s kommt.

Wir wollen ein 2d-Array e mit den Wahrscheinlichkeiten e[z][s] berechnen,

dass das Frisbee von Spieler z mit n Wurfen zu Spieler s kommt.

Zum Beispiel:

Start:Das 2d-Array m mit

”m[z][s] ist die Wkeit, dass

das Frisbee von z mit einem Wurf zu s kommt“.

[ [ 0.1, 0.1, 0.3, 0.3, 0.2 ],

[ 0.3, 0.05, 0.1, 0.2, 0.35],

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[ 0.15, 0.25, 0.2, 0.3, 0.1 ],

[ 0.1, 0.3, 0.05, 0.1, 0.45] ]

Ziel:Das 2d-Array e mit

”e[z][s] ist die Wkeit, dass

das Frisbee von z mit vier Wurfen zu s kommt“.

[ [ 0.1648, 0.1926, 0.1581, 0.2116, 0.2735 ],

[ 0.1651, 0.1921, 0.1577, 0.2098, 0.2780 ],

[ 0.1642, 0.1923, 0.1566, 0.2112, 0.2751 ],

[ 0.1625, 0.1929, 0.1582, 0.2156, 0.2718 ],

[ 0.1630, 0.1943, 0.1513, 0.2060, 0.2841 ] ]

Frisbee”

brute force“ 1.4.49

Page 349: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Um e zu berechnen, schauen wir uns alle moglichen Folgen aus n Wurfen an.

Beispiel: Fur n “ 5 ist 2–4–2–3–1–4 ein mogliche Wurffolge aus 5 Wurfen

(2 wirft zu 4, 4 wirft zu 2, 2 wirft zu 3, 3 wirft zu 1, und 1 wirft zu 4).

Die Wahrscheinlichkeit dieser Wurffolge ist

das Produkt aus den Wahrscheinlichkeiten der einzelnen Wurfe:

Wurf 2–4 4–2 2–3 3–1 1–4

Wkeit 0.2 0.05 0.2 0.15 0.35

Das Produkt der Wkeiten ist 0.2 ¨ 0.05 ¨ 0.2 ¨ 0.15 ¨ 0.35 “ 0.000105.

Am Anfang haben alle Eintrage e[z][s] in e den Wert 0.

Fur jede mogliche Wurffolge x– . . . –y

wird ihre Wahrscheinlichkeit zu e[x][y] hinzuaddiert (im Beispiel zu e[2][4]).

Dadurch hat man nach Durchlaufen aller Wurffolgen in e die exakten Wahrscheinlichkeiten

e[z][s], dass das Frisbee von z nach n Wurfen bei s landet.Frisbee

”brute force“ 1.4.50

Page 350: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2

......

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

Frisbee”

brute force“ 1.4.51

Page 351: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

Frisbee”

brute force“ 1.4.51

Page 352: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

sonst:

gehe von rechts nach links,

bis die erste Stelle ă 9 gefunden wurde;

ersetze dabei jede 9 durch eine 0;

zahle an der ersten Stelle ă 9 nun 1 dazu;

das ist die nachste Wurffolge

Frisbee”

brute force“ 1.4.51

Page 353: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

sonst:

gehe von rechts nach links,

bis die erste Stelle ă 9 gefunden wurde;

ersetze dabei jede 9 durch eine 0;

zahle an der ersten Stelle ă 9 nun 1 dazu;

das ist die nachste Wurffolge

Frisbee”

brute force“ 1.4.51

Page 354: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

sonst:

gehe von rechts nach links,

bis die erste Stelle ă 9 gefunden wurde;

ersetze dabei jede 9 durch eine 0;

zahle an der ersten Stelle ă 9 nun 1 dazu;

das ist die nachste Wurffolge

Frisbee”

brute force“ 1.4.51

Page 355: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

sonst:

gehe von rechts nach links,

bis die erste Stelle ă 9 gefunden wurde;

ersetze dabei jede 9 durch eine 0;

zahle an der ersten Stelle ă 9 nun 1 dazu;

das ist die nachste Wurffolge

Frisbee”

brute force“ 1.4.51

Page 356: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0

......

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

sonst:

gehe von rechts nach links,

bis die erste Stelle ă 9 gefunden wurde;

ersetze dabei jede 9 durch eine 0;

zahle an der ersten Stelle ă 9 nun 1 dazu;

das ist die nachste Wurffolge

Frisbee”

brute force“ 1.4.51

Page 357: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie durchlauft man alle Wurffolgen einer festen Lange?

Analog zu: wie durchlauft man alle n-stelligen Dezimalzahlen/Folgen von Ziffern?

1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 2...

...

1 1 1 1 1 9 9 9

1 1 1 1 1 9 9 0

1 1 1 1 1 9 0 0

1 1 1 1 1 0 0 0

1 1 1 1 2 0 0 0

1 1 1 1 2 0 0 0...

...

9 9 9 9 9 9 9 9

beginne mit der”kleinsten“ Wurffolge

zahle an der letzten Stelle 1 dazu, falls sie ă 9 ist

sonst:

gehe von rechts nach links,

bis die erste Stelle ă 9 gefunden wurde;

ersetze dabei jede 9 durch eine 0;

zahle an der ersten Stelle ă 9 nun 1 dazu;

das ist die nachste Wurffolge

Frisbee”

brute force“ 1.4.51

Page 358: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# wurffolgen.py

#----------------------------------------------------------------------------------------

# Lies n und c (beides int) von der Kommandozeile.

# Erzeuge der Reihe nach alle Wurffolgen (Array) mit n Wurfen und Spielern 0...c.

#----------------------------------------------------------------------------------------

import sys

# Lies n und c (int) von der Kommandozeile ein.

n = int(sys.argv[1])

c = int(sys.argv[2])

# Erzeuge die "kleinste" Wurffolge k nur aus 0en, und gib sie aus.

k = [0]*(n+1)

print(k)

# Solange nicht die "großte" Wurffolge erreicht wurde, erzeuge die nachste.

while min(k)<c:

for i in range(len(k)-1,-1,-1):

# Falls an Stelle i "ohne Ubertrag" 1 hinzuaddiert werden kann,

# dann mache das und verlasse die for-Schleife.

if k[i]<c:

k[i] += 1

break

# sonst: ersetze die Stelle durch 0 und gehe in der for-Schleife weiter nach links.

else: k[i] = 0

# Gib die Wurffolge aus.

print(k)Frisbee

”brute force“ 1.4.52

Page 359: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 wurffolgen.py 2 2

[0, 0, 0]

[0, 0, 1]

[0, 0, 2]

[0, 1, 0]

[0, 1, 1]

[0, 1, 2]

[0, 2, 0]

[0, 2, 1]

[0, 2, 2]

[1, 0, 0]

[1, 0, 1]

[1, 0, 2]

[1, 1, 0]

[1, 1, 1]

[1, 1, 2]

[1, 2, 0]

[1, 2, 1]

[1, 2, 2]

[2, 0, 0]

[2, 0, 1]

[2, 0, 2]

[2, 1, 0]

[2, 1, 1]

[2, 1, 2]

[2, 2, 0]

[2, 2, 1]

[2, 2, 2]

$ python3 wurffolgen.py 4 1

[0, 0, 0, 0, 0]

[0, 0, 0, 0, 1]

[0, 0, 0, 1, 0]

[0, 0, 0, 1, 1]

[0, 0, 1, 0, 0]

[0, 0, 1, 0, 1]

[0, 0, 1, 1, 0]

[0, 0, 1, 1, 1]

[0, 1, 0, 0, 0]

[0, 1, 0, 0, 1]

[0, 1, 0, 1, 0]

[0, 1, 0, 1, 1]

[0, 1, 1, 0, 0]

[0, 1, 1, 0, 1]

[0, 1, 1, 1, 0]

[0, 1, 1, 1, 1]

[1, 0, 0, 0, 0]

[1, 0, 0, 0, 1]

...

[1, 1, 0, 0, 1]

[1, 1, 0, 1, 0]

[1, 1, 0, 1, 1]

[1, 1, 1, 0, 0]

[1, 1, 1, 0, 1]

[1, 1, 1, 1, 0]

[1, 1, 1, 1, 1]

Frisbee”

brute force“ 1.4.53

Page 360: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# frisbee-bruteforce.py

#-------------------------------------------------------------------------------------------------------------

import sys

# Die Lange der Wurffolge n (int) wird von der Kommandozeile eingelesen.

n = int(sys.argv[1])

# m ist das 2d-Array mit den Wahrscheinlichkeiten m[z][s], dass Spieler z zu Spieler s wirft.

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ], [ 0.3, 0.05,0.1, 0.2, 0.35], [ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[0.15, 0.25,0.3, 0.3, 0.0 ], [ 0.1, 0.3,0.05, 0.1, 0.45] ]

# e ist das 2d-Array der gleichen Große wie m, bei der am Ende in e[z][s] die Wahrscheinlichkeit steht,

# dass von Spieler z nach n Wurfen das Frisbee bei Spieler s landet. Am Anfang sind alle Eintrage 0.

e = [0]*len(m)

for i in range(len(e)): e[i] = [0]*len(m)

# Es werden systematisch alle Wurffolgen betrachtet, die das Frisbee mit n Wurfen durchlaufen kann.

# Die erste Wurffolge besteht nur aus 0en, und die Wahrscheinlichkeit fur sie wird in e[0][0] eingetragen.

k = [0]*(n+1)

e[0][0] = m[0][0]**n

while min(k)<len(m)-1: # solange nicht die "großte" Wurffolge [4,4,4,4,4] durchlaufen wurde

for j in range(len(k)-1,-1,-1): # erzeuge die nachste Wurffolge

if k[j]<len(m)-1:

k[j] += 1

break

else: k[j] = 0

produkt = 1.0 # berechne die Wahrscheinlichkeit der Wurffolge

for i in range(len(k)-1):

produkt *= m[k[i]][k[i+1]]

e[k[0]][k[-1]] += produkt # addiere die Wkeit an der richtigen Stelle zu e hinzu

Frisbee”

brute force“ 1.4.54

Page 361: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----- Die Ausgabe des Ergebnisses.

# Es wird ausgegeben, mit welcher Wkeit das Frisbee bei welchem Spieler landet.

# Dazu wird das berechnete 2d-Array e schon ausgegeben.

print('''

Die Wahrscheinlichkeiten, dass das Frisbee mit %d Wurfen von x zu y kommt,

sind wie folgt:

''' % 2**n)

# Die erste Zeile der Ausgabe mit den Namen der Spalten.

print(' '*8 + '|', end='')

for i in range(len(e)): print(' zu %2d |' % i, end='')

print()

# Die zweite Zeile der Ausgabe: ein langer Strich.

print('-'*11*(len(e)+1))

# Das Array e wird zeilenweise ausgegeben.

for z in range(len(e)):

# Der Name der Zeile.

print(' von %2d |' % z, end='')

# Die Wahrscheinlichkeiten in den Spalten der Zeile.

for s in range(len(e[z])):

print( ' %.6f |' % e[z][s], end='')

print()

print()

#----------------------------------------------------------------------------------------------

Frisbee”

brute force“ 1.4.55

Page 362: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 frisbee-bruteforce.py 1

Die Wahrscheinlichkeiten, dass das Frisbee mit 1 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.100000 | 0.100000 | 0.300000 | 0.300000 | 0.200000 |

von 1 | 0.300000 | 0.050000 | 0.100000 | 0.200000 | 0.350000 |

von 2 | 0.200000 | 0.200000 | 0.200000 | 0.200000 | 0.200000 |

von 3 | 0.150000 | 0.250000 | 0.300000 | 0.300000 | 0.000000 |

von 4 | 0.100000 | 0.300000 | 0.050000 | 0.100000 | 0.450000 |

Frisbee”

brute force“ 1.4.56

Page 363: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 frisbee-bruteforce.py 1

Die Wahrscheinlichkeiten, dass das Frisbee mit 1 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.100000 | 0.100000 | 0.300000 | 0.300000 | 0.200000 |

von 1 | 0.300000 | 0.050000 | 0.100000 | 0.200000 | 0.350000 |

von 2 | 0.200000 | 0.200000 | 0.200000 | 0.200000 | 0.200000 |

von 3 | 0.150000 | 0.250000 | 0.300000 | 0.300000 | 0.000000 |

von 4 | 0.100000 | 0.300000 | 0.050000 | 0.100000 | 0.450000 |

$ python3 frisbee-bruteforce.py 4

Die Wahrscheinlichkeiten, dass das Frisbee mit 4 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.166275 | 0.189950 | 0.184938 | 0.215225 | 0.243613 |

von 1 | 0.166425 | 0.189669 | 0.181056 | 0.212862 | 0.249988 |

von 2 | 0.167450 | 0.189800 | 0.182550 | 0.213800 | 0.246400 |

von 3 | 0.168650 | 0.188694 | 0.187725 | 0.217325 | 0.237606 |

von 4 | 0.165725 | 0.192463 | 0.174656 | 0.208213 | 0.258944 |Frisbee

”brute force“ 1.4.56

Page 364: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 frisbee-bruteforce.py 4

Die Wahrscheinlichkeiten, dass das Frisbee mit 4 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.166275 | 0.189950 | 0.184938 | 0.215225 | 0.243613 |

von 1 | 0.166425 | 0.189669 | 0.181056 | 0.212862 | 0.249988 |

von 2 | 0.167450 | 0.189800 | 0.182550 | 0.213800 | 0.246400 |

von 3 | 0.168650 | 0.188694 | 0.187725 | 0.217325 | 0.237606 |

von 4 | 0.165725 | 0.192463 | 0.174656 | 0.208213 | 0.258944 |

$ python3 frisbee-bruteforce.py 8

Die Wahrscheinlichkeiten, dass das Frisbee mit 8 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.166898 | 0.190211 | 0.181854 | 0.213256 | 0.247781 |

von 1 | 0.166884 | 0.190230 | 0.181792 | 0.213213 | 0.247880 |

von 2 | 0.166890 | 0.190220 | 0.181828 | 0.213238 | 0.247825 |

von 3 | 0.166909 | 0.190193 | 0.181920 | 0.213302 | 0.247676 |

von 4 | 0.166861 | 0.190259 | 0.181692 | 0.213143 | 0.248046 |Frisbee

”brute force“ 1.4.56

Page 365: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 frisbee-bruteforce.py 8

Die Wahrscheinlichkeiten, dass das Frisbee mit 8 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.166898 | 0.190211 | 0.181854 | 0.213256 | 0.247781 |

von 1 | 0.166884 | 0.190230 | 0.181792 | 0.213213 | 0.247880 |

von 2 | 0.166890 | 0.190220 | 0.181828 | 0.213238 | 0.247825 |

von 3 | 0.166909 | 0.190193 | 0.181920 | 0.213302 | 0.247676 |

von 4 | 0.166861 | 0.190259 | 0.181692 | 0.213143 | 0.248046 |

Man sieht, dass die Wahrscheinlichkeiten in einer Spalte sich immer ahnlicher werden.Man weiß auch

”mathematisch“, dass diese Werte fur

”unendliche“ Wurffolgen gleich werden.

Wenn man nur an diesen Grenzwerten interessiert ist,wurde es auch reichen, nur die erste Zeile des Arrays auszurechnen.

Dafur braucht man dann nur 15 der Zeit, die man fur das ganze Array braucht.

Das ist aber auch noch sehr lang.

Frisbee”

brute force“ 1.4.56

Page 366: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Aufruf

python3 frisbee-bruteforce.py 16

dauert bereits sehr lange.

Bei 5 Spielern mussen 517 “ 762939453125 (726 Milliarden) Wurffolgen durchlaufen

und etwa 16 ¨ 517 “ 12207031250000 (12 Billionen) Multiplikationen gemacht werden.

Das dauert . . .

Frisbee”

brute force“ 1.4.57

Page 367: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Approximative Berechnung des Frisbee-Problems mittels Simulation

Jetzt wollen wir die erste Zeile der Matrix e experimentell bestimmen.Dazu schreiben wir ein Programm, das das Experiment

”Ein Frisbee wird beginnend mit Spieler 0 n-mal geworfen. Bei welchem Mitspieler landet es?“

sehr oft wiederholt (Experimentreihe) und zahlt, wie oft das Frisbee bei welchem Mitspieler landet.

In jedem Experiment wird also zufallig eine Wurffolge gewahlt.Die Anzahl der Wiederholungen des Experiments wird kleiner sein als die Anzahl aller Wurffolgen.Dadurch lauft das Programm schneller als frisbee-bruteforce.py,

liefert aber kein exaktes Ergebnis sondern nur eine naherungsweise exakte Losung(Approximation).

Damit das Ergebnis nicht”zu schlecht“ wird, werden die Wurffolgen so gewahlt,

dass Wurffolgen mit hoher Wahrscheinlichkeit eher gewahlt werden als solche mit geringerWahrscheinlichkeit.

Das erreichen wir, indem die einzelnen Wurfe mit ihren Wahrscheinlichkeiten simuliert werden.

Frisbee-Simulation 1.4.58

Page 368: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die”wichtigen“ Daten, die das Programms verarbeitet:

(1) die Wurfwahrscheinlichkeiten der Mitspieler stehen in einem 2d-Array m

(2) fur jeden Mitspieler i wird in ende[i] gezahlt, wie oft das Frisbee am Ende bei ihm landet(das entspricht der ersten Zeile des Arrays e in frisbee-bruteforce.py).

Der Ablauf eines Experiments und seine Auswertung:

das Frisbee liegt bei Spieler p=0wiederhole n-mal:

lasse p das Frisbee werfenes landet mit den in m[p] gegebenen Wahrscheinlichkeiten bei einem Spieler ip=i

ende[p] += 1

Frisbee-Simulation 1.4.59

Page 369: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme

dann wirft p zu iFrisbee-Simulation 1.4.60

Page 370: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme

dann wirft p zu iFrisbee-Simulation 1.4.60

Page 371: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme

dann wirft p zu iFrisbee-Simulation 1.4.60

Page 372: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

zu 0 zu 1 zu 2 zu 3 zu 4

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme

dann wirft p zu iFrisbee-Simulation 1.4.60

Page 373: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

zu 0 zu 1 zu 2 zu 3 zu 4

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme den Abschnitt i, in dem z in obiger Graphik liegt

dann wirft p zu iFrisbee-Simulation 1.4.60

Page 374: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

zu 0 zu 1 zu 2 zu 3 zu 4

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme die kleinste Zahl i mit z < m[p][0] + m[p][1] +...+ m[p][i]loooooooooooooooooooooooomoooooooooooooooooooooooon

dann wirft p zu iFrisbee-Simulation 1.4.60

Page 375: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie simuliert man einen zufalligen Wurf?

Beispiel: zu 0 zu 1 zu 2 zu 3 zu 4

mit Wahrscheinlichkeit

0 wirft 0.1 0.1 0.3 0.3 0.2

”Zeichne“ die Wahrscheinlichkeiten hintereinander auf dem Zahlenstrahl von 0 bis 1.

0.0 1.00.1 0.2 0.5 0.8

0.1 0.1 0.3 0.3 0.2

zu 0 zu 1 zu 2 zu 3 zu 4

Jedem Abschnitt ist ein Ziel des Wurfes zugeordnet.

Idee zur Simulation eines Wurfs von p:

ziehe eine Zufallszahl z aus r0, 1q

bestimme die kleinste Zahl i mit z < m[p][0] + m[p][1] +...+ m[p][i]loooooooooooooooooooooooomoooooooooooooooooooooooon

dann wirft p zu i sum(m[p][0:i+1])Frisbee-Simulation 1.4.60

Page 376: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# frisbee-simulation.py

#-----------------------------------------------------------------------------------------------------------------------

import sys, random

# ----- Die Experimentreihe wird vorbereitet. -----

n = int(sys.argv[1]) # Das Frisbee wird n-mal geworfen.

runden = int(sys.argv[2]) # Das Experiment wird runden-mal wiederholt.

# m ist die Matrix mit den Wahrscheinlichkeiten m[z][s], dass Spieler z zu Spieler s wirft.

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ], # Spieler 0 wirft mit Wkeit 0.1 zu Spieler 0 und 1,

[ 0.3, 0.05,0.1, 0.2, 0.35], # mit Wkeit 0.2 zu 2 und 3, und mit Wkeit 0.2 zu 4

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[0.15, 0.25,0.2, 0.3, 0.1 ],

[ 0.1, 0.3,0.05, 0.1, 0.45] ]

ende = [0]*len(m) # In ende[i] wird gezahlt, wie oft das Frisbee nach n Wurfen bei Spieler i landet.

# ----- Das Experimentreihe wird durchgefuhrt. Sie besteht aus runden vielen Experimenten. -----

for q in range(runden): # In jeder Runde wird das Frisbee n-mal geworfen und es wird nachgesehen, wo es am Ende landet.

p = 0 # Das Frisbee startet bei Spieler p=0.

for w in range(n): # Das Frisbee wird n-mal geworfen.

z = random.random() # Es wird eine Zufallszahl z aus 0..1 gezogen.

# Finde das kleinste i mit z < m[p][0] + m[p][1] +...+ m[p][i]

i = 0

while z>=sum(m[p][0:i+1]):

i += 1

# i ist nun die Nummer des Spielers, zu dem geworfen wird.

p = i

# Das Experiment wird ausgewertet.

ende[p] += 1 # Nach n Wurfen ist das Frisbee bei Spieler p gelandet.Frisbee-Simulation 1.4.61

Page 377: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# ----- Das Ergebnis der Experimentreihe wird ausgegeben. -----

#----- Die Ausgabe des Ergebnisses.

# Es wird ausgegeben, mit welcher Wkeit das Frisbee bei welchem Spieler landet.

# Dazu wird das berechnete Array ende schon ausgegeben.

print('Im Experiment kommt das Frisbee mit %d Wurfen von 0 zu y mit folgenden Wahrscheinlichkeiten:' % n)

# Die erste Zeile der Ausgabe enthalt die Namen der Spalten.

print(' '*8 + '|', end='')

for i in range(len(ende)): print(' zu %2d |' % i, end='')

print()

# Die zweite Zeile der Ausgabe ist ein langer Strich.

print('-'*11*(len(ende)+1))

# Das Array ende wird in der nachsten Zeile ausgegeben.

# Die erste Spalte der Zeile ist der Name der Zeile.

print(' von %2d |' % z, end='')

# Danach kommen die Spalten mit den Wahrscheinlichkeiten aus ende.

for s in range(len(ende)):

print( ' %.6f |' % (ende[s]/runden), end='')

print('\n\n')

#----------------------------------------------------------------------------------------------

Frisbee-Simulation 1.4.62

Page 378: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bei einem Wurf mussten die Ergebnisse der ersten Zeile der Matrix m entsprechen.

$ python3 frisbee-simulation.py 1 100000

Im Experiment kommt das Frisbee mit 1 Wurfen von 0 zu y mit folgenden Wahrscheinlichkeiten:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.100760 | 0.099420 | 0.302050 | 0.297050 | 0.200720 |

Frisbee-Simulation 1.4.63

Page 379: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir vergleichen die Ergebnisse der Simulation mit den exakten Ergebnissen:(2 Wurfe ergeben 52 Wurffolgen beginnend bei 0.)

$ python3 frisbee-simulation.py 2 100000

Im Experiment kommt das Frisbee mit 2 Wurfen von 0 zu y mit folgenden Wahrscheinlichkeiten:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.165280 | 0.209900 | 0.170950 | 0.218700 | 0.235170 |

$ python3 frisbee-bruteforce.py 2

Die Wahrscheinlichkeiten, dass das Frisbee mit 2 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.165000 | 0.210000 | 0.170000 | 0.220000 | 0.235000 |

von 1 | 0.130000 | 0.207500 | 0.172500 | 0.215000 | 0.275000 |

von 2 | 0.170000 | 0.180000 | 0.170000 | 0.220000 | 0.260000 |

von 3 | 0.185000 | 0.172500 | 0.175000 | 0.235000 | 0.232500 |

von 4 | 0.170000 | 0.195000 | 0.112500 | 0.175000 | 0.347500 |

Frisbee-Simulation 1.4.63

Page 380: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir vergleichen die Ergebnisse der Simulation mit den exakten Ergebnissen:(4 Wurfe ergeben 54

“ 625 Wurffolgen beginnend bei 0.)

$ python3 frisbee-simulation.py 4 100000

Im Experiment kommt das Frisbee mit 4 Wurfen von 0 zu y mit folgenden Wahrscheinlichkeiten:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.164750 | 0.193560 | 0.157380 | 0.210980 | 0.273330 |

$ python3 frisbee-bruteforce.py 4

Die Wahrscheinlichkeiten, dass das Frisbee mit 4 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.164075 | 0.192600 | 0.158113 | 0.211675 | 0.273538 |

von 1 | 0.164275 | 0.192119 | 0.155781 | 0.209813 | 0.278012 |

von 2 | 0.165250 | 0.192300 | 0.156600 | 0.210700 | 0.275150 |

von 3 | 0.165700 | 0.192019 | 0.158238 | 0.212200 | 0.271844 |

von 4 | 0.163975 | 0.194363 | 0.151381 | 0.206013 | 0.284269 |

Frisbee-Simulation 1.4.63

Page 381: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir vergleichen die Ergebnisse der Simulation mit den exakten Ergebnissen:(8 Wurfe ergeben 58

“ 390625 Wurffolgen beginnend bei 0.)

$ python3 frisbee-simulation.py 8 100000

Im Experiment kommt das Frisbee mit 8 Wurfen von 0 zu y mit folgenden Wahrscheinlichkeiten:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.166090 | 0.192200 | 0.154910 | 0.207010 | 0.279790 |

$ python3 frisbee-bruteforce.py 8

Die Wahrscheinlichkeiten, dass das Frisbee mit 8 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.164616 | 0.192819 | 0.155610 | 0.209724 | 0.277231 |

von 1 | 0.164610 | 0.192829 | 0.155584 | 0.209701 | 0.277276 |

von 2 | 0.164612 | 0.192823 | 0.155602 | 0.209717 | 0.277246 |

von 3 | 0.164617 | 0.192816 | 0.155622 | 0.209735 | 0.277210 |

von 4 | 0.164598 | 0.192842 | 0.155543 | 0.209664 | 0.277353 |

Frisbee-Simulation 1.4.63

Page 382: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir vergleichen die Ergebnisse der Simulation mit den exakten Ergebnissen:(10 Wurfe ergeben 510

“ 9765625 Wurffolgen beginnend bei 0.)

$ python3 frisbee-simulation.py 10 100000

Im Experiment kommt das Frisbee mit 10 Wurfen von 0 zu y mit folgenden Wahrscheinlichkeiten:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.163780 | 0.195780 | 0.155200 | 0.209890 | 0.275350 |

$ python3 frisbee-bruteforce.py 10

Die Wahrscheinlichkeiten, dass das Frisbee mit 10 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

------------------------------------------------------------------

von 0 | 0.164610 | 0.192827 | 0.155590 | 0.209706 | 0.277267 |

von 1 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 2 | 0.164610 | 0.192827 | 0.155589 | 0.209706 | 0.277269 |

von 3 | 0.164610 | 0.192826 | 0.155591 | 0.209708 | 0.277265 |

von 4 | 0.164608 | 0.192829 | 0.155583 | 0.209700 | 0.277280 |

Frisbee-Simulation 1.4.63

Page 383: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

Die 2-Wurf-Wege von 0 nach 2,

Frisbee”

dynamisch programmiert“ 1.4.64

Page 384: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

0.1 0.1 0.3 0.3 0.2

Die 2-Wurf-Wege von 0 nach 2,

die Wahrscheinlichkeiten jedes einzelnen Wurfes,

Frisbee”

dynamisch programmiert“ 1.4.64

Page 385: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

0.1 0.1 0.3 0.3 0.2

0.3 0.1 0.2 0.3 0.05

Die 2-Wurf-Wege von 0 nach 2,

die Wahrscheinlichkeiten jedes einzelnen Wurfes,

Frisbee”

dynamisch programmiert“ 1.4.64

Page 386: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

0.1 0.1 0.3 0.3 0.2

0.3 0.1 0.2 0.3 0.05

0.03 0.01 0.06 0.09 0.01

Die 2-Wurf-Wege von 0 nach 2,

die Wahrscheinlichkeiten jedes einzelnen Wurfes,

und die Wahrscheinlichkeiten jeder 2-Wurf-Folge.

Frisbee”

dynamisch programmiert“ 1.4.64

Page 387: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

0.1 0.1 0.3 0.3 0.2

0.3 0.1 0.2 0.3 0.05

0.03 0.01 0.06 0.09 0.01

0.2

Die 2-Wurf-Wege von 0 nach 2,

die Wahrscheinlichkeiten jedes einzelnen Wurfes,

und die Wahrscheinlichkeiten jeder 2-Wurf-Folge.

Die Wahrscheinlichkeit,von 0 mit 2 Wurfen bei 2 zu landen, istm[0][0]*m[0][2]+

m[0][1]*m[1][2]+

m[0][2]*m[2][2]+

m[0][3]*m[3][2]+

m[0][4]*m[4][2]Frisbee

”dynamisch programmiert“ 1.4.64

Page 388: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

0.1 0.1 0.3 0.3 0.2

0.3 0.1 0.2 0.3 0.05

0.03 0.01 0.06 0.09 0.01

0.2

Die 2-Wurf-Wege von 0 nach 2,

die Wahrscheinlichkeiten jedes einzelnen Wurfes,

und die Wahrscheinlichkeiten jeder 2-Wurf-Folge.

Die Wahrscheinlichkeit,von z mit 2 Wurfen bei s zu landen, istm[z][0]*m[0][s]+

m[z][1]*m[1][s]+

m[z][2]*m[2][s]+

m[z][3]*m[3][s]+

m[z][4]*m[4][s]Frisbee

”dynamisch programmiert“ 1.4.64

Page 389: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Exakte Berechnung des Frisbee-Problems mit Dynamischem Programmieren

Mit welcher Wahrscheinlichkeit landet das Frisbee mit zwei Wurfen von Spieler 0 bei Spieler 2?

m zu 0 zu 1 zu 2 zu 3 zu 4

von 0 0.1 0.1 0.3 0.3 0.2

von 1 0.3 0.05 0.1 0.2 0.35

von 2 0.2 0.2 0.2 0.2 0.2

von 3 0.15 0.25 0.2 0.3 0.1

von 4 0.1 0.3 0.05 0.1 0.45

0

0 1 2 3 4

2

0.1 0.1 0.3 0.3 0.2

0.3 0.1 0.2 0.3 0.05

0.03 0.01 0.06 0.09 0.01

0.2

Ein Programm zum Erzeugen eines Arrays neu der Große von m,in dem neu[z][s] die Wahrscheinlichkeit ist,dass das Frisbee in 2 Wurfen von z zu s kommt.

# Erzeuge das Array neu und fulle es mit 0en.

neu = [0]*len(m)

for i in range(len(m)): neu[i] = [0]*len(m)

# Fulle das Array neu mit den Wahrscheinlichkeiten.

for z in range(len(m)):

for s in range(len(m)):

for i in range(len(m)):

neu[z][s] += m[z][i]*m[i][s]

Die Wahrscheinlichkeit,von z mit 2 Wurfen bei s zu landen, istm[z][0]*m[0][s]+

m[z][1]*m[1][s]+

m[z][2]*m[2][s]+

m[z][3]*m[3][s]+

m[z][4]*m[4][s]Frisbee

”dynamisch programmiert“ 1.4.64

Page 390: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Matrix (2d-Array) m ist quadratisch – sie hat gleichviele Zeilen und Spalten.

Der Prozess, durch den die Matrix neu aus der Matrix m entsteht,

heißt (mathematisch) Quadrieren von m (Multiplikation von m mit m).

Sei m1 die Matrix, die man beim Quadrieren von m erhalt.

Dann ist m1rzsrss die Wahrscheinlichkeit, dass das Frisbee von z in 2 Wurfen zu s kommt.

Sei m2 die Matrix, die man beim Quadrieren von m1 erhalt.

Dann ist m2rzsrss die Wahrscheinlichkeit, dass das Frisbee von z in 4 Wurfen zu s kommt.

Sei m3 die Matrix, die man beim Quadrieren von m2 erhalt.

Dann ist m3rzsrss die Wahrscheinlichkeit, dass das Frisbee von z in 8 Wurfen zu s kommt.

Sei mi die Matrix, die man beim i-maligen Quadrieren von m erhalt.

Dann ist mirzsrss die Wahrscheinlichkeit, dass das Frisbee von z in 2i Wurfen zu s kommt.

Frisbee”

dynamisch programmiert“ 1.4.65

Page 391: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Diese Losungsidee nennt man”Dynamisches Programmieren“.

Dabei zerlegt man ein Problem (hier: das Frisbee-Problem fur Wurffolgen aus 2n Wurfen)

in Teilprobleme (hier ist es nur ein Teilproblem: das Frisbee-Problem fur Wurffolgen aus 2n´1

Wurfen).

und baut aus den Losungen der Teilprobleme die Losung fur das ganze Problem zusammen

(hier: durch Quadrieren).

Die Teilprobleme lost man wieder durch Zerlegen in weitere Teilprobleme,

bis man bei den unzerlegbaren Grundproblemen angekommen ist

(hier: das Frisbee-Problem fur Wurffolgen aus 20 Wurfen – dessen Losung ist durch m gegeben).

Da wir wissen, dass die Gesamtheit der betrachteten Teilprobleme bei Wurffolgen aus 2n Wurfen

die Probleme fur Wurffolgen aus 20, 21, 22, 23, . . . , 2n´1 Wurfen sind,

haben wir gleich mit dem Grundproblem (Wurffolgen aus 20 Wurfen) begonnen,

den Zerlegungsschritt nicht explizit gemacht und nur die Losungen der Teilprobleme schrittweise

(durch Quadrieren) aus deren Teillosungen zusammengebaut,

bis das ganze Problem gelost war. Frisbee”

dynamisch programmiert“ 1.4.66

Page 392: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen jetzt ein Programm schreiben,

das eine quadratische Matrix (z.B. m) n-mal quadriert und ausgibt.

Grobe Struktur des Programmes:

lies n von der Kommandozeile

die quadratische Matrix m wird im Programm angegeben

wiederhole n-mal:

quadriere m (das Ergebnis heißt dann wieder m)

Wie das Quadrieren einer (quadratischen) Matrix geht,

haben wir auf einer der vorigen Folien gesehen . . .

Frisbee”

dynamisch programmiert“ 1.4.67

Page 393: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# frisbee-quadrat.py

#------------------------------------------------------------------------------------------------------

# Eine Gruppe von Frisbee-Spielern wirft ein Frisbee mit bestimmten Wahrscheinlichkeiten herum.

# Finde heraus, mit welcher Wahrscheinlichkeit das Frisbee nach 2**n Wurfen bei den Mitspielern landet.

#------------------------------------------------------------------------------------------------------

import sys, random

#----- Die Vorbereitungen

# n wird von der Kommandozeile gelesen.

n = int(sys.argv[1])

# m ist die Matrix mit den Wahrscheinlichkeiten m[z][s],

# dass Spieler z zu Spieler s wirft.

m = [ [ 0.1, 0.1, 0.3, 0.3, 0.2 ], # Spieler 0 wirft mit Wkeit 0.1 zu Spieler 0 und 1,

[ 0.3, 0.05,0.1, 0.2, 0.35], # und mit Wkeit 0.2 zu anderen Spielern

[ 0.2, 0.2, 0.2, 0.2, 0.2 ],

[0.15, 0.25,0.3, 0.3, 0.0 ],

[ 0.1, 0.3,0.05, 0.1, 0.45] ]

#----- Das n-fache Quadrieren der Matrix

for q in range(n): # Es werden n Quadrierungen durchgefuhrt.

neu = [0]*len(m) # Das 2d-Array, das durch Quadrieren von m entsteht, heißt neu.

for i in range(len(m)): neu[i] = [0]*len(m) # Es wird zunachst mit lauter 0en gefullt.

# Nun wird an jede Stelle neu[z][s] die Summe der Produkte der j-ten Eintrage von Zeile z und Spalte s von m geschrieben.

for z in range(len(m)):

for s in range(len(m)):

for j in range(len(m[z])):

neu[z][s] += m[z][j]*m[j][s]

# Das Ergebnis des Quadrierens von m wird nun m genannt.

m = neu

Frisbee”

dynamisch programmiert“ 1.4.68

Page 394: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----- Die Ausgabe des Ergebnisses.

# Es wird ausgegeben, mit welcher Wkeit das Frisbee bei welchem Spieler landet.

# Dazu wird die berechnete Matrix schon ausgegeben.

print('''

Die Wahrscheinlichkeiten, dass das Frisbee mit %d Wurfen von x zu y kommt,

sind wie folgt:

''' % 2**n)

# Die erste Zeile der Ausgabe

print(' '*8 + '|', end='')

for i in range(len(m)): print(' zu %2d |' % i, end='')

print()

# Die zweite Zeile der Ausgabe

print('-'*9*(len(m)+1))

# Die Zeilen der Matrix.

for z in range(len(m)):

print(' von %2d |' % z, end='')

for s in range(len(m[z])):

print( ' %.4f |' % m[z][s], end='')

print()

print()

#-----------------------------------------------------------------------------------------

Frisbee”

dynamisch programmiert“ 1.4.69

Page 395: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bei einem Wurf kommen genau die in m eingetragenen Wahrscheinlichkeiten heraus.

$ python3 frisbee-quadrat.py 0

Die Wahrscheinlichkeiten, dass das Frisbee mit 1 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 0.100000 | 0.100000 | 0.300000 | 0.300000 | 0.200000 |

von 1 | 0.300000 | 0.050000 | 0.100000 | 0.200000 | 0.350000 |

von 2 | 0.200000 | 0.200000 | 0.200000 | 0.200000 | 0.200000 |

von 3 | 0.150000 | 0.250000 | 0.200000 | 0.300000 | 0.100000 |

von 4 | 0.100000 | 0.300000 | 0.050000 | 0.100000 | 0.450000 |

Frisbee”

dynamisch programmiert“ 1.4.70

Page 396: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bei”vielen“ Wurfen sieht man,

dass die Wahrscheinlichkeiten nicht mehr von der Startperson abhangig sind

und sich bei mehr Wurfen auch nicht mehr andern.

Diese Eigenschaft folgt aus Eigenschaften der Ausgangsmatrix m.

$ python3 frisbee-quadrat.py 2

Die Wahrscheinlichkeiten, dass das Frisbee mit 4 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 0.164075 | 0.192600 | 0.158113 | 0.211675 | 0.273537 |

von 1 | 0.164275 | 0.192119 | 0.155781 | 0.209813 | 0.278013 |

von 2 | 0.165250 | 0.192300 | 0.156600 | 0.210700 | 0.275150 |

von 3 | 0.165700 | 0.192019 | 0.158238 | 0.212200 | 0.271844 |

von 4 | 0.163975 | 0.194363 | 0.151381 | 0.206013 | 0.284269 |

Frisbee”

dynamisch programmiert“ 1.4.71

Page 397: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bei”vielen“ Wurfen sieht man,

dass die Wahrscheinlichkeiten nicht mehr von der Startperson abhangig sind

und sich bei mehr Wurfen auch nicht mehr andern.

Diese Eigenschaft folgt aus Eigenschaften der Ausgangsmatrix m.

$ python3 frisbee-quadrat.py 3

Die Wahrscheinlichkeiten, dass das Frisbee mit 8 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 0.164616 | 0.192819 | 0.155610 | 0.209724 | 0.277231 |

von 1 | 0.164610 | 0.192829 | 0.155584 | 0.209701 | 0.277276 |

von 2 | 0.164612 | 0.192823 | 0.155602 | 0.209717 | 0.277246 |

von 3 | 0.164617 | 0.192816 | 0.155622 | 0.209735 | 0.277210 |

von 4 | 0.164598 | 0.192842 | 0.155543 | 0.209664 | 0.277353 |

Frisbee”

dynamisch programmiert“ 1.4.71

Page 398: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bei”vielen“ Wurfen sieht man,

dass die Wahrscheinlichkeiten nicht mehr von der Startperson abhangig sind

und sich bei mehr Wurfen auch nicht mehr andern.

Diese Eigenschaft folgt aus Eigenschaften der Ausgangsmatrix m.

$ python3 frisbee-quadrat.py 4

Die Wahrscheinlichkeiten, dass das Frisbee mit 16 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 1 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 2 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 3 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 4 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

Frisbee”

dynamisch programmiert“ 1.4.71

Page 399: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bei”vielen“ Wurfen sieht man,

dass die Wahrscheinlichkeiten nicht mehr von der Startperson abhangig sind

und sich bei mehr Wurfen auch nicht mehr andern.

Diese Eigenschaft folgt aus Eigenschaften der Ausgangsmatrix m.

$ python3 frisbee-quadrat.py 10

Die Wahrscheinlichkeiten, dass das Frisbee mit 1024 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 1 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 2 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 3 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

von 4 | 0.164609 | 0.192827 | 0.155587 | 0.209704 | 0.277272 |

Das”kostet“ 10 ¨ 53 Multiplikationen

(statt mehr als 51025 mit dem vorigen Programm).

Frisbee”

dynamisch programmiert“ 1.4.71

Page 400: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Noch ein paar Bemerkungen zum Auftreten von Rundungsfehlern

Im Array m mit den Wurffwahrscheinlichkeiten

haben alle Zeilen die Summe 1, da jeder Spieler garantiert wirft.

Entsprechend mussen in allen Arrays m, die im Laufe des Programmes durch wiederholtes

Quadrieren berechnet werden, auch in allen Zeilen die Summe 1 haben,

da das Frisbee nach beliebiger Anzahl von Wurfen immer irgendwo ist.

Leider ist das”in der Realitat“ nicht so: durch Rundungsfehler beim Rechnen mit float-Werten

entstehen sehr schnell Zeilensumme ungleich 1.

”Unglucklicherweise“ sind diese Zeilensumme alle großer als 1 (und nie kleiner als 1),

so dass sich die Fehler nicht gegenseitig wieder”ausgleichen“.

Sie schaukeln sich vielmehr hoch, so dass die Zeilensummen immer großer werden.

Auf der folgenden Seite sieht die Summen von m[0] am Ende der Quadrier-Schleife uber q.

Frisbee”

dynamisch programmiert“ 1.4.72

Page 401: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Summen von m[0] am Ende der Quadrier-Schleife uber q.

q | sum(m[0])

-------------------------

0 | 1.0000000000000000

1 | 1.0000000000000002

2 | 1.0000000000000002

3 | 1.0000000000000007

4 | 1.0000000000000016

5 | 1.0000000000000029

6 | 1.0000000000000060

7 | 1.0000000000000120

8 | 1.0000000000000240

9 | 1.0000000000000480

10 | 1.0000000000000964

11 | 1.0000000000001925

12 | 1.0000000000003855

13 | 1.0000000000007707

14 | 1.0000000000015414

15 | 1.0000000000030829

16 | 1.0000000000061655

17 | 1.0000000000123310

18 | 1.0000000000246621

19 | 1.0000000000493245

q | sum(m[0])

-------------------------

20 | 1.0000000000986489

...

40 | 1.0001034463544389

...

50 | 1.1117369235921244

51 | 1.2359589872780812

52 | 1.5275946182334601

53 | 2.3335453176558305

54 | 5.4454337495534517

55 | 29.6527487207757652

56 | 879.2855066974686906

57 | 773143.0022882241755724

58 | 597750101987.2491455078125000

59 | 357305184425766786433024.0000000000000000

60 | 127666994817531223687511336360086608555387387904.0000000000000000

61 | 16298861565739543179307449317066935184232434397238380172718357830145135373363194300023206576128.0000000000000000

62 | 26565288833914163663899252402006839285301226789647187468341106234994526369159899865489080320.0000000000000000

63 | inf

64 | inf

Frisbee”

dynamisch programmiert“ 1.4.73

Page 402: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Dadurch sind die Ergebnisse eigentlich von Anfang an falsch und werden immer falscher.

Irgendwann sieht man dann sogar sofort, dass die Ergebnisse nicht stimmen konnen.

In der”Numerischen Mathematik“ kummert man sich (u.a.) darum,

wie man Rundungsfehler vermeiden/klein halten/abschatzen kann.

$ python3 frisbee-quadrat.py 54

Die Wahrscheinlichkeiten, dass das Frisbee mit 18014398509481984 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 0.384124 | 0.449971 | 0.363070 | 0.489354 | 0.647026 |

von 1 | 0.384124 | 0.449971 | 0.363070 | 0.489354 | 0.647026 |

von 2 | 0.384124 | 0.449971 | 0.363070 | 0.489354 | 0.647026 |

von 3 | 0.384124 | 0.449971 | 0.363070 | 0.489354 | 0.647026 |

von 4 | 0.384124 | 0.449971 | 0.363070 | 0.489354 | 0.647026 |

Frisbee”

dynamisch programmiert“ 1.4.74

Page 403: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Dadurch sind die Ergebnisse eigentlich von Anfang an falsch und werden immer falscher.

Irgendwann sieht man dann sogar sofort, dass die Ergebnisse nicht stimmen konnen.

In der”Numerischen Mathematik“ kummert man sich (u.a.) darum,

wie man Rundungsfehler vermeiden/klein halten/abschatzen kann.

$ python3 frisbee-quadrat.py 58

Die Wahrscheinlichkeiten, dass das Frisbee mit 288230376151711744 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | 127266.623445 | 149083.097887 | 120291.366770 | 162131.339229 | 214370.574957 |

von 1 | 127266.623445 | 149083.097887 | 120291.366770 | 162131.339229 | 214370.574957 |

von 2 | 127266.623445 | 149083.097887 | 120291.366770 | 162131.339229 | 214370.574957 |

von 3 | 127266.623445 | 149083.097887 | 120291.366770 | 162131.339229 | 214370.574957 |

von 4 | 127266.623445 | 149083.097887 | 120291.366770 | 162131.339229 | 214370.574957 |

Frisbee”

dynamisch programmiert“ 1.4.74

Page 404: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Dadurch sind die Ergebnisse eigentlich von Anfang an falsch und werden immer falscher.

Irgendwann sieht man dann sogar sofort, dass die Ergebnisse nicht stimmen konnen.

In der”Numerischen Mathematik“ kummert man sich (u.a.) darum,

wie man Rundungsfehler vermeiden/klein halten/abschatzen kann.

$ python3 frisbee-quadrat.py 70

Die Wahrscheinlichkeiten, dass das Frisbee mit 1180591620717411303424 Wurfen von x zu y kommt,

sind wie folgt:

| zu 0 | zu 1 | zu 2 | zu 3 | zu 4 |

----------------------------------------------------------------

von 0 | inf | inf | inf | inf | inf |

von 1 | inf | inf | inf | inf | inf |

von 2 | inf | inf | inf | inf | inf |

von 3 | inf | inf | inf | inf | inf |

von 4 | inf | inf | inf | inf | inf |

Frisbee”

dynamisch programmiert“ 1.4.74

Page 405: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

Wir kennen den Datentyp list (Array) jetzt genauer,

konnen 2-dimensionale Arrays erzeugen und auf ihre Elemente zugreifen,

haben gesehen,

wie man ein Netzwerk mit Ubergangswahrscheinlichkeiten durch 2d-Arrays modellieren kann,

haben verschiedene Algorithmen-Arten zur Losung eines Netzwerk-Problems gesehen,

und haben eine Vorstellung vom Sinn des Quadrierens von Matrizen.

1.4.75

Page 406: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Ein Farbungsexperiment

Ein Feld wird in lauter kleine Quadrate aufgeteilt, die zufallig gefarbt werden. (Im Beispiel sind es 10ˆ10kleine Quadrate und 4 Farben.)

Die Farbung am Anfang Die Farbung nach einer Runde

Anschließend wird rundenweise eine neue Farbung bestimmt. Dazu wird fur jedes Quadrat zufallig einerseiner direkten Nachbarn (oder es selbst) ausgewahlt und die Farbe wechselt zur Farbe des ausgewahltenNachbarn. (Man stellt sich die Rander des Feldes an den gegenuberliegenden Seiten zusammengeklebt vor,damit jedes Quadrat 8 Nachbarn hat). Diese Runden sollen solange wiederholt werden, bis alle Quadratedie gleiche Farbe haben. Passiert das? 1.4.76

Page 407: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# faerbungsexperiment.py

import sys, stdarray, random

n = int(sys.argv[1]) # die Seitenlange des Feldes

farben = int(sys.argv[2]) # die Anzahl der Farben fur die Quadrate

# Initialisiere das Array feld und farbe die Quadrate zufallig.

feld = stdarray.create2D(n, n, 0)

for z in range(n):

for s in range(n): feld[z][s] = random.randrange(0,farben)

# Bereite die Wiederholungen des Experiments vor.

rundenzaehler = 0

alleGleich = False # Wir gehen davon aus, dass nicht alle Quadrate die gleiche Farbe haben.

# Das Experiment wird solange wiederholt, bis alle Quadrate die gleiche Farbe haben.

while not alleGleich:

neu = stdarray.create2D(n,n,0) # das Array brauchen wir fur die Farben nach einer Runde

rundenzaehler += 1

alleGleich = True

# Schaue jedes Quadrat an.

for z in range(n):

for s in range(n):

# Wahle zufallig einen Nachbarn aus der direkten Nachbarschaft (randubergreifend).

nachbar_zeile = random.randrange(z-1,z+2) % n

nachbar_spalte = random.randrange(s-1,s+2) % n

# Die neue Farbe des Quadrats wird bestimmt.

neu[z][s] = feld[nachbar_zeile][nachbar_spalte]

# Falls eine zweite Farbe gefunden wird, wird alleGleich False (und bleibt es bis Rundenende).

alleGleich = alleGleich and neu[z][s]==neu[0][0]

# feld wird zum neu-berechneten Feld neu

feld = neu

# Gib die Dauer des Experiments aus.

print('Nach ' + str(rundenzaehler) + ' Runden haben alle Quadrate im Feld die gleiche Farbe.')

#-----------------------------------------------------------------------

1.4.77

Page 408: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 05

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und Schleifen

1.4 Arrays

1.5 Ein- und Ausgabestandard output

standard input

standard drawing

1.6 Dictionaries und Abschluss-Beispiel Page Rank

1.5.1

Page 409: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1.5 Ein- und Ausgabe

Die bisher benutzten Programme konnten Eingaben von der Kommandozeile lesen

und Text auf dem Bildschirm ausgeben.

Eingabe von der Kommandozeile

§ konnen uber das Array sys.argv[] benutzt werden

§ sind stets vom Typ string und mussen mittels Funktionen wie int() oder float() etc.

zum passenden Typ konvertiert werden.

Text-Ausgaben auf dem Bildschirm

§ konnen mit der Funktion print(x) ausgegeben werden

§ sind stets vom Typ string

§ bilden den Datenstrom standard output.

1.5.2

Page 410: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schematische Darstellung einfacher Ein- und Ausgabemoglichkeiten

programm.py

standard input

standard output

Kommandozeile

standard drawing

Wir kennen:

§ Kommandozeile

§ standard output (print)

Diese Vorlesung:

§ mehr zu str fur print

§ standard input

§ Verbindung von standard outputund standard input

Nachste Vorlesung:

§ standard drawing(mit Modul stddraw.py)

1.5.3

Page 411: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ausgabe mit print

standard output ist der ubliche Datenstrom fur die Ausgabe von Daten.

Zum Schreiben in den Datenstrom benutzt man die Funktion print(...).

Der Datenstrom wird auf dem Bildschirm angezeigt.

Man kann ihn außerhalb des Programms auch in eine Datei umlenken

oder zum Eingabe-Datenstrom fur ein anderes Programm machen.

print(x) schreibe String x gefolgt von einem Zeilenumbruch '\n' auf standard output

(Wenn x weggelassen wird, wird nur ein Zeilenumbruch geschrieben)

print(x, end='', flush=True) schreibe String x ohne Zeilenumbruch sofort auf standard output

(Wenn end='' bzw. flush=True weggelassen wird, dann

werden die Default-Argumente end='\n' bzw. flush=False eingesetzt .)

print(x, file=f) schreibe String x in die Datei mit Dateiobjekt fstandard output – print 1.5.4

Page 412: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Formatierte”

schone“ Ausgabe mit der %-Operation auf Strings

'Die Wurzel von %5d ist %7.4f.' % (n, r)

ergibt mit n=1000 und r=31.62276 den String

'Die Wurzel von 1000 ist 31.6228.'

standard output – print 1.5.5

Page 413: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Formatierte”

schone“ Ausgabe mit der %-Operation auf Strings

'Die Wurzel von %5d ist %7.4f.' % (n, r)

Tupel der einzusetzenden WerteFormat-String

ergibt mit n=1000 und r=31.62276 den String

'Die Wurzel von 1000 ist 31.6228.'

standard output – print 1.5.5

Page 414: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Formatierte”

schone“ Ausgabe mit der %-Operation auf Strings

'Die Wurzel von %5d ist %7.4f.' % (n, r)

Tupel der einzusetzenden WerteFormat-String

Konversion

ergibt mit n=1000 und r=31.62276 den String

'Die Wurzel von 1000 ist 31.6228.'

standard output – print 1.5.5

Page 415: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Formatierte”

schone“ Ausgabe mit der %-Operation auf Strings

'Die Wurzel von %5d ist %7.4f.' % (n, r)

Tupel der einzusetzenden WerteFormat-String

Konversion

Konversions-Code

ergibt mit n=1000 und r=31.62276 den String

'Die Wurzel von 1000 ist 31.6228.'

standard output – print 1.5.5

Page 416: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Formatierte”

schone“ Ausgabe mit der %-Operation auf Strings

'Die Wurzel von %5d ist %7.4f.' % (n, r)

Tupel der einzusetzenden WerteFormat-String

Konversion

Feldbreite

ergibt mit n=1000 und r=31.62276 den String

'Die Wurzel von 1000 ist 31.6228.'

standard output – print 1.5.5

Page 417: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Formatierte”

schone“ Ausgabe mit der %-Operation auf Strings

'Die Wurzel von %5d ist %7.4f.' % (n, r)

Tupel der einzusetzenden WerteFormat-String

Konversion

Genauigkeit

ergibt mit n=1000 und r=31.62276 den String

'Die Wurzel von 1000 ist 31.6228.'

standard output – print 1.5.5

Page 418: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Typ Konversions-Code Format-String Ergebnis

int d '%14d' % 1984 ergibt ' 1984'

'%-14d' % 1984 ergibt '1984 '

float f '%14.2f' % 1234.12345678 ergibt ' 1234.12'

'%.6f' % 1234.12345678 ergibt '1234.123457'

e '%14.4e' % 1234.12345678 ergibt ' 1.2341e+03'

string s '%14s' % 'Hello, World' ergibt ' Hello, World'

'%-14s' % 'Hello, World' ergibt 'Hello, World '

'%-14.5s' % 'Hello, World' ergibt 'Hello '

Statt eines Tupels aus einem Element kann man auch das Element ohne Klammern und Komma schreiben.

standard output – print 1.5.6

Page 419: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------

# formatierteAusgabe.py

#-----------------------------------------------------------------------------------------

# Beispiele fur die formatierte Ausgabe von int- und float-Werten.

#-----------------------------------------------------------------------------------------

import math

n = 1000

r = math.sqrt(n)

# Unformatierte Ausgabe:

# Gib int n und float r aus.

print('(1) Die Wurzel von ' + str(n) + ' ist ' + str(r) + '.')

# Formatierte Ausgaben:

# Gib int n und float r aus. Bei float werden standardmaßig 6 Nachkommastellen ausgegeben.

print( '(2) Die Wurzel von %d ist %f.' % (n, r) )

# Gib int n mit 5 Zeichen und float r mit 3 Nachkommastellen aus

# und fuge einen zusatzlichen Zeilenumbruch am Zeilenende ein.

print( '(3) Die Wurzel von %5d ist %.3f.' % (n, r) )

# Wenn Zeilenumbruche wie im Format-String gemacht werden sollen,

# dann muss man ihn in ''' einklammern.

print( '''(4) Die Wurzel von

%5d

ist %.3f.''' % (n, r) )

# (1) Die Wurzel von 1000 ist 31.622776601683793.

# (2) Die Wurzel von 1000 ist 31.622777.

# (3) Die Wurzel von 1000 ist 31.623.

# (4) Die Wurzel von

# 1000

# ist 31.623.

standard output – print 1.5.7

Page 420: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# Gib int n mit 5 Zeichen und float r mit 8 Zeichen und 3 Nachkommastellen aus.

print('(5) Die Wurzel von %5d ist %8.3f.' % (n, r))

# Gib int n mit 5 Zeichen und float r linksbundig mit 8 Zeichen und 3 Nachkommastellen aus

# und lasse den Zeilenumbruch am Ende der Ausgabe weg (geht nur in Python3).

print( '(6) Die Wurzel von %5d ist %-8.3f.' % (n, r) , end='' )

# Wenn die angegebene Zeichenzahl zu klein ist, wird sie ignoriert.

print( '(7) Die Wurzel von %2d ist %1.3f.' % (n, r) )

# (5) Die Wurzel von 1000 ist 31.623.

# (6) Die Wurzel von 1000 ist 31.623 .(7) Die Wurzel von 1000 ist 31.623.

standard output – print 1.5.8

Page 421: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Leite standard output in eine Datei um und nicht auf den Bildschirm

# wuerfele.py

#----------------------------------------------------------------------

# Lies n von der Kommandozeile und gib n Wurfe mit einem Wurfel aus.

#----------------------------------------------------------------------

import sys, random

n = int(sys.argv[1])

for i in range(n):

print(random.randrange(1,7))

#---------------------------------------------------------------------

# python3 wuerfele.py 4

# 4

# 4

# 1

# 2

Man kann das Programm beliebig viele Werte ausgeben lassen (Datenstrom).

Die Ausgabe erfolgt auf dem Bildschirm oder kann in eine Datei umgeleitet werden.

standard output – Ausgabeumleitung 1.5.9

Page 422: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Leite standard output in eine Datei um und nicht auf den Bildschirm

# wuerfele.py

#----------------------------------------------------------------------

# Lies n von der Kommandozeile und gib n Wurfe mit einem Wurfel aus.

#----------------------------------------------------------------------

import sys, random

n = int(sys.argv[1])

for i in range(n):

print(random.randrange(1,7))

#---------------------------------------------------------------------

# python3 wuerfele.py 100000 > wuerfelergebnisse.txt

# (...Die Ausgabe wird in Datei wuerfelergebnisse.txt geschrieben...)

#

#

#

Man kann das Programm beliebig viele Werte ausgeben lassen (Datenstrom).

Die Ausgabe erfolgt auf dem Bildschirm oder kann in eine Datei umgeleitet werden.

standard output – Ausgabeumleitung 1.5.9

Page 423: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Schreibe mit print in eine Datei

# wuerfele-datei.py

#-------------------------------------------------

# Gib 10 Wurfel-Wurfe in die Datei wuerfe.txt aus.

#-------------------------------------------------

import random

# Offne die Datei wuerfe.txt zum Schreiben.

# D.h. erzeuge ein Datei-Objekt dafur.

ausgabe = open('wuerfe.txt', 'w')

for i in range(n):

print(random.randrange(1,7), file=ausgabe)

# Schließe die Datei wuerfe.txt.

ausgabe.close()

#-------------------------------------------------

$ python3 wuerfele-datei.py

$ cat wuerfe.txt

6

3

4

6

3

5

6

1

5

3

standard output – Ausgabeumleitung 1.5.10

Page 424: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Standard input

Standard input ist ein Datenstrom, der von einem Programm als Eingabe gelesen werden.

Der Datenstrom kommt ublicherweise von der Tastatur,

kann aber auch aus einer Datei auf standard input umgeleitet werden

oder die Ausgabe eines”zuvor“ gestarteten Programms sein.

sys.stdin.readline(): gibt die nachste Zeile (Typ str) von standard input zuruck

sys.stdin.readlines(): gibt ein Array aus Strings zuruck

das aus allen Zeilen von standard input besteht

for z in sys.stdin: durchlauft alle Zeilen z (Typ str) von standard input,

bis zum Dateiende <Strg-d>.

standard input 1.5.11

Page 425: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------------------

# mittelwert4.py

#----------------------------------------------------------------------------------------------------------------------

# Von der Kommandozeile wird n eingelesen. Anschließend wird die Eingabe von n int-Werten von standard input erwartet.

# Sie werden mit sys.stdin.readline() gelesen. Der Mittelwert der Werte wird ausgegeben.

#----------------------------------------------------------------------------------------------------------------------

import sys

# Die Anzahl der zu lesenden Werte wird von der Kommandozeile gelesen.

n = int(sys.argv[1])

# Es werden n int-Werte von standard input gelesen und aufsummiert.

summe = 0

for i in range(n):

# Gib die Eingabeaufforderung aus (kein Zeilenwechsel, Ausgabe sofort).

print( 'Eingabe %d von %d: ' % (i+1,n), end='', flush=True )

# Die nachste Zeile wird von standard input gelesen (string s), und der eingelesene Wert wird aufsummiert.

zeile = sys.stdin.readline()

summe += int(zeile)

# Der Mittelwert wird ausgegeben.

print( '\nDer Mittelwert ist %.2f.' % (summe/n) )

#----------------------------------------------------------------------------------------------------------------------

# python3 mittelwert4.py 5

# Eingabe 1 von 5: 1

# Eingabe 2 von 5: 22

# Eingabe 3 von 5: 333

# Eingabe 4 von 5: 4444

# Eingabe 5 von 5: 55555

#

# Der Mittelwert ist 12071.00. standard input 1.5.12

Page 426: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------------------

# mittelwert4.py

#----------------------------------------------------------------------------------------------------------------------

# Von der Kommandozeile wird n eingelesen. Anschließend wird die Eingabe von n int-Werten von standard input erwartet.

# Sie werden mit sys.stdin.readline() gelesen. Der Mittelwert der Werte wird ausgegeben.

#----------------------------------------------------------------------------------------------------------------------

import sys

# Die Anzahl der zu lesenden Werte wird von der Kommandozeile gelesen.

n = int(sys.argv[1])

# Es werden n int-Werte von standard input gelesen und aufsummiert.

summe = 0

for i in range(n):

# Gib die Eingabeaufforderung aus (kein Zeilenwechsel, Ausgabe sofort).

print( 'Eingabe %d von %d: ' % (i+1,n), end='', flush=True )

# Die nachste Zeile wird von standard input gelesen (string s), und der eingelesene Wert wird aufsummiert.

zeile = sys.stdin.readline()

summe += int(zeile)

# Der Mittelwert wird ausgegeben.

print( '\nDer Mittelwert ist %.2f.' % (summe/n) )

#----------------------------------------------------------------------------------------------------------------------

# python3 mittelwert4.py 4

# Eingabe 1 von 4: 1 2 3 4

# Traceback (most recent call last):

# File "mittelwert4.py", line 17, in <module>

# summe += int(s)

# ValueError: invalid literal for int() with base 10: '1 2 3 4'

standard input 1.5.12

Page 427: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------

# mittelwert5.py

#----------------------------------------------------------------------------------------------------

# Die Eingabe von int-Werten von standard input wird erwartet und mit sys.stdin.readlines() gelesen.

# Der Mittelwert der Werte wird ausgegeben.

#----------------------------------------------------------------------------------------------------

import sys

# Es werden int-Werte von standard input gelesen und aufsummiert.

# Die Anzahl der eingelesenen Werte wird gezahlt.

summe = 0

zaehler = 0

print('Bitte geben Sie int-Werte ein.')

# Lies alle Zeilen von standard input in das Array zeilen.

alleZeilen = sys.stdin.readlines()

# Gehe durch alle Zeilen, die von standard input stammen.

for zeile in alleZeilen:

# Wandele die Zeile in eine Zahl um und summiere sie auf.

summe += int(zeile)

zaehler += 1

# Der Mittelwert wird ausgegeben.

print( '\nEs wurden %d Werte eingegeben.' % zaehler )

print( 'Der Mittelwert ist %.2f.' % (summe/zaehler) )

$ python3 mittelwert5.py

Bitte geben Sie int-Werte ein.

1

2

3

4

<Strg-d>

Es wurden 4 Werte eingegeben.

Der Mittelwert ist 2.50.

standard input 1.5.13

Page 428: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------------------------------

# mittelwert6.py

#--------------------------------------------------------------------------------------------------------

# Die Eingabe von int-Werten von standard input wird erwartet.

# und mit for zeile in sys.stdin: gelesen.

# Der Mittelwert der Werte wird ausgegeben.

#--------------------------------------------------------------------------------------------------------

import sys

# Es sollen int-Werte von standard input gelesen und aufsummiert werden,

# und ihre Anzahl wird gezahlt.

summe = 0

zaehler = 0

print('Bitte geben Sie int-Werte ein.')

# Gehe durch alle Zeilen von standard input,

# summiere die eingegebenen Zahlen auf und zahle sie.

for zeile in sys.stdin:

summe += int(zeile)

zaehler += 1

# Der Mittelwert wird ausgegeben.

print( '\nEs wurden %d Werte eingegeben.' % zaehler )

print( 'Der Mittelwert ist %.2f.' % (summe/zaehler) )

#--------------------------------------------------------

# python3 mittelwert6.py

# Bitte geben Sie int-Werte ein.

# 1

# 2

# 3

# 4

# <Strg-d>

# Es wurden 4 Werte eingegeben.

# Der Mittelwert ist 2.50.

standard input 1.5.14

Page 429: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Direkt aus einer Datei lesen

Statt von standard input mittels sys.stdin

kann man auch direkt aus einer Datei lesen.

Die Datei muss zuerst zum Lesen geoffnet werden.

Das dazu erzeugte Datei-Objekt kann einer Variablen zugewiesen werden.

eingabedatei = open('dateiname', 'r')

Nun kann eingabedatei genau wie sys.stdin verwendet werden.

Wenn das Lesen beendet ist, muss die Datei wieder geschlossen werden.

eingabedatei.close()

standard input 1.5.15

Page 430: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Datei lesen mittels Umleitung auf standard input

Bisher haben wir den Eingabestrom standard input an der Tastatur erzeugt.

Die Umleitung der Eingabe erlaubt auch das Lesen einer Datei (ohne das Programm zu andern).Die Beispiele zeigen:– standard input ist die Tastatur– standard input ist eine Datei (Eingabeumleitung <)– standard input ist die Ausgabe eines Programms (Ausgabeweiterleitung |)

# python3 mittelwert5.py

# Bitte geben Sie int-Werte ein.

# 1

# 2

# 3

# 4

# <Strg-d>

# Es wurden 4 Werte eingegeben.

# Der Mittelwert ist 2.50.

standard input – Eingabeumleitung 1.5.16

Page 431: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Datei lesen mittels Umleitung auf standard input

Bisher haben wir den Eingabestrom standard input an der Tastatur erzeugt.

Die Umleitung der Eingabe erlaubt auch das Lesen einer Datei (ohne das Programm zu andern).Die Beispiele zeigen:– standard input ist die Tastatur– standard input ist eine Datei (Eingabeumleitung <)– standard input ist die Ausgabe eines Programms (Ausgabeweiterleitung |)

# python3 mittelwert5.py

# Bitte geben Sie int-Werte ein.

# 1

# 2

# 3

# 4

# <Strg-d>

# Es wurden 4 Werte eingegeben.

# Der Mittelwert ist 2.50.

# python3 mittelwert5.py < wuerfelergebnisse.txt

# Bitte geben Sie int-Werte ein.

#

# Es wurden 10000 Werte eingegeben.

# Der Mittelwert ist 3.50.

standard input – Eingabeumleitung 1.5.16

Page 432: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Datei lesen mittels Umleitung auf standard input

Bisher haben wir den Eingabestrom standard input an der Tastatur erzeugt.

Die Umleitung der Eingabe erlaubt auch das Lesen einer Datei (ohne das Programm zu andern).Die Beispiele zeigen:– standard input ist die Tastatur– standard input ist eine Datei (Eingabeumleitung <)– standard input ist die Ausgabe eines Programms (Ausgabeweiterleitung |)

# python3 mittelwert5.py

# Bitte geben Sie int-Werte ein.

# 1

# 2

# 3

# 4

# <Strg-d>

# Es wurden 4 Werte eingegeben.

# Der Mittelwert ist 2.50.

# python3 mittelwert5.py < wuerfelergebnisse.txt

# Bitte geben Sie int-Werte ein.

#

# Es wurden 10000 Werte eingegeben.

# Der Mittelwert ist 3.50.

# python3 wuerfele.py 2222 | python3 mittelwert5.py

# Bitte geben Sie int-Werte ein.

#

# Es wurden 2222 Werte eingegeben.

# Der Mittelwert ist 3.48.standard input – Eingabeumleitung 1.5.16

Page 433: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Abschlussbeispiel: Entwicklung der Tageshochsttemperaturen in Jena seit 1824

im Jahresdurchschnitt

Der Deutsche Wetterdienst (DWD) stellt Messwerte als csv-Dateien zur Verfugung.

csv . . . comma separated values (im Beispiel hier sind es Semikolons)

siehe ftp://ftp-cdc.dwd.de/pub/CDC/observations_germany/climate/daily/kl/historical/

Die erste Zeile der Datei enthalt eine Erklarung zu den Spalten der weiteren Zeilen,von denen jede einen Messwert etc. enthalt.

STATIONS_ID;MESS_DATUM;QN_3; FX; FM;QN_4; RSK;RSKF; SDK;SHK_TAG; NM; VPM; PM; TMK; UPM; TXK; TNK; TGK;eor

2444;18240101;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 990.70; 4.5;-999; 5.5; 1.6;-999;eor

2444;18240102;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 984.00; 5.0;-999; 6.5; 3.1;-999;eor

2444;18240103;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 997.80; 3.5;-999; 5.0; 1.9;-999;eor

2444;18240104;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 1019.50; 1.2;-999; 2.3; -2.9;-999;eor

2444;18240105;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 1021.30; -0.8;-999; 3.0; -3.8;-999;eor

2444;18240106;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 1013.80; -3.7;-999; 0.0; -10.4;-999;eor

...

2444;18241231;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 1013.30; 6.6; 62.00; 7.0; 0.6;-999;eor

2444;18250101;-999;-999;-999; 2; -999;-999;-999;-999; -999; -999; 1008.00; 8.2; 54.00; 9.1; 2.1;-999;eor

...

2444;20181231;-999;-999;-999; 3; 0.5; 4;-999; 0; -999; 9.0; -999; 7.0; 89.83; 8.6; 6.4; 5.0;eor

Wetterdaten vom DWD 1.5.17

Page 434: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

www.dwd.de

-1-

DATENSATZBESCHREIBUNG Historische tägliche Stationsbeobachtungen (Temperatur, Druck, Niederschlag,Sonnenscheindauer, etc.) für Deutschland Version v006 Zitieren mit: DWD Climate Data Center (CDC): Historische tägliche Stationsbeobachtungen (Temperatur, Druck,

Niederschlag, Sonnenscheindauer, etc.) für Deutschland, Version v006, 2018.

ZWECK Diese historischen Daten sind qualitätsgeprüfte Messwerte und Beobachtungen. Sie stammen aus Stationen des DWD und rechtlichund qualitativ gleichgestellten Partnernetzstationen. Umfangreiche Stationsmetadaten (Stationsverlegungen, Instrumentenwechsel,Wechsel der Bezugszeit, Änderungen in den Algorithmen) werden mitgeliefert.

KONTAKT Deutscher WetterdienstCDC - Vertrieb Klima und UmweltFrankfurter Straße 13563067 OffenbachTel.: + 49 (0) 69 8062-4400Fax.: + 49 (0) 69 8062-4499Mail: [email protected]

DATENBESCHREIBUNG Räumliche Abdeckung Stationen in Deutschland

Zeitliche Abdeckung 01.01.1781 - 31.12.2017

Zeitliche Auflösung täglich

Format(e) Die Stationsbeobachtungen (produkt_*.txt) sind gemeinsam mit den Stationsmetadaten gezippt.

Die Stationsmetadaten werden sowohl als *.txt als auch als *.html bereitgestellt. Die DateiMetadaten_Parameter* enthält eine Liste der an dieser Station gemessenen Parameter (dasParameterportfolio), mit Beginn, Ende, dazugehörigen Einheiten, Messvorschriften, Formeln, Terminenund Zeiteinheiten (z.B. MOZ oder UTC) , die der Stations_Id und dem aktuellen Stationsnamen zugeordnetwerden. Die Gerätehistorie ist den meteorologischen Parametern entsprechend sortiert (siehe DateiMetadaten_Geraete*). Dort ist die zeitliche Geschichte der Sensor- bzw Geberhöhen, Gerätetypen undMessverfahren, gemeinsam mit der zeitlichen Geschichte der Stationsnamen enthalten. Die Stations_idist unveränderlich. Um erfolgte Änderung der Stationsnamen bei einzelnen Stationen zu dokumentierten,gibt es zur Übersicht zusätzlich die Datei Metadaten_Stationsname*. Die geographische Metadaten derStation (geografische Länge und Breite, Stationshöhe) sind in Metadaten_Geographie*.txt erfasst, undder Stations_id und dem aktuellem Stationsnamen zugeordnet. Alle Informationen sind für jede Station ineinem einzigen zip-File *_[Stations_id]_[von]_[bis]_hist.zip bereitgestellt. Eine Übersicht über alle Stationen,Startdatum und evtl. Enddatum der Station ist in der Stationsliste hinterlegt. Diese Liste umfasst derVollständigkeit halber nicht nur die hier abgegebenen Stationen, sondern auch jene, deren Urheberrechtenicht beim DWD liegen. Beim angegebenen Kontakt können für Stationen, die in dieser Liste auftreten, fürdie aber kein *.zip veröffentlicht ist, die Nutzungsbedingungen erfragt werden.

Parameter Die Parameterportfolios der einzelnen Stationen sind unterschiedlich umfangreich. Insgesamt stehen in

produkt*.txt folgende Parameter zur Verfügung:STATIONS_ID StationsidentifikationsnummerMESS_DATUM Datum yyyymmdd

www.dwd.de

-2-

QN_3 Qualitätsniveau der nachfolgendenSpalten

code siehe Absatz"Qualitätsinformation"

FX Tagesmaximum Windspitze m/sFM Tagesmittel Windgeschwindigkeit m/sQN_4 Qualitätsniveau der nachfolgenden

Spaltencode siehe Absatz"Qualitätsinformation"

RSK tägliche Niederschlagshöhe mmRSKF Niederschlagsform

0 kein Niederschlag (konventionelleoder automatische Messung),entspricht WMO Code-Zahl 10

1 nur Regen (in historischen Datenvor 1979)

4 Form nicht bekannt, obwohlNiederschlag gemeldet

6 nur Regen; flüssiger Niederschlagbei automatischen Stationen,entspricht WMO Code-Zahl 11

7 nur Schnee; fester Niederschlag beiautomatischen Stationen, entsprichtWMO Code-Zahl 12

8 Regen und Schnee (und/oderSchneeregen); flüssiger und festerNiederschlag bei automatischenStationen, entspricht WMO Code-Zahl 13

9 fehlender Wert oderNiederschlagsform nicht feststellbarbei automatischer Messung,entspricht WMO Code-Zahl 15

SDK tägliche Sonnenscheindauer hSHK_TAG Tageswert Schneehöhe cmNM Tagesmittel des Bedeckungsgrades 1/8VPM Tagesmittel des Dampfdruckes hPaPM Tagesmittel des Luftdrucks hPaTMK Tagesmittel der Temperatur °CUPM Tagesmittel der Relativen Feuchte %TXK Tagesmaximum der Lufttemperatur

in 2m Höhe°C

TNK Tagesminimum der Lufttemperaturin 2m Höhe

°C

TGK Minimum der Lufttemperatur amErdboden in 5cm Höhe

°C

eor Ende data recordFehlwerte sind mit -999 gekennzeichnet. Es ist zu beachten, dass sich innerhalb einer Zeitreihe derZeitbezug hh ändern kann, und zwar je nach Parameter, und je nach Station. Zum Beispiel ist dasZeitintervall der täglichen Niederschlagshöhe in modernerer Zeit als 6 Uhr bis 6 Uhr Folgetag definiert,dies war in früheren Jahren oft anders. Wann eine Zeitangabe in wahrer Ortszeit (WOZ), GesetzlicherZeit (GZ), Mittlerer Ortszeit (MOZ), Mitteleuropäischer Zeit (MEZ) oder Universal Time (UTC) vorliegt,ist in den Dateien Metadaten_Parameter* hinterlegt. Der Wert der Windgeschwindigkeit beruht vor derAutomatisierung z.T auf Schätzwerten der Beobachter (Beaufortskala), welche anschliessend in m/skonvertiert wurden, und ist hier nur als Hilfsgröße gegeben.

Unsicherheiten Heutzutage sind die Stationen nach den WMO-Vorschriften eingerichtet und betrieben. Somit werden

die lokalen Effekte besonders gering gehalten. Je weiter in die Geschichte zurückgegangen wird, destoweniger waren solche vereinheitlichten Vorschriften etabliert. Je nach Anwendung sollten mögliche lokale,regionale und zeitlich sich ändernde Einflüsse untersucht werden, die orts- und parameterspezifischsein können. Unsicherheitsfaktoren für die Langzeitstabilität sind (1) Änderungen in der Stationshöhebei Stationsverschiebungen (besonders für Wind und Temperatur), genaue Angaben dazu sind inden stationsweise gezippten Dateien Metadaten_Geographie* enthalten; (2) Änderungen in denBeobachtungszeiten ("Terminwerte"), aus denen das Tagesmittel berechnet wurde, und (3) Änderungenin der Rechenvorschrift. Genaue Angaben zu (2) und (3) sind in den stationsweise gezippten DateienMetadaten_Parameter* enthalten. Unsicherheiten sind auch zu erwarten von (4) Änderungen in denInstrumenten, siehe Dateien Metadaten_Geraete* und möglicherweise auch aus (5) unterschiedlichenQualitätsprüfverfahren (Behrendt et al., 2011), durch (6) Fehler in Übermittlung oder Software, (7)Beobachterwechsel, und (8) andere, siehe Freydank, 2014 .

Wetterdaten vom DWD 1.5.18

Page 435: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wert Format SpalteStation 0Mess-Datum YYYYMMDD 1Tages-Niederschlagmenge 6Tages-Sonnenscheindauer 8Tagesmittel des Luftdrucks 12Tagesmittel der Temperatur 13Tagesmaximum der Lufttemperatur in 2m Hohe 15Tagesminimum der Lufttemperatur in 2m Hohe 16Tagesminimum der Lufttemperatur in 5cm Hohe 17

Wetterdaten vom DWD 1.5.19

Page 436: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen

die Jahresdurchschnitte der Tageshochst- und -tiefsttemperaturen in Jena

fur jedes Jahr seit 1824 berechnen.

Daraus wollen wir”gleitende“ Durchschnitte uber k Jahre berechnen.

(Der gleitende Durchschnitt fur 1960 uber 5 Jahre ist der Durchschnitt von 1956,. . .,1960.)

(Die Aufgaben fur Hochst- und Tiefsttemperaturen werden getrennt gelost.)

Die Aufgabe teilen wir in drei Teile auf.

Teil 1: filtere aus der DWD-Datei die relevanten Daten heraus, filter-DWD.py

z.B. alle Tageshochsttemperaturen fur jedes Jahr

Teil 2: berechne daraus die Jahresdurchschnittstemperaturen jahres-mittel.py

Teil 3: berechne daraus die gleitenden Durchschnitte kjahres-mittel.py

Die Ausgabe eines Teils dient als Eingabe des nachsten Teils.

Diese”Schnittstelle“ (Form der ausgegebenen/zu lesenden Daten) muss vereinbart werden.

Durchschnittstemperaturen berechnen 1.5.20

Page 437: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

DWD-Datei

python3 filter-DWD.py 15

python3 jahres-mittel.py

python3 kjahres-mittel.py 5

1832 11.35

1833 11.33

...

2017 15.43

2018 15.64

Durchschnittstemperaturen berechnen 1.5.21

Page 438: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Filterung der Eingabedatei mit filter-DWD.py

Das Programm erhalt ein int n und die DWD-Datei als Eingabe von standard input

STATIONS_ID;MESS_DATUM;QN_3;FX;FM;QN_4;RSK;RSKF;SDK;SHK_TAG;NM;VPM; PM;TMK;UPM;TXK;TNK; TGK;eor

2444;18240101;-999;-999;-999; 2;-999;-999;-999;-999;-999;-999; 990.70; 4.5;-999; 5.5; 1.6;-999;eor

2444;18240102;-999;-999;-999; 2;-999;-999;-999;-999;-999;-999; 984.00; 5.0;-999; 6.5; 3.1;-999;eor

2444;18240103;-999;-999;-999; 2;-999;-999;-999;-999;-999;-999; 997.80; 3.5;-999; 5.0; 1.9;-999;eor

...

2444;18241231;-999;-999;-999; 2;-999;-999;-999;-999;-999;-999;1013.30; 6.6;62.00;7.0; 0.6;-999;eor

2444;18250101;-999;-999;-999; 2;-999;-999;-999;-999;-999;-999;1008.00; 8.2;54.00;9.1; 2.1;-999;eor

...

2444;20181231;-999;-999;-999; 3; 0.5; 4;-999; 0; -999; 9.0; -999; 7.0; 89.83; 8.6; 6.4; 5.0;eor

und produziert fur n “ 15 die Ausgabe-Zeilen

1824 5.5 6.5 5.0 ... 7.0

1825 9.1 ... ...

...

2018 ... ... 8.6

In jeder Zeile steht zuerst das Jahr und darauf folgen die Werte in Spalte n fur das Jahr.Die Werte sind jeweils durch genau ein Leerzeichen getrennt.

Durchschnittstemperaturen berechnen – Teil 1 1.5.22

Page 439: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Funktionen aus dem Modul str, die wir brauchen werden

str.split(string, trenner) teilt einen String uberall dort,

wo das Zeichen trenner in ihm vorkommt, und gibt diese Teile als Array zuruck.

Beispiel: In

zeile = '2444;18240101; 5.5; 1.6;-999;eor'

felder = str.split(zeile, ';')

ist felder das Array

[ '2444', '18240101', ' 5.5', ' 1.6', '-999', 'eor' ]

str.strip(string) gibt einen String zuruck, der aus string entsteht, indem

alle Leerzeichen, Zeilenumbruche etc. am Anfang und am Ende entfernt werden.

Bsp.: str.strip(' ab c \n ') ergibt 'ab c'.

Durchschnittstemperaturen berechnen – Teil 1 1.5.23

Page 440: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

In der DWD-Datei stehen die relevanten Informationen zum Berechnen der

Jahresdurchschnittshochsttemperaturen in Spalte 1 (Datum) und Spalte 15 (Tagesmaximum).

2444;18240101;-999;-999;-999; 2;-999;-999;-999;-999;-999;-999; 990.70; 4.5;-999; 5.5; 1.6;-999;eor

Sei zeile obiger String.

Dann ist str.split(zeile, ';') das Array

['2444', '18240101', '-999', '-999', '-999', ' 2', '-999', '-999', '-999', '-999', '-999', '-999',

' 990.70', ' 4.5', '-999', ' 5.5', ' 1.6', '-999', 'eor' ]

Sei felder = str.split(zeile, ';') obiges Array.

Das Jahr '1824' ist felder[1][0:4] (Typ str),

und der gesuchte Temperaturwert '5.5' ist str.strip(felder[15]) (Typ str).

Durchschnittstemperaturen berechnen – Teil 1 1.5.24

Page 441: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-------------------------------------------------------------------------------------------------------------------------

# filter-DWD.py

#-------------------------------------------------------------------------------------------------------------------------

# Auf der Kommandozeile wird ein int n erwartet, auf standard input wird eine Wetterdatei vom DWD erwartet.

# Jede ihrer Zeilen enthalt die Messwerte einer Station von einem Tag. Die Eintrage in der Zeile sind durch ';' getrennt.

# Spalte 1 enthalt das Datum in der Form YYYYMMDD, Spalte 15 enthalt die Hochsttemperatur des Tages (z.B. 12.7)

# und Spalte 16 enthalt die Tiefsttemperatur des Tages (z.B. -2.3). Fehlt ein Messwert, so steht -999 an der Stelle.

# Die Ausgabe geht auf standard output. Sie enthalt fur jedes Jahr eine Zeile mit dem Jahr (z.B 1899)

# und den Werten von Spalte n fur dieses Jahr. Zwischen zwei Eintragen in einer Zeile steht ein ' '.

# Fehl-Eintrage (-999) werden nicht ausgegeben.

#-------------------------------------------------------------------------------------------------------------------------

import sys

n = int(sys.argv[1]) # n ist der Index der Spalte, die aus der Datei herausgefiltert werden soll.

sys.stdin.readline() # Lies die erste Zeile und ignoriere sie. Sie enthalt nur Informationen uber die Spalten.

jahr = '0' # Die Datei beginnt mit einem Eintrag fur einen Tag in einem Jahr>0.

for zeile in sys.stdin: # Gehe alle weiteren Zeilen von standard input durch.

felder = str.split(zeile, ';') # Trenne die Zeile in ihre Spalten auf.

j = felder[1][0:4] # Das Jahr des Messwerts steht in den ersten vier Zeichen von Spalte 1.

messwert = str.strip(felder[n]) # Der auszugebende Messwert steht in Spalte n. Wir entfernen storende Zeichen daraus.

if messwert=='-999': continue # Falls es ein Fehl-Eintrag ist, dann wird mit dem Eintrag nichts weiter gemacht.

if j != jahr: # Falls das Jahr des Messwerts nicht das Jahr des vorangegangenen Messwerts ist,

print('\n' + j, end='') # dann beginnen wir in der Ausgabe eine neue Zeile mit dem Jahr.

jahr = j

print(' ' + messwert, end='') # Schließlich wird ein Leerzeichen gefolgt vom Messwert ausgegeben (ohne Zeilenumbr.).

Durchschnittstemperaturen berechnen – Teil 1 1.5.25

Page 442: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Hochsttemperaturen der vergangenen Jahre . . .

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt

1824 5.5 6.5 5.0 2.3 3.0 ... 6.3 10.1 8.8 3.4 7.0

1825 9.1 9.4 5.3 7.9 -0.3 ... -2.8 0.3 4.0 6.1 7.9

...

...

2018 11.5 7.4 10.3 9.4 9.4 ... 5.7 9.7 4.7 7.5 8.3 8.6

. . . und die Niederschlagmengen:

python3 filter-DWD.py 6 < Jena-Wetterdaten.txt

1826 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

1827 0.1 0.5 0.1 0.0 1.4 0.8 0.0 1.6 0.6 1.6 1.5 9.8 ... 0.0 0.0 0.4 1.2 0.0 0.0

...

...

2018 1.2 6.4 2.5 1.2 0.2 6.4 1.0 0.0 0.1 0.0 0.2 1.1 ... 0.1 0.0 0.1 4.5 0.0 0.5

Durchschnittstemperaturen berechnen – Teil 1 1.5.26

Page 443: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 2: Berechnung der Durchschnittswerte pro Jahres-Zeile jahres-mittel.py

Das Programm soll die Ausgabe von filter-DWD.py zeilenweise lesen.

Jede Zeile besteht aus dem Jahr gefolgt von den Messwerten,jeweils durch ein Leerzeichen getrennt.

zeile = '1825 2.1 4.4 0.0 1.6 -4.8 ... 1.3 -0.9 -3.1 -1.3 -10.6 -8.4'

Mit str.split(zeile, ' ') machen wir daraus ein Array felder:

[ '1825', '2.1', '4.4', ...'-3.1', '-1.3', '-10.6', '-8.4' ]

felder[0] ist dann das Jahr,und felder[1], felder[2], ... sind die Werte, deren Mittelwert berechnet wird.

Die Ausgabe soll dann aus Zeilen mit Jahr und Mittelwert bestehen:

1824 13.50

1825 13.38

1826 13.27

1827 12.92

1828 13.07

... Durchschnittstemperaturen berechnen – Teil 1 1.5.27

Page 444: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# jahres-mittel.py

#------------------------------------------------------------------------------------------------------------------------

# Es wird von standard input eine Datei aus Zeilen erwartet,

# die mit einer Jahreszahl beginnen, auf die die Messwerte des Jahres folgen.

# Die Eintrage in jeder Zeile sind durch ' ' getrennt. (Das ist das Format, das von filter-DWD.py erzeugt wird.)

# Die Ausgabe auf standard output besteht aus Zeilen mit # der Jahreszahl und dem Durchschnitt der Messwerte des Jahres.

#------------------------------------------------------------------------------------------------------------------------

import sys

# Lies alle Zeilen von standard input.

for zeile in sys.stdin:

# Ignoriere Leerzeilen (die Ausgabe von filter-DWD.py beginnt mit einer Leerzeile).

if zeile == '\n': continue

# Teile die Zeile am Trennzeichen ' ' in ein Array felder auf.

# Das Jahr steht dann in felder[0]; die Messwerte stehen in felder[1], ... , felder[len(felder)-1], d.h. in felder[1:]

felder = str.split(zeile, ' ')

# Jahre mit zuwenig Messwerten werden aussortiert.

if len(felder)<360: continue

# Die Durchschnittsberechnung der Messwerte des Jahres wird vorbereitet.

summe = 0.0

# Die Summe der Messwerte des Jahres wird berechnet.

for s in felder[1:]:

summe += float(s)

# Das Jahr und der Mittelwert der Messwerte des Jahres werden ausgegeben.

print( '%s %.2f' % (felder[0], summe/(len(felder)-1)) )

#------------------------------------------------------------------------------------------------------------------------

Durchschnittstemperaturen berechnen – Teil 1 1.5.28

Page 445: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die durchschnittlichen Hochsttemperaturen:

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py

1824 13.50

1825 13.38

1826 13.27

1827 12.92

...

2015 16.42

2016 15.60

2017 15.85

2018 16.94Die durchschnittlichen Tiefsttemperaturen:

python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py

1824 3.59

1825 5.39

1826 5.19

...

2015 6.28

2016 6.23

2017 6.40

2018 6.53

Durchschnittstemperaturen berechnen – Teil 1 1.5.29

Page 446: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die durchschnittlichen Hochsttemperaturen:

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py

1824 13.50

1825 13.38

1826 13.27

1827 12.92

...

2015 16.42

2016 15.60

2017 15.85

2018 16.94Die durchschnittlichen Tiefsttemperaturen:

python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py

1824 3.59

1825 5.39

1826 5.19

...

2015 6.28

2016 6.23

2017 6.40

2018 6.53

Durchschnittstemperaturen berechnen – Teil 1 1.5.29

Page 447: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 3: Berechnung der k-Jahre Durchschnittswerte kjahres-mittel.py

Das Programm soll die Ausgabe von jahres-durchschnitte.py zeilenweise lesen.

Jede Zeile besteht aus dem Jahr gefolgt von dem Durchschnittswertdurch ein Leerzeichen getrennt.

1824 13.50

1825 13.38

1826 13.27

1827 12.92

1828 13.07

1829 13.23

1830 12.88

...

Durchschnittstemperaturen berechnen – Teil 1 1.5.30

Page 448: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir betrachten die Idee zur Berechnung von 4-Jahres-Durchschnitten.Wir benutzen 4-stellige Arrays werte und int-Variable letzter.werte enthalt die Daten der letzten 4 Jahre,und letzter ist der Index des letzten Jahres in den beiden Arrays.Am Anfang wird das Array mit den Werten der ersten 4 Jahren gefullt.

Index 0 1 2 3

Jahr 1824 1825 1826 1827

werte 13.50 13.38 13.27 12.92

letzter: 3

Daraus kann der 4-Jahres-Durchschnitt fur 1827 berechnet werden.

Durchschnittstemperaturen berechnen – Teil 1 1.5.31

Page 449: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir betrachten die Idee zur Berechnung von 4-Jahres-Durchschnitten.Wir benutzen 4-stellige Arrays werte und int-Variable letzter.werte enthalt die Daten der letzten 4 Jahre,und letzter ist der Index des letzten Jahres in den beiden Arrays.Am Anfang wird das Array mit den Werten der ersten 4 Jahren gefullt.

Index 0 1 2 3

Jahr 1824 1825 1826 1827

werte 13.50 13.38 13.27 12.92

letzter: 3

Daraus kann der 4-Jahres-Durchschnitt fur 1827 berechnet werden.

Fur 1828 braucht man den Wert von 1824 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1828 an die Stelle mit Index letzter.Damit ist der Wert von 1824 uberschrieben.

Index 0 1 2 3

jahre 1828 1825 1826 1827

werte 13.07 13.38 13.27 12.92

letzter: 0

Daraus kann der 4-Jahres-Durchschnitt fur 1828 berechnet werden.

Durchschnittstemperaturen berechnen – Teil 1 1.5.31

Page 450: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Fur 1828 braucht man den Wert von 1824 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1828 an die Stelle mit Index letzter.Damit ist der Wert von 1824 uberschrieben.

Index 0 1 2 3

jahre 1828 1825 1826 1827

werte 13.07 13.38 13.27 12.92letzter: 0

Daraus kann der 4-Jahres-Durchschnitt fur 1828 berechnet werden.

Fur 1829 braucht man den Wert von 1825 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1829 an die Stelle mit Index letzter.Damit ist der Wert von 1825 uberschrieben.

Index 0 1 2 3

jahre 1828 1829 1826 1827

werte 13.07 10.47 13.27 12.92letzter: 1

Daraus kann der 4-Jahres-Durchschnitt fur 1829 berechnet werden.

Durchschnittstemperaturen berechnen – Teil 1 1.5.31

Page 451: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Fur 1829 braucht man den Wert von 1825 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1829 an die Stelle mit Index letzter.Damit ist der Wert von 1825 uberschrieben.

Index 0 1 2 3

jahre 1828 1829 1826 1827

werte 13.07 10.47 13.27 12.92letzter: 1

Daraus kann der 4-Jahres-Durchschnitt fur 1829 berechnet werden.

Fur 1830 braucht man den Wert von 1826 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1830 an die Stelle mit Index letzter.Damit ist der Wert von 1826 uberschrieben.

Index 0 1 2 3

jahre 1828 1829 1830 1827

werte 13.07 10.47 12.25 12.92letzter: 2

Daraus kann der 4-Jahres-Durchschnitt fur 1830 berechnet werden.

Durchschnittstemperaturen berechnen – Teil 1 1.5.31

Page 452: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Fur 1830 braucht man den Wert von 1826 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1830 an die Stelle mit Index letzter.Damit ist der Wert von 1826 uberschrieben.

Index 0 1 2 3

jahre 1828 1829 1830 1827

werte 13.07 10.47 12.25 12.92letzter: 2

Daraus kann der 4-Jahres-Durchschnitt fur 1830 berechnet werden.

Fur 1831 braucht man den Wert von 1827 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1831 an die Stelle mit Index letzter.Damit ist der Wert von 1827 uberschrieben.

Index 0 1 2 3

jahre 1828 1829 1830 1831

werte 13.07 10.47 12.25 13.37letzter: 3

Daraus kann der 4-Jahres-Durchschnitt fur 1830 berechnet werden.

Durchschnittstemperaturen berechnen – Teil 1 1.5.31

Page 453: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Fur 1831 braucht man den Wert von 1827 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1831 an die Stelle mit Index letzter.Damit ist der Wert von 1827 uberschrieben.

Index 0 1 2 3

jahre 1828 1829 1830 1831

werte 13.07 10.47 12.25 13.37letzter: 3

Daraus kann der 4-Jahres-Durchschnitt fur 1830 berechnet werden.

Fur 1832 braucht man den Wert von 1828 nicht mehr.Man setzt letzter eins hoher (modulo 4)und schreibt den Wert von 1832 an die Stelle mit Index letzter.Damit ist der Wert von 1828 uberschrieben.

Index 0 1 2 3

jahre 1832 1829 1830 1831

werte 12.42 10.47 12.25 13.37letzter: 0

Daraus kann der 4-Jahres-Durchschnitt fur 1830 berechnet werden.

. . .Durchschnittstemperaturen berechnen – Teil 1 1.5.31

Page 454: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# kjahres-mittel.py

#------------------------------------------------------------------------------------------------------------------------

# Von der Kommandozeile wird int k eingelesen.

# Es wird von standard input eine Datei aus Zeilen erwartet, die aus einer Jahreszahl und einem float Messwert bestehen.

# Die Ausgabe auf standard output

# besteht aus Zeilen mit der Jahreszahl und dem Durchschnitt der Messwerte der k vorigen Jahre.

#------------------------------------------------------------------------------------------------------------------------

import sys

k = int(sys.argv[1])

# Wir benutzen werte als Ringpuffer fur die letzten k Jahres-Werte.

werte = [0]*k

# Am Anfang wird der Ringpuffer mit den ersten k-1 Werten gefullt.

for i in range(k-1):

zeile = sys.stdin.readline()

felder = str.split(zeile,' ')

werte[i] = float(felder[1])

# letzter speichert den Index des letzten Eintrages.

letzter = k-2

# Gehe durch alle Zeilen von standard input.

for zeile in sys.stdin:

# zeile wird fur den nachsten Eintrag in den Ringpuffern "auseinandergenommen".

felder = str.split(zeile,' ')

jahr = felder[0]

letzter = (letzter+1)%k

werte[letzter] = float(felder[1])

# Das Jahr und der Mittelwert der letzten k Jahre werden ausgegeben.

print( '%s %.2f' % (jahr, sum(werte)/k) )

Durchschnittstemperaturen berechnen – Teil 1 1.5.32

Page 455: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | python3 kjahres-mittel.py 9

1832 11.35

1833 11.33

1834 11.48

1835 11.48

1836 11.45

1837 11.56

1838 11.40

...

2011 15.29

2012 15.27

2013 15.22

2014 15.36

2015 15.45

2016 15.40

2017 15.43

2018 15.64

Durchschnittstemperaturen berechnen – Teil 1 1.5.33

Page 456: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassungstandard input und standard output

Wir haben gesehen, wie Daten

§ von der Tastatur eingelesen undauf dem Bildschirm ausgegeben werden konnen

§ aus Dateien eingelesen und in Dateien geschrieben werden konnen(Eingabeumleitung < bzw. open(dateiname, 'r'); Ausgabeumleitung > bzw. open(dateiname, 'w') etc.)

§ als Ausgabe eines Programms weitergereicht und als Eingabe eines anderen Programmsbenutzt werden konnen (Piping |).

Wir haben gesehen, wie eine großere Aufgabein kleinere und einfachere Aufgaben aufgeteilt werden kann.

Die kleineren Aufgaben sind unabhangig voneinander.Jede Aufgabe hat ein festes Format fur die Eingabe- und Ausgabe-Daten.

1.5.34

Page 457: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 06

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und Schleifen

1.4 Arrays

1.5 Ein- und Ausgabestandard output

standard input

standard drawing

1.6 Dictionaries und Abschluss-Beispiel Page Rank

1.5.35

Page 458: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1.5.3 Graphische Ausgabe mit stddraw

Das Modul stddraw.py bietet einfache Mittel zur graphischen Ausgabe.

Damit konnen z.B. Graphiken gemalt oder bewegte Bilder dargestellt werden.

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | \

python3 jahres-mittel.py | \

python3 kjahres-mittel.py 30 | \

python3 male-kurve-mit-achsen.py 1830 2022 0 20

python3 kugel-3.py 2 0.05 0.095

1.5.36

Page 459: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Ausgabe mit dem Modul stddraw (standard drawing)

Das Modul stddraw ermoglicht das Malen auf eine”abstrakte“ Leinwand aus Punkten

(Standardgroße 512ˆ 512 Pixel).

p0, 0q

p1, 1q

x-Achse

y-A

chse

Jeder Punkt auf der Leinwand hat Koordinaten px , yq mit Standard 0 ď x , y ď 1.

Es konnen Punkte, Linien, Kreise, Rechtecke etc. gemalt werden.

Die Koordinaten der Eckpunkte der Leinwand konnen verandert werden . . .

stddraw – Einfuhrung 1.5.37

Page 460: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Ausgabe mit dem Modul stddraw (standard drawing)

Das Modul stddraw ermoglicht das Malen auf eine”abstrakte“ Leinwand aus Punkten

(Standardgroße 512ˆ 512 Pixel).

p0, 0q

p1, 1q

x-Achse

y-A

chse

p0.5, 0.3q

Jeder Punkt auf der Leinwand hat Koordinaten px , yq mit Standard 0 ď x , y ď 1.

Es konnen Punkte, Linien, Kreise, Rechtecke etc. gemalt werden.

Die Koordinaten der Eckpunkte der Leinwand konnen verandert werden . . .

stddraw – Einfuhrung 1.5.37

Page 461: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Ausgabe mit dem Modul stddraw (standard drawing)

Das Modul stddraw ermoglicht das Malen auf eine”abstrakte“ Leinwand aus Punkten

(Standardgroße 512ˆ 512 Pixel).

p´2.5, 3.2q

p2, 5q

x-Achse

y-A

chse

p0.25, 3.74q

Jeder Punkt auf der Leinwand hat Koordinaten px , yq mit Standard 0 ď x , y ď 1.

Es konnen Punkte, Linien, Kreise, Rechtecke etc. gemalt werden.Die Koordinaten der Eckpunkte der Leinwand konnen verandert werden . . .

stddraw – Einfuhrung 1.5.37

Page 462: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zeichne ein Dreieck

Aufgabe:Zeichne ein Dreieck mit den Eckpunkten p0, 0q, p1, 0q, und p0.5,

?3.0{2q,

und zeichne einen Punkt in die Mitte des Dreiecks.

Wir mussen also die Linienvon p0, 0q nach p1, 0q,von p1, 0q nach p0.5,

?3.0{2q, und

von p0.5,?

3.0{2q nach p0, 0qund einen Punkt p0.5,

?3.0{6q zeichnen und das gemalte Bild anzeigen.

Das geht mit folgenden stddraw-Funktionen.

stddraw.line(x0, y0, x1, y1) male eine Linie von px0, y0q zu px1, y1q

stddraw.point(x, y) male einen Punkt an px , yq

stddraw.show(t) zeige das Bild im standard-drawing-Fenster und

warte t Millisekunden;

falls t weggelassen wird, dann

warte, bis das Fenster vom Nutzer geschlossen wirdstddraw – Einfuhrung 1.5.38

Page 463: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------

# dreieck.py

#--------------------------------------------------------------------

# Zeichne mit stddraw ein Dreieck mit den Eckpunkten (0,0), (1,0)

# und (0.5, sqrt(3.0)/2), und einen Punkt in die Mitte des Dreiecks.

#--------------------------------------------------------------------

import math

import stddraw

t = math.sqrt(3.0)/2

# Male eine Linie von (0,0) nach (1,0).

stddraw.line(0, 0, 1, 0)

# Male eine Linie von (0,0) nach (0.5,t).

stddraw.line(0.0, 0.0, 0.5, t)

# Male eine Linie von (0.5,t) nach (1,0).

stddraw.line(0.5, t, 1, 0)

# Male einen Punkt an (0.5, t/3).

stddraw.point(0.5, t/3)

# Zeige das Bild an.

stddraw.show()

#--------------------------------------------------------------------

# python3 dreieck.py

$ python3 dreieck.py

stddraw – Einfuhrung 1.5.39

Page 464: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------

# dreieck.py

#--------------------------------------------------------------------

# Zeichne mit stddraw ein Dreieck mit den Eckpunkten (0,0), (1,0)

# und (0.5, sqrt(3.0)/2), und einen Punkt in die Mitte des Dreiecks.

#--------------------------------------------------------------------

import math

import stddraw

t = math.sqrt(3.0)/2

# Male eine Linie von (0,0) nach (1,0).

stddraw.line(0, 0, 1, 0)

# Male eine Linie von (0,0) nach (0.5,t).

stddraw.line(0.0, 0.0, 0.5, t)

# Male eine Linie von (0.5,t) nach (1,0).

stddraw.line(0.5, t, 1, 0)

# Male einen Punkt an (0.5, t/3).

stddraw.point(0.5, t/3)

# Zeige das Bild an.

stddraw.show()

#--------------------------------------------------------------------

# python3 dreieck.py

$ python3 dreieck.py

stddraw – Einfuhrung 1.5.39

Page 465: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anderung von StandardwertenLeinwandgroße, Skalierung der Achsen, Stiftdicke, Stiftfarbe

Leinwandgroße:

stddraw.setCanvasSize(w, h) setze die Leinwandgroße auf w -mal-h Pixel

(Default fur w (Breite) und h (Hohe) ist 512)

Skalierung der Achsen:

stddraw.setXscale(x0, x1) setze den Bereich der x-Koordinaten auf x0 ď x ď x1

(Default ist x0 “ 0 und x1 “ 1)

stddraw.setYscale(y0, y1) setze den Bereich der y -Koordinaten auf y0 ď y ď y1

(Default ist y0 “ 0 und y1 “ 1)

Stiftdicke und -farbe:

stddraw.setPenRadius(r) setze die Stiftdicke auf r

(Default-Wert von r ist 0.005)

stddraw.setPenColor(c) setzt die Farbe des Stiftes auf c; c kann z.B. stddraw.BLUE sein

mit Farben BLACK, BLUE, CYAN, DARK GRAY, GRAY, GREEN, LIGHT GRAY, MAGENTA, ORANGE, PINK, RED, WHITE, YELLOWstddraw – Einfuhrung 1.5.40

Page 466: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------------------------

# dreieck-bunt.py

#--------------------------------------------------------------------------------------------------

# Zeichne das Dreieck mit dem Punkt wie in dreieck.py.

# Verandere die Standardparameter Leinwandgroße, Skalierung der Achsen, Stiftdicke und Stiftfarbe.

#--------------------------------------------------------------------------------------------------

import math, stddraw

# Setze die Leinwandgroße und die Skalierung der Achsen.

stddraw.setCanvasSize(800,800) # Leinwandgroße

stddraw.setXscale(-0.3,1.3) # Skalierung der x-Achse

stddraw.setYscale(-0.3,1.3) # Skalierung der y-Achse

stddraw.setPenRadius(0.01) # andere die Stiftdicke

stddraw.line(0, 0, 1, 0) # male die Linie von (0,0) nach (1,0)

t = math.sqrt(3.0)/2

stddraw.setPenColor(stddraw.BLUE) # andere die Stiftfarbe

stddraw.line(0, 0, 0.5, t) # male die Linie von (0,0) nach (0.5,t)

stddraw.setPenRadius(0.05) # andere die Stiftdicke

stddraw.setPenColor(stddraw.RED) # andere die Stiftfarbe

stddraw.line(0.5, t, 1, 0) # male die Linie von (0.5,t) nach (1,0)

stddraw.setPenRadius(0.1) # andere die Stiftdicke

stddraw.setPenColor(stddraw.CYAN) # andere die Stiftfarbe

stddraw.point(0.5, t/3) # male einen Punkt an (0.5, t/3)

stddraw.show() # zeige das Bild an

$ python3 dreieck-bunt.py

stddraw – Einfuhrung 1.5.41

Page 467: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------------------------------------------

# dreieck-bunt.py

#--------------------------------------------------------------------------------------------------

# Zeichne das Dreieck mit dem Punkt wie in dreieck.py.

# Verandere die Standardparameter Leinwandgroße, Skalierung der Achsen, Stiftdicke und Stiftfarbe.

#--------------------------------------------------------------------------------------------------

import math, stddraw

# Setze die Leinwandgroße und die Skalierung der Achsen.

stddraw.setCanvasSize(800,800) # Leinwandgroße

stddraw.setXscale(-0.3,1.3) # Skalierung der x-Achse

stddraw.setYscale(-0.3,1.3) # Skalierung der y-Achse

stddraw.setPenRadius(0.01) # andere die Stiftdicke

stddraw.line(0, 0, 1, 0) # male die Linie von (0,0) nach (1,0)

t = math.sqrt(3.0)/2

stddraw.setPenColor(stddraw.BLUE) # andere die Stiftfarbe

stddraw.line(0, 0, 0.5, t) # male die Linie von (0,0) nach (0.5,t)

stddraw.setPenRadius(0.05) # andere die Stiftdicke

stddraw.setPenColor(stddraw.RED) # andere die Stiftfarbe

stddraw.line(0.5, t, 1, 0) # male die Linie von (0.5,t) nach (1,0)

stddraw.setPenRadius(0.1) # andere die Stiftdicke

stddraw.setPenColor(stddraw.CYAN) # andere die Stiftfarbe

stddraw.point(0.5, t/3) # male einen Punkt an (0.5, t/3)

stddraw.show() # zeige das Bild an

$ python3 dreieck-bunt.py

stddraw – Einfuhrung 1.5.41

Page 468: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Darstellung der Jenaer Jahresdurchschnittstemperaturen (Teil 1)

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py

liefert Ausgabe

1824 13.50

1825 13.38

1826 13.27

1827 12.92

1828 13.07

1829 10.47

...

stddraw – Messwerte als Punkte darstellen 1.5.42

Page 469: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Darstellung der Jenaer Jahresdurchschnittstemperaturen (Teil 1)

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py

liefert Ausgabe

1824 13.50

1825 13.38

1826 13.27

1827 12.92

1828 13.07

1829 10.47

...

Aufgabe: Wir fassen jede Zeile als x- und y -Wert eines Punktes aufund wollen alle diese Punkte zeichnen.

Die x-Koordinaten sind im Bereich 1824 . . . 2018,

und die y -Koordinaten sind im Bereich 0 . . . 20.

stddraw – Messwerte als Punkte darstellen 1.5.42

Page 470: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Darstellung der Jenaer Jahresdurchschnittstemperaturen (Teil 1)

Aufgabe: Wir fassen jede Zeile als x- und y -Wert eines Punktes aufund wollen alle diese Punkte zeichnen.

Die x-Koordinaten sind im Bereich 1824 . . . 2018,und die y -Koordinaten sind im Bereich 0 . . . 20.

Das Programm soll fur unterschiedliche”Punktarten“ arbeiten (Hochst-, Tiefsttemperatur, . . . )

Ablauf des Programms:

Lies den Bereich der x- und y -Koordinaten von der Kommandozeile.Lies alle Punkte von standard input,

male sie auf die Leinwandund zeige die Leinwand an.

stddraw – Messwerte als Punkte darstellen 1.5.42

Page 471: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Grundsatzliche Alternativen fur”Lies alle Punkte von standard input,

und male sie auf die Leinwand“

(A) Male jeden Punkt direkt nach dem Einlesen.

fur jede Eingabezeile (Zeile “Punkt):bestimme den entsprechenden Punktmale ihn

(B) zuerst: lies alle Punkte einund speichere sie

danach: male jeden Punkt

fur jede Eingabezeile (Zeile “Punkt):speichere den entsprechenden Punkt

fur jeden gespeicherten Punkt:male ihn

stddraw – Messwerte als Punkte darstellen 1.5.43

Page 472: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Grundsatzliche Alternativen fur”Lies alle Punkte von standard input,

und male sie auf die Leinwand“

(A) Male jeden Punkt direkt nach dem Einlesen.

fur jede Eingabezeile (Zeile “Punkt):bestimme den entsprechenden Punktmale ihn

(B) zuerst: lies alle Punkte einund speichere sie

danach: male jeden Punkt

fur jede Eingabezeile (Zeile “Punkt):speichere den entsprechenden Punkt

fur jeden gespeicherten Punkt:male ihn

stddraw – Messwerte als Punkte darstellen 1.5.43

Page 473: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Grundsatzliche Alternativen fur”Lies alle Punkte von standard input,

und male sie auf die Leinwand“

(A) Male jeden Punkt direkt nach dem Einlesen.

fur jede Eingabezeile (Zeile “Punkt):bestimme den entsprechenden Punktmale ihn

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert,y_wert)

(B) zuerst: lies alle Punkte einund speichere sie

danach: male jeden Punkt

fur jede Eingabezeile (Zeile “Punkt):speichere den entsprechenden Punkt

fur jeden gespeicherten Punkt:male ihn

stddraw – Messwerte als Punkte darstellen 1.5.43

Page 474: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Grundsatzliche Alternativen fur”Lies alle Punkte von standard input,

und male sie auf die Leinwand“

(A) Male jeden Punkt direkt nach dem Einlesen.

fur jede Eingabezeile (Zeile “Punkt):bestimme den entsprechenden Punktmale ihn

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert,y_wert)

(B) zuerst: lies alle Punkte einund speichere sie

danach: male jeden Punkt

fur jede Eingabezeile (Zeile “Punkt):speichere den entsprechenden Punkt

fur jeden gespeicherten Punkt:male ihn

stddraw – Messwerte als Punkte darstellen 1.5.43

Page 475: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Grundsatzliche Alternativen fur”Lies alle Punkte von standard input,

und male sie auf die Leinwand“

(A) Male jeden Punkt direkt nach dem Einlesen.

fur jede Eingabezeile (Zeile “Punkt):bestimme den entsprechenden Punktmale ihn

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert,y_wert)

(B) zuerst: lies alle Punkte einund speichere sie

danach: male jeden Punkt

fur jede Eingabezeile (Zeile “Punkt):speichere den entsprechenden Punkt

fur jeden gespeicherten Punkt:male ihn

xwerte = []

ywerte = []

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

xwerte += [ float(punkt[0]) ]

ywerte += [ float(punkt[1]) ]

# Der i-te Punkt ist (xwerte[i],ywerte[i]).

for i in range(len(xwerte)):

stddraw.point(xwerte[i],ywerte[i])stddraw – Messwerte als Punkte darstellen 1.5.43

Page 476: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------

# male-punkte.py

#-----------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input

# und male sie als Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#-----------------------------------------------------------------------------------------

import sys, stddraw

# Richte die Achsen der Leinwand ein und bereite den Stift vor.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.01)

# Standard input liefert zeilenweise x- und y-Werte von Punkten.

# Jeder dieser Punkte wird gemalt, die Leinwand wird angezeigt,

# und anschließend wird ein bisschen gewartet.

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert, y_wert)

stddraw.show(30)

stddraw.show()

#-----------------------------------------------------------------------------------------# python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | python3 male-punkte.py 1820 2020 -1 20

#

# python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | python3 male-punkte.py 1820 2020 -8 12

stddraw – Messwerte als Punkte darstellen 1.5.44

Page 477: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------

# male-punkte.py

#-----------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input

# und male sie als Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#-----------------------------------------------------------------------------------------

import sys, stddraw

# Richte die Achsen der Leinwand ein und bereite den Stift vor.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.01)

# Standard input liefert zeilenweise x- und y-Werte von Punkten.

# Jeder dieser Punkte wird gemalt, die Leinwand wird angezeigt,

# und anschließend wird ein bisschen gewartet.

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert, y_wert)

stddraw.show(30)

stddraw.show()

#-----------------------------------------------------------------------------------------# python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | python3 male-punkte.py 1820 2020 -1 20

#

# python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | python3 male-punkte.py 1820 2020 -8 12

stddraw – Messwerte als Punkte darstellen 1.5.44

Page 478: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------

# male-punkte.py

#-----------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input

# und male sie als Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#-----------------------------------------------------------------------------------------

import sys, stddraw

# Richte die Achsen der Leinwand ein und bereite den Stift vor.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.01)

# Standard input liefert zeilenweise x- und y-Werte von Punkten.

# Jeder dieser Punkte wird gemalt, die Leinwand wird angezeigt,

# und anschließend wird ein bisschen gewartet.

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert, y_wert)

stddraw.show(30)

stddraw.show()

#-----------------------------------------------------------------------------------------# python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | \

# python3 kjahres-mittel.py 9 | python3 male-punkte.py 1820 2020 -1 20

#

# python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | \

# python3 kjahres-mittel.py 9 | python3 male-punkte.py 1820 2020 -8 12stddraw – Messwerte als Punkte darstellen 1.5.44

Page 479: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------

# male-punkte.py

#-----------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input

# und male sie als Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#-----------------------------------------------------------------------------------------

import sys, stddraw

# Richte die Achsen der Leinwand ein und bereite den Stift vor.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.01)

# Standard input liefert zeilenweise x- und y-Werte von Punkten.

# Jeder dieser Punkte wird gemalt, die Leinwand wird angezeigt,

# und anschließend wird ein bisschen gewartet.

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

x_wert = float(punkt[0])

y_wert = float(punkt[1])

stddraw.point(x_wert, y_wert)

stddraw.show(30)

stddraw.show()

#-----------------------------------------------------------------------------------------# python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | \

# python3 kjahres-mittel.py 9 | python3 male-punkte.py 1820 2020 -1 20

#

# python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | \

# python3 kjahres-mittel.py 9 | python3 male-punkte.py 1820 2020 -8 12stddraw – Messwerte als Punkte darstellen 1.5.44

Page 480: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Darstellung der Jenaer Jahresdurchschnittstemperaturen (Teil 2)

Nun wollen wir noch aufeinanderfolgende Punkte mit einem Strich verbinden,

damit es eine schone Kurve gibt,

Ablauf des Programms:

lies alle Punkte ein

fur alle aufeinanderfolgenden Punkte:

male einen Strich mit ihnen als Endpunkte

und danach werden wir noch Achsen mit Skalen malen.

stddraw – Messwerte als Kurve darstellen 1.5.45

Page 481: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------

# male-kurve.py

#----------------------------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input und male sie

# als mit Strichen verbundene Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#----------------------------------------------------------------------------------------------------------

import sys, stddraw

# Bereite die Leinwand und den Stift vor.

# Die Skalenbereiche der Achsen werden von der Kommandozeile gelesen.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.04)

# Wir lesen zuerst alle Punkte von standard input und schreiben

# alle x-Werte in ein Array x[], und alle y-Werte in ein Array y[].

# Dann ist (x[i],y[i]) jeweils ein Punkt.

xwerte = []

ywerte = []

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

xwerte += [ float(punkt[0]) ]

ywerte += [ float(punkt[1]) ]

# Wir zeichnen jeweils eine Linie zwischen zwei aufeinanderfolgenden Punkten.

# Da der letzte Punkt keinen "Nachfolger" hat, ist er kein Startpunkt einer Linie.

for i in range(len(xwerte)-1):

stddraw.line( xwerte[i], ywerte[i], xwerte[i+1], ywerte[i+1] )

stddraw.show() # Zeige das Bild an.stddraw – Messwerte als Kurve darstellen 1.5.46

Page 482: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------

# male-kurve.py

#----------------------------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input und male sie

# als mit Strichen verbundene Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#----------------------------------------------------------------------------------------------------------

import sys, stddraw

# Bereite die Leinwand und den Stift vor.

# Die Skalenbereiche der Achsen werden von der Kommandozeile gelesen.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.04)

# Wir lesen zuerst alle Punkte von standard input und schreiben

# alle x-Werte in ein Array x[], und alle y-Werte in ein Array y[].

# Dann ist (x[i],y[i]) jeweils ein Punkt.

xwerte = []

ywerte = []

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

xwerte += [ float(punkt[0]) ]

ywerte += [ float(punkt[1]) ]

# Wir zeichnen jeweils eine Linie zwischen zwei aufeinanderfolgenden Punkten.

# Da der letzte Punkt keinen "Nachfolger" hat, ist er kein Startpunkt einer Linie.

for i in range(len(xwerte)-1):

stddraw.line( xwerte[i], ywerte[i], xwerte[i+1], ywerte[i+1] )

stddraw.show() # Zeige das Bild an.

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | \

python3 jahres-mittel.py | \

python3 male-kurve.py 1820 2020 -1 20

stddraw – Messwerte als Kurve darstellen 1.5.46

Page 483: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------------------------

# male-kurve.py

#----------------------------------------------------------------------------------------------------------

# Lies x0, x1, y0 und y1 von der Kommandozeile. Lies Wertepaare x,y von standard input und male sie

# als mit Strichen verbundene Punkte auf eine Leinwand mit x-Achse x0..x1 und y-Achse y0..y1.

#----------------------------------------------------------------------------------------------------------

import sys, stddraw

# Bereite die Leinwand und den Stift vor.

# Die Skalenbereiche der Achsen werden von der Kommandozeile gelesen.

stddraw.setXscale(float(sys.argv[1]), float(sys.argv[2]))

stddraw.setYscale(float(sys.argv[3]), float(sys.argv[4]))

stddraw.setPenRadius(0.04)

# Wir lesen zuerst alle Punkte von standard input und schreiben

# alle x-Werte in ein Array x[], und alle y-Werte in ein Array y[].

# Dann ist (x[i],y[i]) jeweils ein Punkt.

xwerte = []

ywerte = []

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

xwerte += [ float(punkt[0]) ]

ywerte += [ float(punkt[1]) ]

# Wir zeichnen jeweils eine Linie zwischen zwei aufeinanderfolgenden Punkten.

# Da der letzte Punkt keinen "Nachfolger" hat, ist er kein Startpunkt einer Linie.

for i in range(len(xwerte)-1):

stddraw.line( xwerte[i], ywerte[i], xwerte[i+1], ywerte[i+1] )

stddraw.show() # Zeige das Bild an.

python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | \

python3 jahres-mittel.py | \

python3 kjahres-durchschnitte.py 9 | \

python3 male-kurve.py 1820 2020 -1 20

stddraw – Messwerte als Kurve darstellen 1.5.46

Page 484: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Und abschließend zeichnen wir noch beschriftete Achsen dazu.

stddraw – Messwerte als Kurve darstellen 1.5.47

Page 485: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------

# male-kurve-mit-achsen.py

#-----------------------------------------------------------------------------------------

# Lies xmin, xmax, ymin und ymax von der Kommandozeile.

# Lies Wertepaare x,y von standard input

# und male sie als mit Strichen verbundene Punkte auf eine Leinwand

# mit x-Achse xmin..xmax und y-Achse ymin..ymax.

#-----------------------------------------------------------------------------------------

import sys, stddraw

# Wir lesen die Punkte von standard input.

# Wir schreiben alle x-Werte in ein Array x[], und alle y-Werte in ein Array y[].

# Dann ist (x[i],y[i]) jeweils ein Punkt.

xwerte = []

ywerte = []

for zeile in sys.stdin:

punkt = str.split(zeile, ' ')

xwerte += [ float(punkt[0]) ]

ywerte += [ float(punkt[1]) ]

# Um die Leinwand vorzubereiten,

# lesen wir von der Kommandozeile die Langen der x- und der y-Achse.

xmin = float(sys.argv[1])

xmax = float(sys.argv[2])

ymin = float(sys.argv[3])

ymax = float(sys.argv[4])

# Zum Malen der Achsen und deren Beschriftung brauchen wir an jeder Seite etwas Rand.

stddraw.setXscale(xmin-10, xmax+10)

stddraw.setYscale(ymin-2, ymax+2)

stddraw.setPenRadius(0.04)

# Male die x-Achse und die y-Achse des Koordinatensystems (in blau).

stddraw.setPenColor(stddraw.BLUE)

stddraw.line(xmin,ymin, xmax,ymin)

stddraw.line(xmin,ymin, xmin,ymax)

stddraw – Messwerte als Kurve darstellen 1.5.48

Page 486: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# Male die x-Achse und die y-Achse des Koordinatensystems (in blau).

stddraw.setPenColor(stddraw.BLUE)

stddraw.line(xmin,ymin, xmax,ymin)

stddraw.line(xmin,ymin, xmin,ymax)

# Beschrifte die Achsen des Koordinatensystems.

for i in range(int(ymin), int(ymax+1), int(ymax-ymin)//10): # beschrifte die y-Achse

stddraw.line(xmin-2,i, xmin+2,i) # male einen kleinen waagerechten Strich uber die y-Achse in Hohe i

stddraw.text(xmin-5, i, str(i)) # schreibe i links neben die y-Achse in Hohe i

for i in range(int(xmin), int(xmax+1), int(xmax-xmin)//10): # beschrifte die x-Achse

stddraw.line(i,ymin-0.2, i, ymin+0.2) # male einen kleinen senkrechten Strich an Stelle i der x-Achse

stddraw.text(i, ymin-1, str(i)) # schreibe i etwas unter die x-Achse an Stelle i

# Die Linien zwischen aufeinanderfolgenden (x,y)-Paaren werden gemalt.

stddraw.setPenColor(stddraw.BLACK)

stddraw.setPenRadius(0.06)

for i in range(len(xwerte)-1):

stddraw.line( xwerte[i], ywerte[i], xwerte[i+1], ywerte[i+1] )

stddraw.show(20)

stddraw.show()

#----------------------------------------------------------------------------------

stddraw – Messwerte als Kurve darstellen 1.5.49

Page 487: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# Male die x-Achse und die y-Achse des Koordinatensystems (in blau).

stddraw.setPenColor(stddraw.BLUE)

stddraw.line(xmin,ymin, xmax,ymin)

stddraw.line(xmin,ymin, xmin,ymax)

# Beschrifte die Achsen des Koordinatensystems.

for i in range(int(ymin), int(ymax+1), int(ymax-ymin)//10): # beschrifte die y-Achse

stddraw.line(xmin-2,i, xmin+2,i) # male einen kleinen waagerechten Strich uber die y-Achse in Hohe i

stddraw.text(xmin-5, i, str(i)) # schreibe i links neben die y-Achse in Hohe i

for i in range(int(xmin), int(xmax+1), int(xmax-xmin)//10): # beschrifte die x-Achse

stddraw.line(i,ymin-0.2, i, ymin+0.2) # male einen kleinen senkrechten Strich an Stelle i der x-Achse

stddraw.text(i, ymin-1, str(i)) # schreibe i etwas unter die x-Achse an Stelle i

# Die Linien zwischen aufeinanderfolgenden (x,y)-Paaren werden gemalt.

stddraw.setPenColor(stddraw.BLACK)

stddraw.setPenRadius(0.06)

for i in range(len(xwerte)-1):

stddraw.line( xwerte[i], ywerte[i], xwerte[i+1], ywerte[i+1] )

stddraw.show(20)

stddraw.show()

#----------------------------------------------------------------------------------

# python3 filter-DWD.py 15 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | \

# python3 kjahres-mittel.py 9 | python3 male-kurve-mit-achsen.py 1831 2018 -1 20

#stddraw – Messwerte als Kurve darstellen 1.5.49

Page 488: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# Male die x-Achse und die y-Achse des Koordinatensystems (in blau).

stddraw.setPenColor(stddraw.BLUE)

stddraw.line(xmin,ymin, xmax,ymin)

stddraw.line(xmin,ymin, xmin,ymax)

# Beschrifte die Achsen des Koordinatensystems.

for i in range(int(ymin), int(ymax+1), int(ymax-ymin)//10): # beschrifte die y-Achse

stddraw.line(xmin-2,i, xmin+2,i) # male einen kleinen waagerechten Strich uber die y-Achse in Hohe i

stddraw.text(xmin-5, i, str(i)) # schreibe i links neben die y-Achse in Hohe i

for i in range(int(xmin), int(xmax+1), int(xmax-xmin)//10): # beschrifte die x-Achse

stddraw.line(i,ymin-0.2, i, ymin+0.2) # male einen kleinen senkrechten Strich an Stelle i der x-Achse

stddraw.text(i, ymin-1, str(i)) # schreibe i etwas unter die x-Achse an Stelle i

# Die Linien zwischen aufeinanderfolgenden (x,y)-Paaren werden gemalt.

stddraw.setPenColor(stddraw.BLACK)

stddraw.setPenRadius(0.06)

for i in range(len(xwerte)-1):

stddraw.line( xwerte[i], ywerte[i], xwerte[i+1], ywerte[i+1] )

stddraw.show(20)

stddraw.show()

#----------------------------------------------------------------------------------

# python3 filter-DWD.py 16 < Jena-Wetterdaten.txt | python3 jahres-mittel.py | \

# python3 kjahres-mittel.py 9 | python3 male-kurve-mit-achsen.py 1831 2018 -5 12

#stddraw – Messwerte als Kurve darstellen 1.5.49

Page 489: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zeichnen des Graphs einer Funktion

Zum Zeichnen des Graphs einer Funktion muss das Programm die Argument-/Wert-Paare,die male-kurve.py von standard input einliest, selbst erzeugen.

Wenn der Graph der Funktion f pxq im Bereich l ď x ď r gezeichnet werden soll,

§ muss man festlegen, wieviele Funktionswerte man im Bereich l ď x ď r berechnen will(das Intervall l . . . r wird in gleichmaßige Abschnitte unterteilt),

Wenn Funktionswerte fur n Argumente im Intervall l ď x ď r berechnet werden sollen,

haben die Argumente Abstand l´rn´1 und sind l , l `1 ¨ r´l

n´1 , l `2 ¨ r´ln´1 , . . . , l ` pn ´ 1q ¨

r ´ l

n ´ 1loooooooooomoooooooooon

“r

.

§ die Argument-Wert-Paare px , f pxqq berechnen und

§ die Funktionswerte aufeinanderfolgender Argumente durch eine Linie verbinden.

Man beachte, dass stets nur eine Naherung berechnet wird,deren Qualitat von der Anzahl der berechneten Funktionswerte abhangt.

stddraw – Graph einer Funktion darstellen 1.5.50

Page 490: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zeichnen des Graphs einer Funktion

Zum Zeichnen des Graphs einer Funktion muss das Programm die Argument-/Wert-Paare,die male-kurve.py von standard input einliest, selbst erzeugen.

Wenn der Graph der Funktion f pxq im Bereich l ď x ď r gezeichnet werden soll,

§ muss man festlegen, wieviele Funktionswerte man im Bereich l ď x ď r berechnen will(das Intervall l . . . r wird in gleichmaßige Abschnitte unterteilt),

Wenn Funktionswerte fur n Argumente im Intervall l ď x ď r berechnet werden sollen,

haben die Argumente Abstand l´rn´1 und sind l , l `1 ¨ r´l

n´1 , l `2 ¨ r´ln´1 , . . . , l ` pn ´ 1q ¨

r ´ l

n ´ 1loooooooooomoooooooooon

“r

.

§ die Argument-Wert-Paare px , f pxqq berechnen und

§ die Funktionswerte aufeinanderfolgender Argumente durch eine Linie verbinden.

Man beachte, dass stets nur eine Naherung berechnet wird,deren Qualitat von der Anzahl der berechneten Funktionswerte abhangt.

stddraw – Graph einer Funktion darstellen 1.5.50

Page 491: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------------------------

# functiongraph.py (so ahnlich wie im Buch)

#-----------------------------------------------------------------------------------------------------------

# Der Graph der Funktion f(x) = sin(4x)+sin(20x) wird im Intervall -pi/2..pi/2 gezeichnet.

# Von der Kommandozeile wird die Sampling-Dichte n (d.h. die Anzahl der zu berechnenden Punkte) eingelesen.

#-----------------------------------------------------------------------------------------------------------

import math, sys, stddraw

# Lies n von der Kommandozeile

# und erzeuge Arrays fur die x-Werte und die y-Werte des Graph der Funktion f.

n = int(sys.argv[1])

x_werte = []

y_werte = []

# Berechne fur n x-Werte, die gleichmaßig uber das Intervall -pi/2..pi/2 verteilt sind,

# jeweils den zugehorigen y-Wert f(x)=sin(4x)+sin(20x).

# Die x_werte sind -pi/2, -pi/2+1*pi/(n-1), -pi/2+2*pi/(n-1),..., -pi/2+(n-1)*pi/(n-1) .

# Speichere den x-Wert in x_werte[] und den zugehorigen y-Wert in y_werte.

# Am Ende gilt f(x_werte[i])==y_werte[i] fur i in range(n).

for i in range(n):

x_werte += [ -math.pi/2 + i * math.pi/(n-1) ]

y_werte += [ math.sin(4*x_werte[i]) + math.sin(20*x_werte[i]) ]

# Richte die Leinwand ein.

stddraw.setXscale(-math.pi/2, math.pi/2)

stddraw.setYscale(-2, 2)

# Male die Punkte und verbinde sie mit Strichen.

for i in range(n-1):

stddraw.line(x_werte[i], y_werte[i], x_werte[i+1], y_werte[i+1])

# Zeige das Bild an.

stddraw.show()stddraw – Graph einer Funktion darstellen 1.5.51

Page 492: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------------------------

# functiongraph.py (so ahnlich wie im Buch)

#-----------------------------------------------------------------------------------------------------------

# Der Graph der Funktion f(x) = sin(4x)+sin(20x) wird im Intervall -pi/2..pi/2 gezeichnet.

# Von der Kommandozeile wird die Sampling-Dichte n (d.h. die Anzahl der zu berechnenden Punkte) eingelesen.

#-----------------------------------------------------------------------------------------------------------

import math, sys, stddraw

# Lies n von der Kommandozeile

# und erzeuge Arrays fur die x-Werte und die y-Werte des Graph der Funktion f.

n = int(sys.argv[1])

x_werte = []

y_werte = []

# Berechne fur n x-Werte, die gleichmaßig uber das Intervall -pi/2..pi/2 verteilt sind,

# jeweils den zugehorigen y-Wert f(x)=sin(4x)+sin(20x).

# Die x_werte sind -pi/2, -pi/2+1*pi/(n-1), -pi/2+2*pi/(n-1),..., -pi/2+(n-1)*pi/(n-1) .

# Speichere den x-Wert in x_werte[] und den zugehorigen y-Wert in y_werte.

# Am Ende gilt f(x_werte[i])==y_werte[i] fur i in range(n).

for i in range(n):

x_werte += [ -math.pi/2 + i * math.pi/(n-1) ]

y_werte += [ math.sin(4*x_werte[i]) + math.sin(20*x_werte[i]) ]

# Richte die Leinwand ein.

stddraw.setXscale(-math.pi/2, math.pi/2)

stddraw.setYscale(-2, 2)

# Male die Punkte und verbinde sie mit Strichen.

for i in range(n-1):

stddraw.line(x_werte[i], y_werte[i], x_werte[i+1], y_werte[i+1])

# Zeige das Bild an.

stddraw.show()

python3 functiongraph.py 21

python3 functiongraph.py 20

stddraw – Graph einer Funktion darstellen 1.5.51

Page 493: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------------------------

# functiongraph.py (so ahnlich wie im Buch)

#-----------------------------------------------------------------------------------------------------------

# Der Graph der Funktion f(x) = sin(4x)+sin(20x) wird im Intervall -pi/2..pi/2 gezeichnet.

# Von der Kommandozeile wird die Sampling-Dichte n (d.h. die Anzahl der zu berechnenden Punkte) eingelesen.

#-----------------------------------------------------------------------------------------------------------

import math, sys, stddraw

# Lies n von der Kommandozeile

# und erzeuge Arrays fur die x-Werte und die y-Werte des Graph der Funktion f.

n = int(sys.argv[1])

x_werte = []

y_werte = []

# Berechne fur n x-Werte, die gleichmaßig uber das Intervall -pi/2..pi/2 verteilt sind,

# jeweils den zugehorigen y-Wert f(x)=sin(4x)+sin(20x).

# Die x_werte sind -pi/2, -pi/2+1*pi/(n-1), -pi/2+2*pi/(n-1),..., -pi/2+(n-1)*pi/(n-1) .

# Speichere den x-Wert in x_werte[] und den zugehorigen y-Wert in y_werte.

# Am Ende gilt f(x_werte[i])==y_werte[i] fur i in range(n).

for i in range(n):

x_werte += [ -math.pi/2 + i * math.pi/(n-1) ]

y_werte += [ math.sin(4*x_werte[i]) + math.sin(20*x_werte[i]) ]

# Richte die Leinwand ein.

stddraw.setXscale(-math.pi/2, math.pi/2)

stddraw.setYscale(-2, 2)

# Male die Punkte und verbinde sie mit Strichen.

for i in range(n-1):

stddraw.line(x_werte[i], y_werte[i], x_werte[i+1], y_werte[i+1])

# Zeige das Bild an.

stddraw.show()

python3 functiongraph.py 21

python3 functiongraph.py 200

stddraw – Graph einer Funktion darstellen 1.5.51

Page 494: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------------------------------

# functiongraph.py (so ahnlich wie im Buch)

#-----------------------------------------------------------------------------------------------------------

# Der Graph der Funktion f(x) = sin(4x)+sin(20x) wird im Intervall -pi/2..pi/2 gezeichnet.

# Von der Kommandozeile wird die Sampling-Dichte n (d.h. die Anzahl der zu berechnenden Punkte) eingelesen.

#-----------------------------------------------------------------------------------------------------------

import math, sys, stddraw

# Lies n von der Kommandozeile

# und erzeuge Arrays fur die x-Werte und die y-Werte des Graph der Funktion f.

n = int(sys.argv[1])

x_werte = []

y_werte = []

# Berechne fur n x-Werte, die gleichmaßig uber das Intervall -pi/2..pi/2 verteilt sind,

# jeweils den zugehorigen y-Wert f(x)=sin(4x)+sin(20x).

# Die x_werte sind -pi/2, -pi/2+1*pi/(n-1), -pi/2+2*pi/(n-1),..., -pi/2+(n-1)*pi/(n-1) .

# Speichere den x-Wert in x_werte[] und den zugehorigen y-Wert in y_werte.

# Am Ende gilt f(x_werte[i])==y_werte[i] fur i in range(n).

for i in range(n):

x_werte += [ -math.pi/2 + i * math.pi/(n-1) ]

y_werte += [ math.sin(4*x_werte[i]) + math.sin(20*x_werte[i]) ]

# Richte die Leinwand ein.

stddraw.setXscale(-math.pi/2, math.pi/2)

stddraw.setYscale(-2, 2)

# Male die Punkte und verbinde sie mit Strichen.

for i in range(n-1):

stddraw.line(x_werte[i], y_werte[i], x_werte[i+1], y_werte[i+1])

# Zeige das Bild an.

stddraw.show()

python3 functiongraph.py 21

python3 functiongraph.py 512

stddraw – Graph einer Funktion darstellen 1.5.51

Page 495: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Weitere stddraw-Funktionen: (1) Kreise malen

stddraw.circle(x, y, r) male einen Kreis

mit Mittelpunkt px , yq und Radius r

import stddraw

x = 2

y = 3

r = 4

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.circle(x, y, r)

stddraw.show()

p2, 3q

4

stddraw – weitere Funktionen 1.5.52

Page 496: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Weitere stddraw-Funktionen: (1) Kreise malen

stddraw.circle(x, y, r) male einen Kreis

mit Mittelpunkt px , yq und Radius r

import stddraw

x = 2

y = 3

r = 4

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.circle(x, y, r)

stddraw.show()

p2, 3q

4

stddraw – weitere Funktionen 1.5.52

Page 497: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(2) Quadrate malen

stddraw.square(x, y, r) male ein Quadrat

mit Mittelpunkt px , yq und Radius r

import stddraw

x = 2

y = 3

r = 4

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.square(x, y, r)

stddraw.show()

p2, 3q

4

4

stddraw – weitere Funktionen 1.5.53

Page 498: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(2) Quadrate malen

stddraw.square(x, y, r) male ein Quadrat

mit Mittelpunkt px , yq und Radius r

import stddraw

x = 2

y = 3

r = 4

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.square(x, y, r)

stddraw.show()

p2, 3q

4

4

stddraw – weitere Funktionen 1.5.53

Page 499: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(3) Vielecke malen

stddraw.polygon(x, y) male ein Vieleck mit den Ecken

px[0], y[0]q, px[1], y[1]q, . . .

(x und y sind Arrays)

import stddraw

x = [1,0,3,4,5]

y = [2,3,4,6,1]

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.polygon(x,y)

stddraw.show()

p1, 2q

p0, 3q

p3, 4q

p4, 6q

p5, 1q

stddraw – weitere Funktionen 1.5.54

Page 500: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

(3) Vielecke malen

stddraw.polygon(x, y) male ein Vieleck mit den Ecken

px[0], y[0]q, px[1], y[1]q, . . .

(x und y sind Arrays)

import stddraw

x = [1,0,3,4,5]

y = [2,3,4,6,1]

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.polygon(x,y)

stddraw.show() p1, 2q

p0, 3q

p3, 4q

p4, 6q

p5, 1q

stddraw – weitere Funktionen 1.5.54

Page 501: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Alle Formen konnen auch gefullt gemalt werden mittelsstddraw.filledCircle(x,y,r), stddraw.filledSquare(x,y,r),

stddraw.filledPolygon(x,y).

stddraw.filledPolygon(x, y) male ein ausgefulltes Vieleck mit den Ecken

px[0], y[0]q, px[1], y[1]q, . . . (x und y sind Arrays)

import stddraw

x = [1,0,3,4,5]

y = [2,3,4,6,1]

stddraw.setXscale(0, 6)

stddraw.setYscale(0, 6)

stddraw.setPenColor(stddraw.RED)

stddraw.filledPolygon(x,y)

stddraw.show()

stddraw – weitere Funktionen 1.5.55

Page 502: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Sonstige stddraw-Funktionen

Male ein Rechteck:

stddraw.rectangle(x,y, w,h) male ein Rechteck mit Punkt (x,y) unten links,

Breite w und Hohe h

stddraw.filledRectangle(x,y, w,h) male ein gefulltes Rechteck . . .

Schreibe Text:

stddraw.text(x,y, s) schreibe String s zentriert an Punkt (x,y)

stddraw.setFontSize(n) setze die Buchstabengroße auf n (Standard 12)

stddraw.setFontFamily(f) setze den Zeichensatz auf f (Standard helvetica)

Losche die Leinwand:

stddraw.clear(c) losche die Leinwand und farbe jedes Pixel mit Farbe c

stddraw – weitere Funktionen 1.5.56

Page 503: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

import stddraw

stddraw.clear(stddraw.YELLOW)

stddraw.square(0.2, 0.8, 0.1)

stddraw.filledSquare(0.8, 0.8, 0.2)

stddraw.setPenColor(stddraw.GREEN)

xd = [0.1, 0.2, 0.3, 0.2]

yd = [0.2, 0.3, 0.2, 0.1]

stddraw.filledPolygon(xd, yd)

stddraw.setPenColor(stddraw.RED)

stddraw.filledCircle(0.8, 0.2, 0.2)

stddraw.setFontSize(20)

stddraw.text(0.8,0.8, 'großer roter Text')

stddraw.show()

Bilder konnen mittels Klick auf die rechte Maustasteoder mit stddraw.save(dateiname) gespeichert werden.

Die Dateinamenendung muss .jpg oder .png sein.

stddraw – weitere Funktionen 1.5.57

Page 504: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Bewegte Bilder

Zeigt man schnell hintereinander ahnliche Bilder, so sieht es aus, als ob sich etwas bewegt.

stddraw – bewegte Bilder 1.5.58

Page 505: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufgabe: Lasse eine Kugel quer uber die Leinwand rollen

Die Kugel soll von der unteren linken Ecke der Leinwand (Punkt p0, 0q)

auf der Diagonalen in die obere rechte Ecke der Leinwand rollen (Punkt p1, 1q).

Die Punkte auf der Diagonalen haben die gleiche x- und y -Koordinate.

Wir erhalten die Punkte der rollenden Kugel, indem wir einen Abstand wahlen,

den wir immer wieder zur x- und y -Koordinate der Kugel addieren,

bis die beiden Koordinaten 1 (oder großer) geworden sind.

Die Leinwand mit der Kugel an ihrer aktuellen Position wird jedesmal fur eine kleine Zeitspanne

angezeigt, wenn die Kugel ihre neue Position erhalten hat.

stddraw – bewegte Bilder 1.5.59

Page 506: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# kugel-1.py

#--------------------------------------------------------------------------------

# Eine Kugel rollt auf der Diagonalen von links nach rechts durch das Bild.

# Das wird als "Film" durch aufeinanderfolgende Bilder angezeigt.

# Von der Kommandozeile wird ein int zeitspanne (Anzeigezeit jedes Bildes in ms)

# und ein float abstand (beeinflusst den Abstand der Kugel von Bild zu Bild) gelesen.

#--------------------------------------------------------------------------------

import sys, stddraw

zeitspanne = int(sys.argv[1])

abstand = float(sys.argv[2])

RADIUS = 0.05 # Der Radius der Kugel.

# Die Kugel wird auf der Diagonalen uber die Leinwand bewegt.

# Der Startpunkt der Kugel ist (0,0) -- d.h. die untere linke Ecke der Leinwand.

# Der Punkt (x_pos,y_pos) ist die aktuelle Position der Kugel.

x_pos = 0.0

y_pos = 0.0

# Die Bewegung entsteht, indem aufeinanderfolgende Bilder gezeigt werden,

# bei denen die Kugel jedesmal ein kleines Stuck weitergerollt ist.

# Das wird erreicht, indem abstand zu x_pos und y_pos addiert wird.

while x_pos<1.0 and y_pos<1.0:

# Bestimme die nachste Position der Kugel.

x_pos = x_pos + abstand

y_pos = y_pos + abstand

# Losche die Leinwand, male die Kugel auf ihrer neuen Position und zeige die Leinwand an.

stddraw.filledCircle(x_pos, y_pos, RADIUS)

stddraw.show(zeitspanne)

stddraw.show()stddraw – bewegte Bilder 1.5.60

Page 507: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

python3 kugel-1.py 20 0.13

python3 kugel-1.py 20 0.18

(Wir konnen jetzt nicht mehr richtig darstellen, was passiert . . . )

stddraw – bewegte Bilder 1.5.61

Page 508: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufgabe: lasse die Kugel hin- und herprallen

Die Kugel soll von der unteren linken Ecke der Leinwand (Punkt p0, 0q)uber die Diagonale in die obere rechte Ecke der Leinwand rollen (Punkt p1, 1q).

Von dort soll sie wieder zuruckrollen usw.

Das erreicht man wie folgt:Wenn die Kugel in einer Ecke ankommt,

dann wird das Vorzeichen von abstand verandert.Wenn abstand positiv ist, dann rollt die Kugel von links unten nach rechts oben.Wenn abstand negativ ist, dann rollt die Kugel von rechts oben nach links unten.

stddraw – bewegte Bilder 1.5.62

Page 509: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# kugel-2.py

#--------------------------------------------------------------------------------------

# Eine Kugel rollt auf der Diagonalen von links nach rechts hin und her durch das Bild.

# Von der Kommandozeile wird ein int zeitspanne (Anzeigezeit jedes Bildes in ms)

# und ein float abstand (beeinflusst den Abstand der Kugel von Bild zu Bild) gelesen.

#-------------------------------------------------------------------------------------

import sys, stddraw

zeitspanne = int(sys.argv[1])

abstand = float(sys.argv[2])

RADIUS = 0.05 # Der Radius der Kugel.

# Der Startpunkt der Kugel ist (0,0) -- d.h. die untere linke Ecke der Leinwand.

# Der Punkt (x_pos,y_pos) ist die aktuelle Position der Kugel.

x_pos = 0.0

y_pos = 0.0

# Die Bewegung entsteht, indem aufeinanderfolgende Bilder gezeigt werden,

# bei denen die Kugel jedesmal ein kleines Stuck weitergerollt ist.

# Das wird erreicht, indem abstand zu x_pos und y_pos addiert wird.

while True:

# Falls die Kugel in einer Ecke ist, dann andere ihre Richtung (um 180 Grad).

if x_pos>=1.0 or x_pos<0.0: abstand = -abstand

# Bestimme die nachste Position der Kugel.

x_pos += abstand

y_pos += abstand

# Losche die Leinwand, male die Kugel auf ihrer neuen Position und zeige die Leinwand an.

stddraw.filledCircle(x_pos, y_pos, RADIUS)

stddraw.show(zeitspanne)

stddraw.show()

#-------------------------------------------------------------------------------

# python kugel-2.py 25 0.005 stddraw – bewegte Bilder 1.5.63

Page 510: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufgabe: lasse die Kugel an den Seiten der Leinwand abprallen

Die Kugel rollt uber die Leinwand.Wenn sie an eine Seite stoßt, dann prallt sie ab (

”Einfallswinkel“Ausfallswinkel“) und rollt weiter.

Wir mussen jetzt die Anderung der x-Koordinate und die Anderung der y -Koordinate der Kugeltrennen.

Wenn die Kugel an den linken oder rechten Rand stoßt,dann andert sich das Vorzeichen der Anderung der x-Koordinate.

Wenn die Kugel an den unteren oder oberen Rand stoßt,

dann andert sich das Vorzeichen der Anderung der y -Koordinate.

stddraw – bewegte Bilder 1.5.64

Page 511: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# kugel-3.py, Beispielaufruf: python3 kugel-3.py 25 0.005 0.008

#-------------------------------------------------------------------------------------------------

# Eine Kugel rollt auf der Leinwand. Wenn sie an eine Seite stoßt, prallt sie ab und rollt weiter.

# Das wird als "Film" durch aufeinanderfolgende Bilder angezeigt. Von der Kommandozeile werden

# ein int zeitspanne (Anzeigezeit jedes Bildes in ms) und zwei floats x_abstand und y_abstand

# (beeinflussen den Abstand der Kugel von Bild zu Bild) gelesen.

#-------------------------------------------------------------------------------------------------

import sys, stddraw

zeitspanne = int(sys.argv[1])

x_abstand = float(sys.argv[2])

y_abstand = float(sys.argv[3])

# Die Kugel liegt in der Mitte der Leinwand. Punkt (x_pos,y_pos) ist ihre aktuelle Position.

(x_pos, y_pos) = (0.5, 0.5)

# Die Bewegung entsteht, indem x_abstand zu x_pos und y_abstand zu y_pos addiert wird.

# Wenn die Kugel an eine Seite prallt, wird das Vorzeichen des entsprechenden Abstands geandert.

while True:

# Falls die Kugel an die rechte oder linke Seite prallt, dann andere ihre x-Richtung.

if x_pos>=1.0 or x_pos<=0.0: x_abstand = -x_abstand

# Falls die Kugel an die untere oder obere Seite prallt, dann andere ihre y-Richtung.

if y_pos>=1.0 or y_pos<=0.0: y_abstand = -y_abstand

# Bestimme die nachste Position der Kugel.

x_pos = x_pos + x_abstand

y_pos = y_pos + y_abstand

# Losche die Leinwand, male die Kugel auf ihrer neuen Position und zeige die Leinwand an.

stddraw.clear(stddraw.GRAY)

stddraw.filledCircle(x_pos, y_pos, 0.05)

stddraw.show(zeitspanne)

stddraw.show()stddraw – bewegte Bilder 1.5.65

Page 512: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassungstandard draw

Wir haben gesehen, wie Bilder aus einfachen Elementen

(Punkte, Striche, Kreise, Rechtecke, Schrift)

gestaltet und angezeigt werden konnen.

Mit diesen Mitteln lassen sich z.B. Messwerte

und einfache Animationen graphisch ansprechend darstellen.

1.5.66

Page 513: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Weitere Beispiele

Eine csv-Datei (comma separated values) enthalt in Zeilen zusammengehorige Daten, die als Stringsdargestellt und durch Kommas (o.a.) getrennt sind.

Bsp.: Datei airports.csv mit Namen, Breiten- und Langengrad etc. von Flughafen.

1,"Goroka","Goroka","Papua New Guinea","GKA","AYGA",-6.081689,145.391881,5282,10,"U","Pacific/Port_Moresby"

2,"Madang","Madang","Papua New Guinea","MAG","AYMD",-5.207083,145.7887,20,10,"U","Pacific/Port_Moresby"

3,"Mount Hagen","Mount Hagen","Papua New Guinea","HGU","AYMH",-5.826789,144.295861,5388,10,"U","Pacific/Port_Moresby"

4,"Nadzab","Nadzab","Papua New Guinea","LAE","AYNZ",-6.569828,146.726242,239,10,"U","Pacific/Port_Moresby"

5,"Port Moresby Jacksons Intl","Port Moresby","Papua New Guinea","POM","AYPY",-9.443383,147.22005,146,10,"U","Pacific/Port_Moresby"

6,"Wewak Intl","Wewak","Papua New Guinea","WWK","AYWK",-3.583828,143.669186,19,10,"U","Pacific/Port_Moresby"

Wir wollen nun die Koordinaten jedes Flughafens ausgeben.Dazu konnen wir jede Zeile in ein Array aufteilen, dessen Elemente die durch Kommas getrennten Stellender Zeile sind.

zeile = '1,"Goroka","Goroka","Papua New Guinea","GKA","AYGA",' +

'-6.081689,145.391881,5282,10,"U","Pacific/Port_Moresby"'

array = string.split( zeile, ',' )

stdio.writeln(array)

liefert['1', '"Goroka"', '"Goroka"', '"Papua New Guinea"', '"GKA"', '"AYGA"', '-6.081689', '145.391881',

'5282', '10', '"U"', '"Pacific/Port_Moresby"']Anhang mit alten Programmen 1.5.67

Page 514: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# coords-aus-csv.py

# Es werden die Zeilen einer csv-Datei eingelesen.

# Die Eintrage an Stelle 6 und 7 werden ausgegeben.

import stdio, string

while stdio.hasNextLine():

line = stdio.readLine()

breitengrad = string.split(line,',')[6]

laengengrad = string.split(line,',')[7]

stdio.writef('%8s %8s\n', breitengrad, laengengrad)

#---------------------------------------------------------

# python coords-aus-csv.py < airports.csv

# -6.081689 145.391881

# -5.207083 145.7887

# -5.826789 144.295861

# -6.569828 146.726242

# -9.443383 147.22005

# -3.583828 143.669186

# ...

Anhang mit alten Programmen 1.5.68

Page 515: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------

# plotfilter.py (aus dem Buch)

#-----------------------------------------------------------------------

import stdio

import stddraw

# Read x and y scales from standard input, and configure standard

# draw accordingly. Then read points from standard input until

# end-of-file, and plot them on standard draw.

x0 = stdio.readFloat()

y0 = stdio.readFloat()

x1 = stdio.readFloat()

y1 = stdio.readFloat()

stddraw.setXscale(x0, x1)

stddraw.setYscale(y0, y1)

# Read and plot the points.

stddraw.setPenRadius(0.002)

while not stdio.isEmpty():

x = stdio.readFloat()

y = stdio.readFloat()

stddraw.point(x, y)

stddraw.show()

#----------------------------------------

# python plotfilter.py < usa.txt

Datei usa.txt:

669905.0 247205.0 1244962.0 700000.0

1097038.8890 245552.7780

1103961.1110 247133.3330

1104677.7780 247205.5560

1108586.1110 249238.8890

1109713.8890 250111.1110

...Anhang mit alten Programmen 1.5.69

Page 516: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen plotfilter.py benutzen, um eine Karte mit den Flughafen zu malen.

Deren Koordinaten haben wir ja bereits.

Dazu mussen wir coords-aus-csv.py so modifizieren,dass es zu plotfiler.py passt:

§ In der ersten Zeile der Ausgabe mussen die Werte x0, y0, x1, y1 fur die Bereiche der x-Werte(x0 ď x ď x1) und die Bereiche der y -Werte (y0 ď y ď y1) stehen.

§ In den darauffolgenden Zeilen folgen x-Koordinate (Langengrad) und y -Koordinate (Breitengrad) jedesFlughafens.

Anhang mit alten Programmen 1.5.70

Page 517: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------

# airports-to-plotfilter.py

#-----------------------------------------------------------------------

# Es werden die Zeilen einer csv-Datei eingelesen.

# Die Ausgabe passt als Eingabe fur plotfilter.py .

# Zuerst werden die Bereiche fur die x- und y-Koordinaten ausgegeben.

# Die x-Koordinaten sind die Langengrade (-180 ... 180) und

# die y-Koordinaten sind die Breitengrade (-90 .. 90).

# Der Eintrag an Stelle 6 der csv-Datei ist der Breitengrad,

# und der Eintrag an Stelle 7 ist der Langengrad.

import stdio, string

# Ausgabe der Bereiche fur die x- und y-Koordinaten

stdio.writeln('-180.0 -90.0 180.0 90.0')

while stdio.hasNextLine():

zeile = stdio.readLine()

xkoordinate = string.split(zeile,',')[7]

ykoordinate = string.split(zeile,',')[6]

stdio.writef('%8s %8s\n', xkoordinate, ykoordinate)

#--------------------------------------------------------------------------

# ( python airports-to-plotfilter.py < airports.csv ) | python plotfilter.py

#Anhang mit alten Programmen 1.5.71

Page 518: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 07

1. Elemente des Programmierens

1.2 Grundlegende Daten-Typen

1.3 Verzweigungen und Schleifen

1.4 Arrays

1.5 Ein- und Ausgabe

1.6 Dictionaries und Abschluss-Beispiel Page Rank

Anhang mit alten Programmen 1.6.1

Page 519: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Dictionaries

Bei Arrays hat man eine Zuordnung von Indizes zu Werten.

Bei Dictionaries hat man eine Zuordnung von Schlusseln zu Werten.

Die Werte konnen uber die Schlussel”angesprochen“ werden.

Die Schlussel konnen vom Typ string, int etc. sein.

Worterbuch:

Adler eagle

Buch book

Dienst service

Efeu ivy

funkeln sparkle...

...

Python:

d = dict() # d ist ein leeres Dictionary

d['Adler'] = 'eagle'

d['Buch'] = 'book'

d['Dienst'] = 'service'

d['Efeu'] = 'ivy'

d['funkeln'] = 'sparkle'

...

Datentyp dict – Dictionary 1.6.2

Page 520: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Benutzung des Datentyps dict

Erzeugen eines Dictionary:

ts1 : w1, s2 : w2, ..., sn : wnu ein Dictionary der Lange n mit den Zuordnungen

Schlussel s0 zu Wert w0, . . . , Schlussel sn´1 zu Wert wn´1

dict() oder t u ein leeres Dictionary (ohne Zuordnungen)

Zugriff auf ein Dictionary d:

d[s] der Wert, der Schlussel s in d zugeordnet ist (indizierter Zugriff)

d[s] = x ersetze den Wert, der Schlussel s zugeordnet ist, durch x (indizierte Zuweisung)

s in d ergibt True, falls Schlussel s im Dictionary d vorkommt, sonst False

len(d) die Anzahl der Schlussel von d

for s in d: iteriere uber alle Schlussel s von d (Durchlaufen)

list(d) ein Array aus allen Schlusseln von d

del(d[s]) losche Schlussel s (und den zugeordneten Wert) aus d

Datentyp dict – Dictionary 1.6.3

Page 521: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen ein Programm schreiben,

das ein Eingabewort in das Morsealphabet kodiert

oder aus dem Morsealphabet dekodiert.

Das Morsealphabet ordnet jedem Großbuchstaben eine Zeichenfolge aus Punkten und Strichen zu,

z.B.

A .-

B -...

C -.-.

D -..

E .

F ..-.

G --.

H ....

I ..

J .---

K -.-

L .-..

Das Wort KABEL wird zu -.- .- -... . .-.. kodiert

und das Wort -... . .. ..-. .- .-.. .-.. wird zu BEIFALL dekodiert.

Unser Programm soll

(1) das Morsealphabet aus einer Datei (wie oben) lesen

und daraus ein Dictionary zum Kodieren (Schlussel: Buchstabe, Wert: Morsecode)

sowie ein Dictionary zum Dekodieren (Schlussel: Morsecode, Wert: Buchstabe) erzeugen, und

(2) den String von der Kommandozeile damit kodieren bzw. dekodieren.Beispielprogramm morsen.py 1.6.4

Page 522: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen ein Programm schreiben,

das ein Eingabewort in das Morsealphabet kodiert

oder aus dem Morsealphabet dekodiert.

Das Morsealphabet ordnet jedem Großbuchstaben eine Zeichenfolge aus Punkten und Strichen zu,

z.B.

A .-

B -...

C -.-.

D -..

E .

F ..-.

G --.

H ....

I ..

J .---

K -.-

L .-..

Das Wort KABEL wird zu -.- .- -... . .-.. kodiert

und das Wort -... . .. ..-. .- .-.. .-.. wird zu BEIFALL dekodiert.

Unser Programm soll

(1) das Morsealphabet aus einer Datei (wie oben) lesen

und daraus ein Dictionary zum Kodieren (Schlussel: Buchstabe, Wert: Morsecode)

sowie ein Dictionary zum Dekodieren (Schlussel: Morsecode, Wert: Buchstabe) erzeugen, und

(2) den String von der Kommandozeile damit kodieren bzw. dekodieren.Beispielprogramm morsen.py 1.6.4

Page 523: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .-

B -...

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

Dictionary morsedecode

Schlussel Wert

Beispielprogramm morsen.py 1.6.5

Page 524: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-'

B -...

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

Dictionary morsedecode

Schlussel Wert

Beispielprogramm morsen.py 1.6.5

Page 525: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-' ['A', '.-']

B -...

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

Dictionary morsedecode

Schlussel Wert

Beispielprogramm morsen.py 1.6.5

Page 526: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-' ['A', '.-'] morsecode['A'] = '.-'

morsedecode['.-'] = 'A'

B -...

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

'A' '.-'

Dictionary morsedecode

Schlussel Wert

'.-' 'A'

Beispielprogramm morsen.py 1.6.5

Page 527: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-' ['A', '.-'] morsecode[z[0]] = z[1]

morsedecode[z[1]] = z[0]

B -...

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

'A' '.-'

Dictionary morsedecode

Schlussel Wert

'.-' 'A'

Beispielprogramm morsen.py 1.6.5

Page 528: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-' ['A', '.-'] morsecode[z[0]] = z[1]

morsedecode[z[1]] = z[0]

B -... 'B -...'

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

'A' '.-'

Dictionary morsedecode

Schlussel Wert

'.-' 'A'

Beispielprogramm morsen.py 1.6.5

Page 529: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-' ['A', '.-'] morsecode[z[0]] = z[1]

morsedecode[z[1]] = z[0]

B -... 'B -...' ['B', '-...']

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

'A' '.-'

Dictionary morsedecode

Schlussel Wert

'.-' 'A'

Beispielprogramm morsen.py 1.6.5

Page 530: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Morsealphabet einlesen und in Dictionaries eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in morsecode und morsedecode

A .- 'A .-' ['A', '.-'] morsecode[z[0]] = z[1]

morsedecode[z[1]] = z[0]

B -... 'B -...' ['B', '-...'] morsecode[z[0]] = z[1]

morsedecode[z[1]] = z[0]

C -.-.

D -..

...

morsecode ist ein Dictionary furdie Zuordnung von Buchstaben zu Morsezeichen.

morsedecode ist ein Dictionary furdie Zuordnung von Morsezeichen zu Buchstaben.

Dictionary morsecode

Schlussel Wert

'A' '.-'

'B' '-...'

Dictionary morsedecode

Schlussel Wert

'.-' 'A'

'-...' 'B'

Beispielprogramm morsen.py 1.6.5

Page 531: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 2: Eingabe kodieren bzw. dekodieren

Grundidee beim Kodieren eines Buchstabens:

lies den Buchstaben x und gib morsecode[x] aus

Grundidee beim Kodieren eines Morsezeichens:

lies die Zeichenfolge x und gib morsedecode[x] aus

Das muss dann fur alle Buchstaben/Morsezeichen gemacht werden.

Ob man kodieren oder dekodieren soll,

erkennt man am erste Zeichen der Eingabe.

Wenn sie . oder - ist, dann muss dekodiert werden,

und sonst muss kodiert werden.

Beispielprogramm morsen.py 1.6.6

Page 532: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# morsen.py

#--------------------------------------------------------------------------------------------------------

import sys

# Teil 1: Einlesen des Morsealphabets von standard input ------------------------------------------------

morsecode = dict() # Das Dictionary fur die Kodierung in den Morsecode.

morsedecode = dict() # Das Dictionary fur die Dekodierung aus dem Morsecode.

for zeile in sys.stdin: # Gehe durch alle Zeilen der Eingabedatei.

z = str.split(zeile) # Teile die Zeile an Folgen von Leerzeichen.

if len(z)<2: continue # Falls dabei nicht mindestens 2 Teile herauskommen: ignoriere es.

morsecode[z[0]] = z[1] # Trage die Zuordnung Zeichen->Morsezeichen in morsecode ein.

morsedecode[z[1]] = z[0] # Trage die Zuordung Morsezeichen->Zeichen in morsedecode ein.

# Teil 2: Kodieren bzw. Dekodieren der Eingabe ----------------------------------------------------------

eingabe = sys.argv[1]

ergebnis = ''

if eingabe[0] in '.-': # Falls die Eingabe mit . oder - anfangt, ist sie im Morsecode und wird dekodiert.

for c in str.split(eingabe):

ergebnis += morsedecode[c]

else: # Sonst wird die Eingabe in den Morsecode kodiert.

for zeichen in eingabe:

ergebnis += morsecode[zeichen] + ' '

# Gib das Ergebnis aus.

print(ergebnis)Beispielprogramm morsen.py 1.6.7

Page 533: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#------------------------------------------------------------------------------------------------

# python3 morsen.py INFORMATIK < morsealphabet.txt

# .. -. ..-. --- .-. -- .- - .. -.-

#

# python3 morsen.py '.. -. ..-. --- .-. -- .- - .. -.-' < morsealphabet.txt

# INFORMATIK

Beispielprogramm morsen.py 1.6.8

Page 534: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1.6 PageRank

Bei Anfragen an Suchmaschinen im Internet werden haufig Millionen von Webseiten zu einemSuchwort gefunden.

Wie kommt es zu der Reihenfolge, in der die Seiten als Suchergebnis angezeigt werden?Es scheint ja so zu sein, dass die

”besten“ Seiten am Anfang angezeigt werden . . .

Die Vermutung ist, dassauf

”wichtige“ Webseiten haufiger direkt oder indirekt von anderen Webseiten verwiesen wird.

Das wird im PageRank quantifiziert – das ist die Wahrscheinlichkeit, mit der ein Websurfer, dernach bestimmten Zufalls-Regeln (s.u.) von einer Webseite zur nachsten surft, die Seite erreicht.

Bei der Anzeige des Suchergebnisses einer Suchmaschine werden die Seiten mit absteigendemPageRank angezeigt (neben moglichen anderen Kriterien).

Das hat sich als nutzlich erwiesen.Wir wollen Programme schreiben, die fur kleine Beispiele den PageRank ausrechnen konnen.

Berechnung des PageRank 1.6.9

Page 535: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Webseiten mit Links zu anderen Seiten (Graph)

bbb.com

ddd.org

aaa.de

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

Berechnung des PageRank 1.6.10

Page 536: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Webseiten mit Links zu anderen Seiten (Graph)

bbb.com

ddd.org

aaa.de

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

Berechnung des PageRank 1.6.10

Page 537: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers (auf jeder Seite wird gezahlt, wie oft sie erreicht wird).

bbb.com

ddd.org

aaa.de

1

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

Berechnung des PageRank 1.6.10

Page 538: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers (auf jeder Seite wird gezahlt, wie oft sie erreicht wird).

bbb.com

ddd.org

aaa.de

1

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

1eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

Berechnung des PageRank 1.6.10

Page 539: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers (auf jeder Seite wird gezahlt, wie oft sie erreicht wird).

bbb.com

ddd.org

aaa.de

2

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

1eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

Berechnung des PageRank 1.6.10

Page 540: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers (auf jeder Seite wird gezahlt, wie oft sie erreicht wird).

bbb.com

ddd.org

aaa.de

2

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

1eee.eu

ccc.edu

ccc.eduddd.org

1

bbb.com

aaa.deeee.eu

Berechnung des PageRank 1.6.10

Page 541: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers (auf jeder Seite wird gezahlt, wie oft sie erreicht wird).

bbb.com

ddd.org

aaa.de

2

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

1eee.eu

ccc.edu

ccc.eduddd.org

1

bbb.com

aaa.deeee.eu

1Berechnung des PageRank 1.6.10

Page 542: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers (auf jeder Seite wird gezahlt, wie oft sie erreicht wird).

bbb.com

ddd.org

aaa.de

3

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

1eee.eu

ccc.edu

ccc.eduddd.org

1

bbb.com

aaa.deeee.eu

1Berechnung des PageRank 1.6.10

Page 543: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers mit der Wahrscheinlichkeit, auf einer Seite zu sein.

bbb.com

ddd.org

aaa.de

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

12

16

0

16 1

6 Berechnung des PageRank 1.6.10

Page 544: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Reise eines Random Surfers mit der Wahrscheinlichkeit, auf einer Seite zu sein.

bbb.com

ddd.org

aaa.de

aaa.de

ddd.org

ccc.edu

aaa.de

bbb.com

eee.eu

ccc.edu

ccc.eduddd.org

bbb.com

aaa.deeee.eu

0.2083

0.2082

0.2116

0.1612 0.2106Berechnung des PageRank 1.6.10

Page 545: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Darstellung des Netzwerks aus Webseiten und Links

Das Netzwerk liegt in einer Datei mit derAngabe seiner Links vor.

Datei NetzwerkVL07.txt:

aaa.de bbb.com

aaa.de ddd.org

bbb.com aaa.de

eee.eu aaa.de

bbb.com ccc.edu

bbb.com aaa.de

bbb.com ddd.com

ccc.edu eee.eu

ddd.com ccc.edu

eee.eu bbb.com

Im Programm kann es als Dictionary dargestelltwerden. Jede Webseite ist ein Schlussel.Der Wert zu jedem Schlussel ist ein Array aus denSeiten, zu denen ein Link geht.

Schlussel Wert

'aaa.de' [ 'bbb.com', 'ddd.org' ]

'eee.eu' [ 'aaa.de', 'bbb.com' ]

'bbb.com' [ 'aaa.de','ccc.edu','aaa.de','ddd.org']

'ddd.org' [ 'ccc.edu' ]

'ccc.edu' [ 'eee.eu' ]

Die Webseiten nennt man auch Knoten.Die Links nennt man auch Kanten.Ein Graph besteht aus Knoten und Kanten.

Berechnung des PageRank 1.6.11

Page 546: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com

aaa.de ddd.org

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

Berechnung des PageRank 1.6.12

Page 547: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com'

aaa.de ddd.org

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

Berechnung des PageRank 1.6.12

Page 548: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com']

aaa.de ddd.org

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

Berechnung des PageRank 1.6.12

Page 549: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger['aaa.de'] = []

nachfolger['aaa.de'] += ['bbb.com]'

aaa.de ddd.org

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' []

Berechnung des PageRank 1.6.12

Page 550: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger['aaa.de'] = []

nachfolger['aaa.de'] += ['bbb.com]'

aaa.de ddd.org

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com']

Berechnung des PageRank 1.6.12

Page 551: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com']

Berechnung des PageRank 1.6.12

Page 552: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org'

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com']

Berechnung des PageRank 1.6.12

Page 553: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org' ['aaa.de', 'ddd.org']

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com']

Berechnung des PageRank 1.6.12

Page 554: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org' ['aaa.de', 'ddd.org'] nachfolger[z[0]] += z[1]

bbb.com aaa.de

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com', 'ddd.org']

Berechnung des PageRank 1.6.12

Page 555: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org' ['aaa.de', 'ddd.org'] nachfolger[z[0]] += z[1]

bbb.com aaa.de 'bbb.com aaa.de'

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com', 'ddd.org']

Berechnung des PageRank 1.6.12

Page 556: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org' ['aaa.de', 'ddd.org'] nachfolger[z[0]] += z[1]

bbb.com aaa.de 'bbb.com aaa.de' ['bbb.com', 'aaa.de']

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com', 'ddd.org']

Berechnung des PageRank 1.6.12

Page 557: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org' ['aaa.de', 'ddd.org'] nachfolger[z[0]] += z[1]

bbb.com aaa.de 'bbb.com aaa.de' ['bbb.com', 'aaa.de'] nachfolger[z[0]] = []

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com', 'ddd.org']

'bbb.com' []

Berechnung des PageRank 1.6.12

Page 558: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Netzwerk einlesen und in Dictionary nachfolger eintragen

Datei zeile in sys.stdin z = str.split(zeile) Eintrag in nachfolger

aaa.de bbb.com 'aaa.de bbb.com' ['aaa.de', 'bbb.com'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

aaa.de ddd.org 'aaa.de ddd.org' ['aaa.de', 'ddd.org'] nachfolger[z[0]] += z[1]

bbb.com aaa.de 'bbb.com aaa.de' ['bbb.com', 'aaa.de'] nachfolger[z[0]] = []

nachfolger[z[0]] += z[1]

...

nachfolger ist ein Dictionary furdie Zuordnung von Seiten zu ihren Folgeseiten.

Dictionary nachfolger

Schlussel Wert

'aaa.de' ['bbb.com', 'ddd.org']

'bbb.com' ['aaa.de']

Berechnung des PageRank 1.6.12

Page 559: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Random Surfer

§ startet auf einer zufallig gewahlten Seite

§ mit Wahrscheinlichkeit 0.9: wahlt zufallig einen Link auf der Seiteund folgt ihm zu einer Nachbarseite

mit Wahrscheinlichkeit 0.1: geht zufallig zu irgendeiner Seite

§ wiederholt den letzten Schritt sehr oft

§ zahlt dabei, wie haufig welche Seite besucht wurde

das Ergebnis wird in einem Dictionary gespeichert: Schlussel Wert'aaa.de' 20846

'eee.eu' 21029

'bbb.com' 20862

'ddd.org' 16104

'ccc.edu' 21160

Berechnung des PageRank 1.6.13

Page 560: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ablauf des Programms in der Ubersicht

Die Programmteile und die Daten,

die im einen Programmteil produziert und im anderen benutzt werden:

lies ein Netzwerk von standard input

simuliere den Random Surfer in dem Netzwerk

gib die 10 Seiten mit dem hochsten PageRank aus

Netzwerk als Dictionary nachfolger

Haufigkeit der Seitenbesuche als Dictionary zaehler

Berechnung des PageRank 1.6.14

Page 561: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 1: Einlesen des Graphen

import sys, random

# Teil 1: Einlesen des Netzwerks von standard input---------------------------------------

# Lies das Netzwerk von standard input (z.B. aus Datei routes-graph.txt).

# Jede Zeile ist ein Link und besteht aus 2 Strings, die durch Leerzeichen getrennt sind.

# Der erste String ist die Startseite und der zweite die Zielseite des Links.

# nachfolger ist ein Dictionary, dessen Schlussel alle Seiten sind.

# Der Wert eines Schlussels/Seite ist ein Array mit allen Zielseiten der Seite.

# In der Eingabe mehrfach vorgekommene Zielseiten einer Seite

# kommen auch in dem Array mehrfach vor.

nachfolger = dict()

for zeile in sys.stdin:

z = str.split(zeile)

if len(z)!=2: continue

startseite = str.strip(z[0])

zielseite = str.strip(z[1])

# Falls eine Seite noch nicht im Dictionary ist, wird sie dort eingetragen.

if startseite not in nachfolger: nachfolger[startseite] = []

if zielseite not in nachfolger: nachfolger[zielseite] = []

# Die zielseite wird als Nachfolger der startseite in das Werte-Array eingetragen.

nachfolger[startseite] += [zielseite]

Berechnung des PageRank 1.6.15

Page 562: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 2: Simulation des Random Surfers

# Teil 2: Simulation des Random Surfers --------------------------------------------------------------------

# Der Random Surfer surft nach bestimmten Zufallsregeln durch das Netzwerk und besucht seine Seiten.

# Fur jede Seite wird gezahlt, wie oft er sie besucht. Dafur benutzen wir das Dictionary zaehler.

# Wieviele "Schritte" der Random Surfer insgesamt machen soll, wird von der Kommandozeile gelesen.

#-----------------------------------------------------------------------------------------------------------

# Erzeuge das Dictionary zaehler mit den Besuchszahlern fur jede Seite.

# Die Schlussel sind die Seiten, die Werte sind am Anfang alle 0.

zaehler = dict()

for schluessel in nachfolger:

zaehler[schluessel] = 0

# Wir brauchen noch ein Array mit allen Seiten, damit wir spater zufallig eine Seite wahlen konnen.

alleSeiten = list(nachfolger)

# Die Simulation des Random Surfers beginnt auf einer zufallig gewahlten Seite.

# Anschließend geht er so oft zu einer neuen Seite, wie auf der Kommandozeile angegeben ist.

aktuelleSeite = random.choice(alleSeiten)

zaehler[aktuelleSeite] += 1

for i in range(int(sys.argv[1])):

# Falls die aktuelle Seite keinen Link hat oder mit Wahrscheinlichkeit 0.1: gehe zu einer zufallig gewahlten Seite.

if len(nachfolger[aktuelleSeite])==0 or random.randrange(10)==0 :

aktuelleSeite = random.choice(alleSeiten)

# Mit Wahrscheinlichkeit 0.9: wahle zufallig einen der Links von der aktuellen Seite und benutze ihn.

else:

aktuelleSeite = random.choice(nachfolger[aktuelleSeite])

zaehler[aktuelleSeite] += 1Berechnung des PageRank 1.6.16

Page 563: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Teil 3: Ausgabe des Ergebnisses

Es sollen die 10 Seiten mit den hochsten PageRanks ausgegeben werden.

# Teil 3: Ausgabe der Ergebnisse -------------------------------------------------------------------------

# Die Top Ten werden ausgegeben.

print( 'Das Netzwerk hat %d Knoten/Seiten.' % len(zaehler) )

print( 'Die Seiten mit den hochsten PageRanks sind:' )

for j in range(min(10,len(zaehler))):

# Beginne mit der Seite, deren Schlussel als erster in zaehler vorkommt.

m = list(zaehler)[0]

# Suche die am haufigsten besuchte Seite.

# Gehe dazu durch alle Seiten und merke dir die mit dem bisher großten Zahlerwert.

for k in zaehler:

if zaehler[k] > zaehler[m]: m = k

# Gib die Seite aus und losche ihren Zahlerwert

# (damit in der nachsten Runde die nachstbeste Seite ausgegeben wird.)

print( ' %s %f' % (m, zaehler[m]/int(sys.argv[1])) )

zaehler[m] = 0

Berechnung des PageRank 1.6.17

Page 564: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Benutzung des Programms

$ python3 random_surfer.py 1000000 < GraphVL05.txt

Der Graph hat 5 Knoten/Seiten.

Die Seiten mit den hochsten PageRanks sind:

ccc.edu 0.211445

eee.eu 0.210078

aaa.de 0.208870

bbb.com 0.208570

ddd.org 0.161038

$ python3 random_surfer.py 10000000 < routes-graph.txt

Der Graph hat 3189 Knoten/Seiten.

Die Seiten mit den hochsten PageRanks sind:

DFW 0.005612

PEK 0.005186

IST 0.005094

CDG 0.004993

DME 0.004844

SIN 0.004727

JFK 0.004698

ATL 0.004663

MIA 0.004661

LAX 0.004630Berechnung des PageRank 1.6.18

Page 565: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Selbst beim kleinen Netzwerk GraphVL05.txt mit 5 Knoten und 10 Kanten gibt es nach 100000 Rundendes Random Surfers recht unterschiedliche Ergebnisse.

# python3 random_surfer.py 100000 < GraphVL05.txt

Das Netzwerk hat 5 Knoten/Seiten.

Die Seiten mit den hochsten PageRanks sind:

ccc.edu 0.210810

eee.eu 0.209920

aaa.de 0.209660

bbb.com 0.207620

ddd.org 0.161990

ccc.edu 0.211200

bbb.com 0.210670

eee.eu 0.210380

aaa.de 0.207840

ddd.org 0.159910

ccc.edu 0.212120

eee.eu 0.210000

bbb.com 0.209340

aaa.de 0.208050

ddd.org 0.160490

Es mussten also noch viel mehr Runden durchlaufen werden, bis das Ergebnis”zuverlassig“ ist.

Wie bei der Frisbee-Simulation (Vorlesung 04) erreicht man schnell gut Ergebnisse mittels wiederholtemQuadrieren der Matrix mit den Ubergangswahrscheinlichkeiten des Random Surfers zwischen den Seiten . . .

Berechnung des PageRank 1.6.19

Page 566: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wiederverwendung von Programmteilen

Um die Ubungen zu losen, muss man ein Netzwerk aus einer Datei einlesen konnen – das macht

der Programmabschnitt auf Seite 15 dieser Vorlesung.

Dazu kann man diesen Programmabschnitt in einer eigenen Datei speichern.

Wir machen das in der Datei netzwerkEinlesen.py

Dort steht jetzt also ein Programm,

das ein Netzwerk von standard input liest und im Dictionary nachfolger speichert.

1.6.20

Page 567: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# netzwerkEinlesen.py

#----------------------------------------------------------------------------------------

# Lies das Netzwerk von standard input (z.B. aus Datei routes-graph.txt).

# Jede Zeile ist ein Link und besteht aus 2 Strings, die durch Leerzeichen getrennt sind.

# Der erste String ist die Startseite und der zweite die Zielseite.

# nachfolger ist ein Dictionary, dessen Schlussel alle Seiten sind.

# Der Wert eines Schlussels/Seite ist ein Array mit allen Zielseiten der Seite.

# In der Eingabe mehrfach vorgekommene Zielseiten einer Seite

# kommen auch in dem Array mehrfach vor.

#----------------------------------------------------------------------------------------

import sys

nachfolger = dict()

for zeile in sys.stdin:

startUndZiel = str.split(zeile)

if len(startUndZiel)!=2: continue

startseite = str.strip(startUndZiel[0])

zielseite = str.strip(startUndZiel[1])

# Falls eine Seite noch nicht im Dictionary ist, wird sie dort eingetragen.

if startseite not in nachfolger: nachfolger[startseite] = []

if zielseite not in nachfolger: nachfolger[zielseite] = []

# Die zielseite wird als Nachfolger der startseite in das Werte-Array eingetragen.

nachfolger[startseite] += [zielseite]

1.6.21

Page 568: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir schreiben jetzt ein Programm netzwerkZaehlen.py,

das zahlt, wieviele Seiten und Links in dem Netzwerk sind.

Die Seitenzahl ist die Lange von nachfolger,

und die Linkzahl ist die Summe der Langen der Werte in nachfolger.

Dabei soll das Netzwerk von netzwerkEinlesen.py eingelesen werden.

Zuerst importiert das Programm netzwerkEinlesen.py.

Dadurch wird netzwerkEinlesen.py ausgefuhrt und dort das Dictionary nachfolger erzeugt.

Anschließend benutzt das Programm die Variable nachfolger aus netzwerkEinlesen.py

als netzwerkEinlesen.nachfolger.

Diese Losung ist nur ein”Krucke“ – wie es schoner geht, kommt in der nachsten Vorlesung.

1.6.22

Page 569: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

import netzwerkEinlesen

anzahlLinks = 0

for s in netzwerkEinlesen.nachfolger:

anzahlLinks += len(netzwerkEinlesen.nachfolger[s])

print( 'Das Netzwerk hat %d Seiten und %d Links.' % (len(netzwerkEinlesen.nachfolger), anzahlLinks) )

#------------------------------------------------------------------------------------------------------

# python3 netzwerkZaehlen.py < NetzwerkVL07.txt

# Das Netzwerk hat 5 Seiten und 10 Links.

#

# python3 netzwerkZaehlen.py < routes-graph.txt

# Das Netzwerk hat 3189 Seiten und 53066 Links.

#-------------------------------------------------------------------------------------------------------

1.6.23

Page 570: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

import netzwerkEinlesen

anzahlLinks = 0

for s in netzwerkEinlesen.nachfolger:

anzahlLinks += len(netzwerkEinlesen.nachfolger[s])

print( 'Das Netzwerk hat %d Seiten und %d Links.' % (len(netzwerkEinlesen.nachfolger), anzahlLinks) )

#------------------------------------------------------------------------------------------------------

# python3 netzwerkZaehlen.py < NetzwerkVL07.txt

# Das Netzwerk hat 5 Seiten und 10 Links.

#

# python3 netzwerkZaehlen.py < routes-graph.txt

# Das Netzwerk hat 3189 Seiten und 53066 Links.

#-------------------------------------------------------------------------------------------------------

Man kann die Variable nachfolger auch direkt benutzen, wenn man das erlaubt.

from netzwerkEinlesen import nachfolger

anzahlLinks = 0

for s in nachfolger:

anzahlLinks += len(nachfolger[s])

print( 'Das Netzwerk hat %d Seiten und %d Links.' % (len(nachfolger), anzahlLinks) )

1.6.23

Page 571: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

import netzwerkEinlesen

anzahlLinks = 0

for s in netzwerkEinlesen.nachfolger:

anzahlLinks += len(netzwerkEinlesen.nachfolger[s])

print( 'Das Netzwerk hat %d Seiten und %d Links.' % (len(netzwerkEinlesen.nachfolger), anzahlLinks) )

#------------------------------------------------------------------------------------------------------

# python3 netzwerkZaehlen.py < NetzwerkVL07.txt

# Das Netzwerk hat 5 Seiten und 10 Links.

#

# python3 netzwerkZaehlen.py < routes-graph.txt

# Das Netzwerk hat 3189 Seiten und 53066 Links.

#-------------------------------------------------------------------------------------------------------

Man kann die Variable nachfolger auch umbenennen.

from netzwerkEinlesen import nachfolger as graph

anzahlLinks = 0

for s in graph:

anzahlLinks += len(graph[s])

print( 'Das Netzwerk hat %d Seiten und %d Links.' % (len(graph), anzahlLinks) )

1.6.23

Page 572: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

§ Wir haben gesehen, dass man mit den bisher erlernten Mitteln bereits Programme fur

interessante Probleme schreiben kann.

§ Das Programm ist ein Beispiel fur ein datengetriebenes Programm.

Solche Programme werden haufig verwendet.

Wir konnen verschiedene Arten, Graphen zu speichern, in die von unseren Programmen

benutzte Art uberfuhren.

§ Es ist nicht immer leicht, ein fehlerfreies Programm zu schreiben.

Die Uberprufung, dass ein Programm fehlerfrei ist, erfordert grundliche Arbeit.

§ Es ist nicht immer leicht, ein schnelles Programm zu schreiben.

Die schnelle Berechnung von PageRanks großer Graphen erfordert spezielle Kenntnisse in Linearer Algebra und

Numerik.

1.6.24

Page 573: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Funktionen und Module

Funktionen erlauben (mehr als Verzweigungen und Schleifen) den Programmfluss zwischen

verschiedenen Stellen des Programmcodes hin und her springen zu lassen. Sie machen es auch

moglich, den gleichen Programmcode an verschiedenen Stellen des Programms wiederzubenutzen.

Schließlich kann man Funktionen in Module auslagern, so dass der gleiche Programmcode in

verschiedenen Programmen (Klienten) benutzt werden kann.

Die Moglichkeit, Funktionen rekursiv zu definieren, liefert eine neue Sicht auf Strukturen in

Problemen, die man mit Programmen losen will.

1. Elemente des Programmierens

2. Funktionen und Module

2.1 Definition von Funktionen

2.2 Module und Klienten

2.3 Rekursion

3. Objekt-orientierte Programmierung (erste Schritte)

4. Algorithmen

2.0.1

Page 574: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 08

2. Funktionen und Module

2.1 Definition von FunktionenDefinition von Funktionen und Gultigkeitsbereiche von Variablen

Wirkung von Funktionsaufrufen auf Argument-Variablen

Abschlussbeispiel: Bilder mit einem Stift malen

Anhang: Sortieren durch Minimum-Suche

2.2 Module und Klienten

2.3 Rekursion

2.1.1

Page 575: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2.1 Wie man Funktionen definiert

Wir haben bereits verschiedene Funktionen benutzt:

int(sys.argv[1])

print( '%d %.2f' % (jahr, t) )

math.sqrt(5)

random.randrange(1,7)

random.random()

stddraw.line(1,2, 0.1,0.2)

Aufgaben eines Programms, die klar abgegrenzt sind,

sollte man auch abgrenzen und z.B. als Funktion aufschreiben.

Dadurch bekommt der Programmcode eine bessere Struktur.

Entwicklung, Fehlersuche, Wartung und Wiederbenutzung werden einfacher.

2.1.2

Page 576: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Definition von Funktionen und Gultigkeitsbereiche von VariablenBeispiel: Der ganzzahlige 2er-Logarithmus

Der ganzzahlige 2er-Logarithmus einer ganzen Zahl ist die Anzahl,

wie oft man die Zahl ganzzahlig durch 2 teilen kann, bis 1 herauskommt.

345 hat den ganzzahligen 2er-Logarithmus 8.

28loomoon

256

ď 345 ă 29loomoon

512

Der ganzzahlige 2er-Logarithmus ist also eine Funktion,

die ein Argument auf einen Wert abbildet.

n n//2 Anzahl

345 172 1

172 86 2

86 43 3

43 21 4

21 10 5

10 5 6

5 2 7

2 1 8

Aufgabe:

schreibe ein Programm,

das den ganzzahligen 2er-Logarithmus jeder uber die Kommandozeile eingegebenen Zahl ausgibt.Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.3

Page 577: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 578: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 579: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

logd(argument)

n = 60

anzahl = 0

n = 30

anzahl = 1

n = 15

anzahl = 2

n = 7

anzahl = 3

n = 3

anzahl = 4

n = 1

anzahl = 5

return 5

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 580: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

logd(argument)

n = 60

anzahl = 0

n = 30

anzahl = 1

n = 15

anzahl = 2

n = 7

anzahl = 3

n = 3

anzahl = 4

n = 1

anzahl = 5

return 5

wert = 5

print('logd(60) = 5')

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 581: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

logd(argument)

...

return 5

wert = 5

print('logd(60) = 5')

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 582: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

logd(argument)

...

return 5

wert = 5

print('logd(60) = 5')

i = 2

argument = 23

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 583: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

logd(argument)

...

return 5

wert = 5

print('logd(60) = 5')

i = 2

argument = 23

logd(argument)

n = 23

anzahl = 0

n = 11

anzahl = 1

n = 5

anzahl = 2

n = 2

anzahl = 3

n = 1

anzahl = 4

return 4

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 584: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#--------------------------------------------------------------

# logarithmen.py

#--------------------------------------------------------------

# Liest die Argumente (int) von der Kommandozeile

# und gibt jeweils den ganzzahligen 2er-Logarithmus dazu aus.

#--------------------------------------------------------------

import sys

# Die Funktion logd(n) wird definiert.

# logd(n) gibt den ganzzahligen 2er-Logarithmus von n zuruck.

# Der ganzzahlige 2er-Logarithmus einer Zahl ist die

# Anzahl, wie oft man die Zahl ganzzahlig durch 2 teilen kann,

# bis 1 erreicht wird.

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

# -------- Hauptprogramm ------------------------------------

# Es werden die Eingaben von der Kommandozeile gelesen

# und fur jede Eingabe wird der Logarithmus ausgegeben.

for i in range (1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print( 'logd(%d) = %d' % (argument, wert) )

#--------------------------------------------------------------

Was bei der Ausfuhrung von

python logarithmen.py 60 23

(informell) passiert:

i = 1argument = 60

logd(argument)

...

return 5

wert = 5

print('logd(60) = 5')

i = 2

argument = 23

logd(argument)

n = 23

anzahl = 0

n = 11

anzahl = 1

n = 5

anzahl = 2

n = 2

anzahl = 3

n = 1

anzahl = 4

return 4

wert = 4

print('logd(23) = 4')

Eine Funktion zur Berechnung des ganzzahligen 2er-Logarithmus 2.1.4

Page 585: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Definition von Funktionen

def logd( n ):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

Signatur Funktionsname

Parameter-Variable

Funktions-Rumpf

lokale Variable

return-Anweisung

RuckgabewertProgrammcode zur Definition und zum Aufruf von Funktionen 2.1.5

Page 586: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufruf von Funktionen

for i in range(1, len(sys.argv)):

argument = int(sys.argv[i])

wert = logd( argument )

print('logd(%d)=%d' % (argument,wert))

Funktions-Aufruf

Funktionsname Argument

Programmcode zur Definition und zum Aufruf von Funktionen 2.1.6

Page 587: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gultigkeitsbereich (scope) von Variablen (1)

def logd(n):

anzahl = 0

while n>1:

n = n//2

anzahl += 1

return anzahl

for i in range(1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print('logd(%d)=%d' % (argument,wert))

Gultigkeitsbereich der Variablen

i, argument und wert

Gultigkeitsbereich der lokalen Variablen

n und anzahl

n und anzahl sind hier unbekannt

i und argument konnen hier nicht verandert werden, wert ist unbekannt

Gultigkeitsbereiche von Variablen 2.1.7

Page 588: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Gultigkeitsbereich (scope) von Variablen (2)

def logd(n):

i = 0

while n>1:

n = n//2

i += 1

return i

for i in range(1,len(sys.argv)):

argument = int(sys.argv[i])

wert = logd(argument)

print('logd(%d)=%d' % (argument,wert))

Gultigkeitsbereich von i,

argument und wert

Gultigkeitsbereich der lokalen Variablen

n und i

zwei verschiedene

Variablen

n ist hier unbekannt

argument kann nicht verandert werden, wert ist unbekannt

Gultigkeitsbereiche von Variablen 2.1.8

Page 589: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: PrimzahlenFunktion mit mehreren return-Anweisungen

Aufgabe: schreibe ein Programm, das Zahlen von der Kommandozeile einliest

und ausgibt, ob sie Primzahlen sind.

Eine Zahl n ą 1 ist eine Primzahl,

wenn sie keinen Teiler außer 1 und n hat.

Es reicht, fur n ą 1 zu testen,

ob eine der Zahlen 2, 3, 4, . . . , n ´ 1 Teiler von n ist.

Wenn man eine solche Zahl findet, dann ist n keine Primzahl.

Wenn man keine solche Zahl findet, dann ist n eine Primzahl.

Wenn n einen Teiler im Bereich 2, 3, . . . , n ´ 1 hat,

dann ist n “ a ¨ b fur a und b aus dem Bereich 2, 3, 4, . . . , n ´ 1.

Fur a ď b gilt: a ď?n.

Also reicht es, einen Teiler von n im Bereich 2, 3, . . . ,?n zu suchen. Eine Funktion zum Primzahltest 2.1.9

Page 590: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: PrimzahlenFunktion mit mehreren return-Anweisungen

Aufgabe: schreibe ein Programm, das Zahlen von der Kommandozeile einliest

und ausgibt, ob sie Primzahlen sind.

Eine Zahl n ą 1 ist eine Primzahl,

wenn sie keinen Teiler außer 1 und n hat.

Es reicht, fur n ą 1 zu testen,

ob eine der Zahlen 2, 3, 4, . . . , n ´ 1 Teiler von n ist.

Wenn man eine solche Zahl findet, dann ist n keine Primzahl.

Wenn man keine solche Zahl findet, dann ist n eine Primzahl.

Wenn n einen Teiler im Bereich 2, 3, . . . , n ´ 1 hat,

dann ist n “ a ¨ b fur a und b aus dem Bereich 2, 3, 4, . . . , n ´ 1.

Fur a ď b gilt: a ď?n.

Also reicht es, einen Teiler von n im Bereich 2, 3, . . . ,?n zu suchen. Eine Funktion zum Primzahltest 2.1.9

Page 591: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: PrimzahlenFunktion mit mehreren return-Anweisungen

Aufgabe: schreibe ein Programm, das Zahlen von der Kommandozeile einliest

und ausgibt, ob sie Primzahlen sind.

Eine Zahl n ą 1 ist eine Primzahl,

wenn sie keinen Teiler außer 1 und n hat.

Es reicht, fur n ą 1 zu testen,

ob eine der Zahlen 2, 3, 4, . . . , n ´ 1 Teiler von n ist.

Wenn man eine solche Zahl findet, dann ist n keine Primzahl.

Wenn man keine solche Zahl findet, dann ist n eine Primzahl.

Wenn n einen Teiler im Bereich 2, 3, . . . , n ´ 1 hat,

dann ist n “ a ¨ b fur a und b aus dem Bereich 2, 3, 4, . . . , n ´ 1.

Fur a ď b gilt: a ď?n.

Also reicht es, einen Teiler von n im Bereich 2, 3, . . . ,?n zu suchen. Eine Funktion zum Primzahltest 2.1.9

Page 592: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# primzahlen.py

#------------------------------------------------------------

# Liest Argumente von der Kommandozeile

# und gibt aus, ob sie Primzahlen sind.

#------------------------------------------------------------

import sys

# Funktion istPrimzahl(n) erhalt als Argument int n

# und hat Ruckgabewert True, falls n eine Primzahl ist,

# sowie Ruckgabewert False, falls n keine Primzahl ist.

def istPrimzahl( n ):

# Jede Primzahl ist >= 2.

if n<2: return False

# Teste mogliche Teiler t = 2, ... , sqrt(n).

t = 2

while t*t<=n:

# Falls t Teiler von n ist, dann ist n keine Primzahl.

if n%t==0: return False

# Sonst: nimm das nachste t.

t += 1

# Es wurde kein Teiler gefunden: also ist n Primzahl.

return True

Eine Funktion zum Primzahltest 2.1.10

Page 593: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# primzahlen.py

#------------------------------------------------------------

# Liest Argumente von der Kommandozeile

# und gibt aus, ob sie Primzahlen sind.

#------------------------------------------------------------

import sys

# Funktion istPrimzahl(n) erhalt als Argument int n

# und hat Ruckgabewert True, falls n eine Primzahl ist,

# sowie Ruckgabewert False, falls n keine Primzahl ist.

def istPrimzahl( n ):

# Jede Primzahl ist >= 2.

if n<2: return False

# Teste mogliche Teiler t = 2, ... , sqrt(n).

t = 2

while t*t<=n:

# Falls t Teiler von n ist, dann ist n keine Primzahl.

if n%t==0: return False

# Sonst: nimm das nachste t.

t += 1

# Es wurde kein Teiler gefunden: also ist n Primzahl.

return True

Was bei der Ausfuhrung von

istPrimzahl(15)

(informell) passiert:

istPrimzahl(15)

n = 15

t = 2

"2*2<=15 ist True"

"15%2==0 ist False"

t = 3

"3*3<=15 ist True"

"15%3==0 ist True"

return False

Eine Funktion zum Primzahltest 2.1.10

Page 594: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# primzahlen.py

#------------------------------------------------------------

# Liest Argumente von der Kommandozeile

# und gibt aus, ob sie Primzahlen sind.

#------------------------------------------------------------

import sys

# Funktion istPrimzahl(n) erhalt als Argument int n

# und hat Ruckgabewert True, falls n eine Primzahl ist,

# sowie Ruckgabewert False, falls n keine Primzahl ist.

def istPrimzahl( n ):

# Jede Primzahl ist >= 2.

if n<2: return False

# Teste mogliche Teiler t = 2, ... , sqrt(n).

t = 2

while t*t<=n:

# Falls t Teiler von n ist, dann ist n keine Primzahl.

if n%t==0: return False

# Sonst: nimm das nachste t.

t += 1

# Es wurde kein Teiler gefunden: also ist n Primzahl.

return True

Was bei der Ausfuhrung von

istPrimzahl(13)

(informell) passiert:

istPrimzahl(13)

n = 13

t = 2

"2*2<=13 ist True"

"13%2==0 ist False"

t = 3

"3*3<=13 ist True"

"13%3==0 ist False"

t = 4

"4*4<=13 ist False"

return True

Eine Funktion zum Primzahltest 2.1.10

Page 595: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# -------- Hauptprogramm --------------------------------

# Lies die Zahlen von der Kommandozeile

# und gib aus, ob sie Primzahlen sind.

for i in range(1,len(sys.argv)):

argument = int(sys.argv[i])

if istPrimzahl(argument):

print( '%d ist Primzahl.' % (argument) )

else:

print( '%d ist keine Primzahl.' % (argument) )

#-----------------------------------------------------------

# python primzahlen.py 0 1 2 3 4 5 12 13 14 15 16 17

# 0 ist keine Primzahl.

# 1 ist keine Primzahl.

# 2 ist Primzahl.

# 3 ist Primzahl.

# 4 ist keine Primzahl.

# 5 ist Primzahl.

# 12 ist keine Primzahl.

# 13 ist Primzahl.

# 14 ist keine Primzahl.

# 15 ist keine Primzahl.

# 16 ist keine Primzahl.

# 17 ist Primzahl.

Eine Funktion zum Primzahltest 2.1.11

Page 596: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Wirkung von Funktionsaufrufen auf Argument-Variablen

Beispielprogramm:

def inc(j):

j += 1

i = 99

inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

Argumente sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.12

Page 597: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Wirkung von Funktionsaufrufen auf Argument-Variablen

Beispielprogramm:

def inc(j):

j += 1

i = 99

inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

Argumente sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.12

Page 598: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Wirkung von Funktionsaufrufen auf Argument-Variablen

Beispielprogramm:

def inc(j):

j += 1

i = 99

inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

Argumente sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.12

Page 599: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Wirkung von Funktionsaufrufen auf Argument-Variablen

Beispielprogramm:

def inc(j):

j += 1

i = 99

inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

Argumente sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.12

Page 600: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ubergabe des Ergebnisses nach Funktionsausfuhrung

Beispielprogramm:

def inc(j):

j += 1

return j

i = 99

i = inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

i = 100

Ruckgabewerte sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.13

Page 601: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ubergabe des Ergebnisses nach Funktionsausfuhrung

Beispielprogramm:

def inc(j):

j += 1

return j

i = 99

i = inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

i = 100

Ruckgabewerte sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.13

Page 602: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ubergabe des Ergebnisses nach Funktionsausfuhrung

Beispielprogramm:

def inc(j):

j += 1

return j

i = 99

i = inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

i = 100

Ruckgabewerte sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.13

Page 603: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ubergabe des Ergebnisses nach Funktionsausfuhrung

Beispielprogramm:

def inc(j):

j += 1

return j

i = 99

i = inc(i)

Informeller Programmablauf:

i = 99

inc(i)

j = 99

j = 100

i = 100

Ruckgabewerte sind Objekt-Referenzen.

Programmablauf auf dem Objekt-Level:

i = 99 99i

Aufruf inc(i) 99i

j

j += 1 99

1

100

i

j

Nach der Ausfuhrung 99

1

100

i

Wirkung von Fuktionsaufrufen auf Variablen 2.1.13

Page 604: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Seiteneffekte bei Argumenten eines veranderbaren Datentyps

def tausche(b, i, j):

temp = b[i]

b[i] = b[j]

b[j] = temp

a = [ 17, 4, 21 ]

tausche(a, 0, 1)

a = [17, 4, 21]

17 4 21

0 1 2

3a

Wirkung von Fuktionsaufrufen auf Variablen 2.1.14

Page 605: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Seiteneffekte bei Argumenten eines veranderbaren Datentyps

def tausche(b, i, j):

temp = b[i]

b[i] = b[j]

b[j] = temp

a = [ 17, 4, 21 ]

tausche(a, 0, 1)

a = [17, 4, 21]

17 4 21

0 1 2

3a

Aufruf von tausche(a,0,1)

17 4 21

0 1 2

3a

b

0 1i j

Wirkung von Fuktionsaufrufen auf Variablen 2.1.14

Page 606: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Seiteneffekte bei Argumenten eines veranderbaren Datentyps

def tausche(b, i, j):

temp = b[i]

b[i] = b[j]

b[j] = temp

a = [ 17, 4, 21 ]

tausche(a, 0, 1)

a = [17, 4, 21]

17 4 21

0 1 2

3a

Aufruf von tausche(a,0,1)

17 4 21

0 1 2

3a

b

0 1i j

temp = b[i]

17 4 21

0 1 2

3a

b

temp

0 1i j

Wirkung von Fuktionsaufrufen auf Variablen 2.1.14

Page 607: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Seiteneffekte bei Argumenten eines veranderbaren Datentyps

def tausche(b, i, j):

temp = b[i]

b[i] = b[j]

b[j] = temp

a = [ 17, 4, 21 ]

tausche(a, 0, 1)

Aufruf von tausche(a,0,1)

17 4 21

0 1 2

3a

b

0 1i j

temp = b[i]

17 4 21

0 1 2

3a

b

temp

0 1i j

b[i] = b[j]

17 4 21

0 1 2

3a

b

temp

0

1

i

j

Wirkung von Fuktionsaufrufen auf Variablen 2.1.14

Page 608: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Seiteneffekte bei Argumenten eines veranderbaren Datentyps

def tausche(b, i, j):

temp = b[i]

b[i] = b[j]

b[j] = temp

a = [ 17, 4, 21 ]

tausche(a, 0, 1)

temp = b[i]

17 4 21

0 1 2

3a

b

temp

0 1i j

b[i] = b[j]

17 4 21

0 1 2

3a

b

temp

0

1

i

j

b[j] = temp

17 4 21

0 1 2

3a

b

temp

0

1

i

j

Wirkung von Fuktionsaufrufen auf Variablen 2.1.14

Page 609: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Seiteneffekte bei Argumenten eines veranderbaren Datentyps

def tausche(b, i, j):

temp = b[i]

b[i] = b[j]

b[j] = temp

a = [ 17, 4, 21 ]

tausche(a, 0, 1)

b[i] = b[j]

17 4 21

0 1 2

3a

b

temp

0

1

i

j

b[j] = temp

17 4 21

0 1 2

3a

b

temp

0

1

i

j

Nach der Ausfuhrung

17 4 21

0 1 2

3a

Wirkung von Fuktionsaufrufen auf Variablen 2.1.14

Page 610: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Ein Funktionsaufruf mit einer Variablen als Argument,

die eine Referenz auf ein Objekt eines unveranderbaren Datentyps ist,

andert das Objekt (und damit den Wert der Variablen) nicht.

Ein Funktionsaufruf mit einer Variablen als Argument,

die eine Referenz auf ein Objekt eines veranderbaren Datentyps ist,

kann das Objekt (und damit den Wert der Variablen) andern.

Wirkung von Fuktionsaufrufen auf Variablen 2.1.15

Page 611: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Abschlussbeispiel: Bilder mit einem Stift malen

Idee: Bilder lassen sich mit einem Bleistift malen, indem man wiederholt

§ eine Richtung von 0˝ bis 360˝ einnimmt§ in diese Richtung einen geraden Strich einer bestimmten Lange zeichnet

Bsp.: ein gleichseitiges Dreieck malt man durch:

nimm Richtung 0˝ ein

male einen 10cm langen Strich

drehe die Richtung 120˝ nach links

male einen 10cm langen Strich

drehe die Richtung 120˝ nach links

male einen 10cm langen Strich

n-Ecke mit einem Stift malen 2.1.16

Page 612: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was ist ein Stift?

Die Daten-Frage

Er hat

§ eine Position auf der Leinwand

§ eine Richtung im Bereich 0˝ . . . 360˝

§ eine Farbe

Um diese Werte zu speichern,

benutzen wir fur jeden Stift ein Dictionary mit den Schlusseln

§ 'position'

§ 'richtung'

§ 'farbe'

n-Ecke mit einem Stift malen 2.1.17

Page 613: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Funktionen zum Malen mit einem Stift

Die Funktionen sollen§ einen Stift erzeugen konnen,§ einen Strich mit einem Stift auf die Leinwand von stddraw malen, und§ die Richtung des Stiftes andern konnen.

Operation Beschreibung

neuerStift(p, r, c=stddraw.BLACK)

gibt einen Stift an Position p mit Richtung r˝

und Farbe c (default stddraw.BLACK) zuruck

male(s, laenge, sichtbar=True) Stift s malt einen Strich der Lange

laenge auf die Leinwand; die Position von Stift s wird entsprechend

geandert; falls sichtbar Wert False hat, wird nur die Position des

Stiftes verandert

drehe(s, winkel) Stift s dreht seine Richtung winkel Gradn-Ecke mit einem Stift malen 2.1.18

Page 614: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was brauchen wir noch?

stddraw.line(a,b, x,y) malt einen Strich von Punkt pa, bq nach Punkt px , yq.

Wir mussen also aus Punkt pa, bq, Winkel α und Strichlange ` den vom Stift beim Malen

erreichten Punkt ausrechnen, um den Strich mit stddraw malen zu konnen.

` ¨ cosα

`` ¨ sinα

pa, bq

α

pa` ` ¨ cosα, b ` ` ¨ sinαq

n-Ecke mit einem Stift malen 2.1.19

Page 615: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

nEck.py . . . die Funktionen fur den Stift

# nEck.py

#----------------------------------------------------------------------------------------

# Liest n von der Kommandozeile und malt ein n-Eck mit einem simulierten Stift

# in den Einheitskreis (Kreis mit Radius 1 und Mittelpunkt (0,0)).

#----------------------------------------------------------------------------------------

import sys, stddraw, math

# Zuerst werden Funktionen zum Malen mit einem Stift definiert.

# Ein Stift ist ein Dictionary mit den Attributen 'position', 'richtung' und 'farbe'.

# - position ist ein Koordinaten-Paar (x,y) fur die Position des Stiftes auf der Leinwand

# - richtung ist die Richtung (Winkel 0..360), in die der Stift malt

# - farbe ist seine Farbe

#----------------------------------------------------------------------------------------

#----------------------------------------------------------------------------------------

# neuerStift(position, richtung, farbe) gibt ein (neues) Dictionary mit den Schlusseln

# 'position', 'richtung' und 'farbe' zuruck,

# deren Werte durch die Parameter beim Funktionsaufruf gesetzt sind.

def neuerStift(position, richtung, farbe):

s = {}

s['position'] = position

s['richtung'] = richtung

s['farbe'] = farbe

return sn-Ecke mit einem Stift malen 2.1.20

Page 616: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----------------------------------------------------------------------------------------

# drehe(stift, delta) dreht stift um delta Grad.

def drehe(stift, delta):

stift['richtung'] = (stift['richtung'] + delta) % 360

#----------------------------------------------------------------------------------------

# ziel(start, laenge, winkel) gibt den Punkt zuruck,

# den man vom Punkt start mit Winkel winkel in Lange laenge erreicht.

def ziel(start, laenge, winkel):

x_ziel = start[0] + laenge * math.cos(math.radians(winkel))

y_ziel = start[1] + laenge * math.sin(math.radians(winkel))

return (x_ziel, y_ziel)

#----------------------------------------------------------------------------------------

# male(stift, laenge, sichtbar) bewegt stift entlang einer Linie der Lange laenge.

# Falls sichtbar Wert True hat, wird die Linie auf die Leinwand von stddraw gemalt.

# Anderenfalls wird nur die Position des Stiftes verandert und nicht gemalt.

def male(stift, laenge, sichtbar=True):

# Die Linie geht von der jetzigen Position startpunkt des Stiftes

# zu seiner neuen Position.

# Zuerst wird die neue Position zielpunkt berechnet und zur Position des Stiftes.

# Falls gemalt werden soll, wird ein Strich von startpunkt zu zielpunkt gemalt.

startpunkt = stift['position']

zielpunkt = ziel(startpunkt, laenge, stift['richtung'])

stift['position'] = zielpunkt

if sichtbar:

# Male die Linie auf die Leinwand.

stddraw.setPenColor(stift['farbe'])

stddraw.line(startpunkt[0], startpunkt[1], zielpunkt[0], zielpunkt[1])

stddraw.show(100)

n-Ecke mit einem Stift malen 2.1.21

Page 617: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Was wollen wir mit dem Stift malen?

Wir wollen ein Programm schreiben,

das mit einem Stift ein n-Eck malt (n wird eingegeben).

Das n-Eck soll in den Einheitskreis mit Radius 1 und Mittelpunkt p0, 0q gemalt werden.

n-Ecke mit einem Stift malen 2.1.22

Page 618: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

72˝

Der Einheitskreis hat Radius 1 und Mittelpunkt p0, 0q.

Ein regelmaßiges n-Eck besteht aus n gleichen

Dreiecken.

Fur ein regelmaßiges n-Eck im Einheitskreis

ist 2α “ 360n (also α “ 180

n).

Es kann im Punkt pcos 180n ,´ sin 180

n q beginnen,

die Stiftrichtung ist dann 90˝, und

die Seitenlange ist 2 ¨ sin 180n .

Nach dem Malen einer Seite wird der Stift um360n

˝gedreht.

n-Ecke mit einem Stift malen 2.1.23

Page 619: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

72˝

Der Einheitskreis hat Radius 1 und Mittelpunkt p0, 0q.

Ein regelmaßiges n-Eck besteht aus n gleichen

Dreiecken.

Fur ein regelmaßiges n-Eck im Einheitskreis

ist 2α “ 360n (also α “ 180

n).

Es kann im Punkt pcos 180n ,´ sin 180

n q beginnen,

die Stiftrichtung ist dann 90˝, und

die Seitenlange ist 2 ¨ sin 180n .

Nach dem Malen einer Seite wird der Stift um360n

˝gedreht.

n-Ecke mit einem Stift malen 2.1.23

Page 620: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

72˝

α

1

pcosα, sinαq

pcosα,´ sinαq

sinα

Der Einheitskreis hat Radius 1 und Mittelpunkt p0, 0q.

Ein regelmaßiges n-Eck besteht aus n gleichen

Dreiecken.

Fur ein regelmaßiges n-Eck im Einheitskreis

ist 2α “ 360n (also α “ 180

n).

Es kann im Punkt pcos 180n ,´ sin 180

n q beginnen,

die Stiftrichtung ist dann 90˝, und

die Seitenlange ist 2 ¨ sin 180n .

Nach dem Malen einer Seite wird der Stift um360n

˝gedreht.

n-Ecke mit einem Stift malen 2.1.23

Page 621: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

nEck.py . . . die Funktionen zum Malen des n-Ecks

# Nun schreiben wir eine Funktion, die das n-Eck malt, und eine Funktion, die die Leinwand vorbereitet.

#--------------------------------------------------------------------------------------------------------------

# male_nEck(n, f=stddraw.BLACK) malt ein regelmaßiges n-Eck mit Farbe f in den Einheitskreis.

def male_nEck(n, f=stddraw.BLACK):

# Die Seitenlange eines regelmaßigen n-Ecks im Einheitskreis ist:

seitenlaenge = 2*math.sin(math.radians(180/n))

# Erzeuge einen Stift mit Farbe f,

# setze ihn auf eine Startposition auf den Einheitskreis, die man von (0,0) im Winkel -1/2 * 360/n erreicht,

# und stelle seine Richtung auf 90 Grad ein.

s = neuerStift( (math.cos(math.radians(180/n)),-math.sin(math.radians(180/n))), 90, f )

# Male mit Stift s ein n-Eck.

for j in range(n):

male(s, seitenlaenge)

drehe(s, 360/n)

#--------------------------------------------------------------------------------------------------------------

# richteLeinwandEin() stellt die Große der Leinwand von stddraw so ein,

# dass der Einheitskreis (das ist der Kreis mit Radius 1 und Mittelpunkt (0,0))

# darauf passt. Der Einheitskreis wird weiß gemalt, der Rest der Leinwand ist schwarz.

def richteLeinwandEin():

stddraw.setCanvasSize(800,800)

stddraw.setXscale(-1,1)

stddraw.setYscale(-1,1)

stddraw.clear(stddraw.BLACK)

stddraw.setPenColor(stddraw.WHITE)

stddraw.filledCircle(0,0,1)

n-Ecke mit einem Stift malen 2.1.24

Page 622: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Hauptprogramm von nEck.py

#----------------------------------------------------------------------------------------------------------

# Das Hauptprogramm liest int n von der Kommandozeile. Anschließend wird ein n-Eck gemalt und angezeigt.

n = int(sys.argv[1])

richteLeinwandEin()

stddraw.setPenRadius(0.01)

male_nEck(n, stddraw.BOOK_BLUE)

stddraw.show()

#----------------------------------------------------------------------------------------------------------

python3 nEck.py 5 python3 nEck.py 7 python3 nEck.py 12n-Ecke mit einem Stift malen 2.1.25

Page 623: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Funktionen mit Ruckgabewerten:

neuerStift (Ruckgabewert vom Typ dict)

ziel (Ruckgabewert vom Typ tuple, auch Beispiel fur”mehr als ein Ruckgabewert“)

Funktionen ohne Ruckgabewerte:

drehe(s, delta) hat Seiteneffekt auf Stift s

male(stift, laenge, sichtbar=True) hat Seiteneffekt auf

Stift stift und Leinwand von stddraw

male_nEck(n, f=stddraw.BLACK) hat Seiteneffekt auf Leinwand von stddraw

richteLeinwandEin() hat Seiteneffekt auf Leinwand von stddraw

Funktion mit optionalem Parameter:

male(stift, laenge, sichtbar=True) kann aufgerufen werden durch

male(s, l, t) (Parameter-Variable sichtbar erhalt Wert t) oder

male(s, l) (Parameter-Variable sichtbar erhalt Default-Wert True)

male_nEck(n, f=stddraw.BLACK) kann aufgerufen werden durch

male_nEck(n, c) (Parameter-Variable f erhalt Wert c) oder

male_nEck(n) (Parameter-Variable f erhalt Default-Wert stddraw.BLACK)n-Ecke mit einem Stift malen 2.1.26

Page 624: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

§ Durch Definition und Benutzung von Funktionen hat man beim Programmieren neue

Moglichkeiten zum Strukturieren von Programmen.

§ Man muss sich den Ablauf eines Programms nicht mehr Schritt fur Schritt in elementaren

Anweisungen vorstellen, sondern kann abstrakter uber Funktionsaufrufe und Ruckgabewerte

argumentieren.

§ Programme kann man aufschreiben als Definition von Funktionen gefolgt von einem

Hauptprogramm.

§ Der Programmcode wird dadurch einfacher

zu entwickeln, zu verstehen, zu verbessern und zu warten.

§ Dadurch lassen sich auch”kompliziertere“ Anwendungen programmieren.

2.1.27

Page 625: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Sortieren eines Arrays durch Minimum-Suchen

Aufgabe:

sortiere beliebig viele Zahlen in aufsteigender Reihenfolge.

Anhang: Sortieren durch Minimum-Suche 2.1.28

Page 626: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Sortieren eines Arrays durch Minimum-Suchen

Aufgabe:

sortiere beliebig viele Zahlen in aufsteigender Reihenfolge.

Idee des Sortierens mittels Minimum-Suche:

suche im Array a das kleinste Element

tausche es an die Stelle a[0]

suche im Array a[1:] das kleinste Element

tausche es an die Stelle a[1]

suche im Array a[2:] das kleinste Element

tausche es an die Stelle a[2]

a[0] a[1] a[2] a[3]

16 22 12 18

12 22 16 18

Anhang: Sortieren durch Minimum-Suche 2.1.28

Page 627: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Sortieren eines Arrays durch Minimum-Suchen

Aufgabe:

sortiere beliebig viele Zahlen in aufsteigender Reihenfolge.

Idee des Sortierens mittels Minimum-Suche:

suche im Array a das kleinste Element

tausche es an die Stelle a[0]

suche im Array a[1:] das kleinste Element

tausche es an die Stelle a[1]

suche im Array a[2:] das kleinste Element

tausche es an die Stelle a[2]

a[0] a[1] a[2] a[3]

16 22 12 18

12 22 16 18

12 16 22 18

Anhang: Sortieren durch Minimum-Suche 2.1.28

Page 628: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Sortieren eines Arrays durch Minimum-Suchen

Aufgabe:

sortiere beliebig viele Zahlen in aufsteigender Reihenfolge.

Idee des Sortierens mittels Minimum-Suche:

suche im Array a das kleinste Element

tausche es an die Stelle a[0]

suche im Array a[1:] das kleinste Element

tausche es an die Stelle a[1]

suche im Array a[2:] das kleinste Element

tausche es an die Stelle a[2]

a[0] a[1] a[2] a[3]

16 22 12 18

12 22 16 18

12 16 22 18

12 16 18 22

Anhang: Sortieren durch Minimum-Suche 2.1.28

Page 629: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Sortieren eines Arrays durch Minimum-Suchen

Aufgabe:

sortiere beliebig viele Zahlen in aufsteigender Reihenfolge.

Idee des Sortierens mittels Minimum-Suche:

suche im Array a das kleinste Element

tausche es an die Stelle a[0]

suche im Array a[1:] das kleinste Element

tausche es an die Stelle a[1]

suche im Array a[2:] das kleinste Element

tausche es an die Stelle a[2]

a[0] a[1] a[2] a[3]

16 22 12 18

12 22 16 18

12 16 22 18

12 16 18 22

Etwas formaler:

for i in range(len(a)-1):

suche in a[i:] das kleinste Element a[j]

tausche a[i] und a[j]Anhang: Sortieren durch Minimum-Suche 2.1.28

Page 630: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anhang: Sortieren eines Arrays durch Minimum-Suchen

Aufgabe:

sortiere beliebig viele Zahlen in aufsteigender Reihenfolge.

Etwas formaler:

for i in range(len(a)-1):

suche in a[i:] das kleinste Element a[j]

tausche a[i] und a[j]

Struktur des Programms:

Funktion zum Suchen des Index des kleinsten Elements im Abschnitt des Arrays

Funktion zum Tauschen zweier Eintrage (gegeben durch Indizes) eines Array

Funktion zum Sortieren eines Arrays

Hauptprogramm zum

Einlesen der Zahlen

Aufruf der Sortier-Funktion

Ausgabe des Ergebnisses

Anhang: Sortieren durch Minimum-Suche 2.1.28

Page 631: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# minsort.py

#-----------------------------------------------------------------------------------------------

# Lies Zahlen (int) von der Kommandozeile und gib sie sortiert in aufsteigender Reihenfolge aus.

#-----------------------------------------------------------------------------------------------

import sys

# tausche(a,i,j) erhalt Array a, int i und int j als Argumente

# und tauscht die Eintrage a[i] und a[j] von a (als Seiteneffekt).

def tausche(a, i, j):

(a[i], a[j]) = (a[j], a[i])

# indexDesMinimums(a,anfang) erhalt Array a und int anfang als Argumente.

# Ruckgabewert ist der Index des kleinsten Eintrags in a[anfang:].

def indexDesMinimums(a, anfang):

indexDesMins = anfang

for i in range(anfang+1,len(a)):

if a[indexDesMins] > a[i] : indexDesMins = i

return indexDesMins

# minSortierung(a) erhalt Array a als Parameter und sortiert a (als Seiteneffekt) aufsteigend.

def minSortierung(a):

for i in range(len(a)-1):

# print(a) # Ausgabe zum Testen des Programms

# Bestimme den Index des kleinsten Elementes in a[i:]

k = indexDesMinimums(a, i)

# Tausche das kleinste Element von a[i:] in a[i].

tausche(a, i, k) Anhang: Sortieren durch Minimum-Suche 2.1.29

Page 632: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#----- Hauptprogramm ---------------------------------------------------

# Kopiere die Zahlen aus der Kommandozeile in ein Array a.

a = []

for i in range(1,len(sys.argv)):

a += [int(sys.argv[i])]

# Sortiere das Array a und gib es aus.

minSortierung(a)

print(a)

#------------------------------------------------------------------------

Aufruf des Programms mit Ausgabe zum Testen:

python minsort.py 2 -2 89 -34 25 -12 -13 13 999 23 15

[2, -2, 89, -34, 25, -12, -13, 13, 999, 23, 15]

[-34, -2, 89, 2, 25, -12, -13, 13, 999, 23, 15]

[-34, -13, 89, 2, 25, -12, -2, 13, 999, 23, 15]

[-34, -13, -12, 2, 25, 89, -2, 13, 999, 23, 15]

[-34, -13, -12, -2, 25, 89, 2, 13, 999, 23, 15]

[-34, -13, -12, -2, 2, 89, 25, 13, 999, 23, 15]

[-34, -13, -12, -2, 2, 13, 25, 89, 999, 23, 15]

[-34, -13, -12, -2, 2, 13, 15, 89, 999, 23, 25]

[-34, -13, -12, -2, 2, 13, 15, 23, 999, 89, 25]

[-34, -13, -12, -2, 2, 13, 15, 23, 25, 89, 999]

[-34, -13, -12, -2, 2, 13, 15, 23, 25, 89, 999]

Aufruf des Programms (ohne Ausgabe zum Testen):

python minsort.py 12 14 27 13 89 45 23 111 1

[1, 12, 13, 14, 23, 27, 45, 89, 111]

Anhang: Sortieren durch Minimum-Suche 2.1.30

Page 633: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Objekt-orientierte Programmierung (erste Schritte)

3. Objekt-orientierte Programmierung (erste Schritte)

3.1 Benutzung von Daten-Typen

Page 634: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 10

3. Objekt-orientierte Programmierung (erste Schritte)

3.1 Benutzung von Daten-TypenDatentyp Color

Datentypen fur Strings und Datenstrome

Datentyp Picture

Schreiben wie Goethe oder Schiller

Anhang: Sortieren durch Minimum-Suche 3.1.1

Page 635: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3.1 Benutzung von Datentypen

Datentypen dienen der Speicherung bestimmter Daten

§ Array: Folge beliebiger Daten, Zugriff uber Index

§ Dictionary: (ungeordnete) Menge von Schlusseln und Werten, Zugriff uber Schlussel

§ str: Folge von Zeichen

§ stddraw: Leinwand zum Bemalen

und der Bereitstellung von Funktionen/Methoden zu deren Manipulation

§ Array: z.B. Zuweisung, durchlaufe alle Elemente, finde das Maximum aller Elemente

§ Dictionary: z.B. Zuweisung, durchlaufe alle Elemente

§ str: z.B. Zuweisung, Konkatenation

§ stddraw: z.B. male einen Strich, losche die Leinwand

In dieser Vorlesung wollen wir nochmal ansehen, wie die Benutzung von Datentypen geht.

Im nachsten Semester geht es auch darum, wie man eigene Datentypen implementiert.

Anhang: Sortieren durch Minimum-Suche 3.1.1

Page 636: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Der Datentyp Color

Auf der Titelseite der FAZ vom 26.6.2019 stand eine

Graphik uber die Entwicklung der Jahresdurchschnitts-

temperatur an einem nicht genannten Ort seit 1850.

Fur jedes Jahr steht von links nach rechts ein vertikaler

Balken.

Ein weißer Balken steht dafur, dass die

Durschnittstemperatur des Jahres (etwa) das Mittel der

Temperaturen seit 1850 ist. Je weiter die

Jahresdurchschnittstemperatur unter dem Mittelwert liegt,

desto dunkleblauer ist der Ballen,

und je weiter sie uber dem Mittelwert liegt, desto

dunkelroter wird der Balken.

Wir wollen eine solche Graphik fur Jena (oder andere Orte)

malen.Datentyp Color 3.1.2

Page 637: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Eine abstrakte Vorstellung von Farbe

Jede Farbe setzt sich aus rot, grun und blau in unterschiedlichen Intensitaten zusammen.

Bei maximaler Intensitat aller Farben zusammen erhalten wir weiß,

bei minimaler Intensitat schwarz.

Farben werden durch Tripel pr , g , bq angegeben,

bei denen r die Intensitat von rot,

g die Intensitat von grun und

b die Intensitat von blau angibt.

Jede Intensitat ist eine ganze Zahl aus dem Bereich 0 . . . 1.

Datentyp Color 3.1.3

Page 638: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die API des Datentyps Color in color.py

Color(r,g,b) eine neue Farbe mit Rot-, Grun- und Blau-Bestandteilen r, g und b;

r, g und b sind int-Werte aus dem Bereich 0 . . . 255

c.getRed() der Rot-Bestandteil der Farbe c

c.getGreen() der Grun-Bestandteil der Farbe c

c.getBlue() der Blau-Bestandteil der Farbe c

str(c) Darstellung der Farbe c als String pR,G ,Bq

Color() ist der Konstruktor und erzeugt ein neues Objekt von Typ Color.

getRed(), getGreen() und getBlue() sind Methoden des Datentyps Color.

Sie werden auf Objekte vom Typ Color angewendet.

str() ist eine Funktion, die es fur jeden Datentyp geben soll.

(Es gibt keine Methoden zum Andern eines Color-Objektes.)Datentyp Color 3.1.4

Page 639: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die API des Moduls stddraw im Buch

Farb-Objekte vom Typ Color konnen

als Farben bei stddraw verwendet

werden.

Datentyp Color 3.1.5

Page 640: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Farbverlauf von rot

Color(0, 0, 0) ist schwarz und Color(255, 255, 255) ist weiß.

Ein”richtiges“ rot ist Color(255, 0, 0).

Eine Farbe Color(i, 0, 0) mit 0<i<255 ist ein”dunkleres“ rot:

je kleiner i ist, des dunkler ist das rot.

Eine Farbe Color(255, i, i) mit 0<i<255 ist ein”helleres“ rot:

je großer i ist, desto heller ist das rot.

Wir schreiben ein Programm, das den Farbverlauf vom dunkelsten bis zum hellsten rot malt.

Datentyp Color 3.1.6

Page 641: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# rot_farbverlauf.py

#---------------------------------------------------------------------------------------

# Malt den Farbverlauf von rot in Streifen auf die Leinwand von stddraw.

# Color(0,0,0), Color(1,0,0),...,Color(255,0,0),Color(255,1,1),...,Color(255,255,255)

# Rot-Ton: 0 1 ... 255 256 ... 510

#---------------------------------------------------------------------------------------

import stddraw, color

#---------------------------------------------------------------------------------------

# rot(n) gibt ein Color-Objekt mit Rot-Ton n gemaß der obigen Darstellung zuruck.

def rot(n):

if n<=255: c = color.Color( n, 0, 0 )

else: c = color.Color( 255, n-255, n-255)

return c

#---------------------------------------------------------------------------------------

# Das Hauptprogramm richtet eine Leinwand mit x-Skala 0...510 ein

# und malt fur jedes n in 0...510 einen Streifen mit Farbe rot(n) an x-Position n.

#---------------------------------------------------------------------------------------

def hauptprogramm():

stddraw.setCanvasSize(1200,800)

stddraw.setXscale(0,510)

for i in range(0,511):

c = rot(i)

stddraw.setPenColor(c)

stddraw.filledRectangle(i, 0, 1.4, 1)

stddraw.show()

#----------------------------------------------------------------------------------------------

if __name__=='__main__': hauptprogramm()

#----------------------------------------------------------------------------------------------

Datentyp Color 3.1.7

Page 642: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

python3 rot_farbverlauf.py

Hier wurden die Streifen mit Breite 1 gemalt:

stddraw.filledRectangle(i, 0, 1, 1)

Durch Rundungsfehler von stddraw (das Bild ist

1200 Pixel breit und hat 511 ganzzahlige

x-Positionen) werden dabei nicht alle Pixel der

Leinwand bemalt und es entstehen dunne weiße

Streifen, die man nicht haben will.

python3 rot_farbverlauf.py

Hier wurden die Streifen mit Breite 1.4 gemalt:

stddraw.filledRectangle(i, 0, 1.4, 1)

Dadurch werden alle Rundungsfehler ubermalt . . .

Datentyp Color 3.1.8

Page 643: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Farbverlaufe fur alle Farben

Funktionen, die eine der drei Grundfarben rot, grun und blau im angegebenen Ton zuruckgeben,

konnen wir genauso implementieren.

# farbverlaeufe.py

#---------------------------------------------------------------------------------------

# Stellt Funktionen fur Farbverlaufe von rot, blau und grun zur Verfugung.

# Fur rot ist der Verlauf

# Color(0,0,0), Color(1,0,0),...,Color(255,0,0),Color(255,1,1),...,Color(255,255,255)

# Rot-Ton: 0 1 255 256 510

# Fur die anderen Farben ist das entsprechend.

#---------------------------------------------------------------------------------------

import stddraw, color

#---------------------------------------------------------------------------------------

# rot(n) gibt ein Color-Objekt mit Rot-Ton n gemaß der obigen Darstellung zuruck.

def rot(n): return color.Color( min(n,255), max(0,n-255), max(0,n-255) )

#---------------------------------------------------------------------------------------

# gruen(n) gibt ein Color-Objekt mit Grun-Ton n gemaß der obigen Darstellung zuruck.

def gruen(n): return color.Color( max(0,n-255), min(n,255), max(0,n-255) )

#---------------------------------------------------------------------------------------

# blau(n) gibt ein Color-Objekt mit Blau-Ton n gemaß der obigen Darstellung zuruck.

def blau(n): return color.Color( max(0,n-255), max(0,n-255), min(n,255) )

Datentyp Color 3.1.9

Page 644: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nun konnen wir Farbverlaufe der drei Farben malen.

# farbverlaeufe.py (Fortsetzung)

#---------------------------------------------------------------------------------------

# Das Testprogramm malt den Farbverlauf von blau beginnend mit schwarz

# und dahinter den Farbverlauf von rot beginnend mit weiß

# und dahinter den Farbverlauf von grun beginnend mit schwarz.

#--------------------------------------------------------------

def testprogramm():

stddraw.setCanvasSize(1200,800)

stddraw.setXscale(0,1541)

for i in range(0,511):

stddraw.setPenColor( blau(i) )

stddraw.filledRectangle(i, 0, 1.8, 1)

stddraw.setPenColor( rot(510-i) )

stddraw.filledRectangle(510+i, 0, 1.8, 1)

stddraw.setPenColor( gruen(i) )

stddraw.filledRectangle(1020+i, 0, 1.8, 1)

stddraw.show()

#---------------------------------------------------------------------------------------

if __name__=='__main__': testprogramm()

Datentyp Color 3.1.10

Page 645: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Nun konnen wir Farbverlaufe der drei Farben malen.

# farbverlaeufe.py (Fortsetzung)

#---------------------------------------------------------------------------------------

# Das Testprogramm malt den Farbverlauf von blau beginnend mit schwarz

# und dahinter den Farbverlauf von rot beginnend mit weiß

# und dahinter den Farbverlauf von grun beginnend mit schwarz.

#--------------------------------------------------------------

def testprogramm():

stddraw.setCanvasSize(1200,800)

stddraw.setXscale(0,1541)

for i in range(0,511):

stddraw.setPenColor( blau(i) )

stddraw.filledRectangle(i, 0, 1.8, 1)

stddraw.setPenColor( rot(510-i) )

stddraw.filledRectangle(510+i, 0, 1.8, 1)

stddraw.setPenColor( gruen(i) )

stddraw.filledRectangle(1020+i, 0, 1.8, 1)

stddraw.show()

#---------------------------------------------------------------------------------------

if __name__=='__main__': testprogramm()

python3 farbverlaeufe.py

Datentyp Color 3.1.10

Page 646: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Leuchtdichte einer Farbe

Die Leuchtdichte (Luminanz) einer RGB-Farbe pr , g , bq ist

E pr , g , bq “ 0.299 ¨ r ` 0.587 ¨ g ` 0.114 ¨ b .

Man benutzt sie, um Farbfotos schwarz-weiß zu drucken.

Eine RGB-Farbe px , x , xq mit gleichem Anteil aller Farben erscheint uns grau.

Ersetzt man in einem Farbfoto jede Farbe pr , g , bq durch pE pr , g , bq,E pr , g , bq,E pr , g , bqq,

konnen wir das entstandene Schwarz-Weiß-Bild gut erkennen.

Die Leuchtdichte ist auch wichtig beim farbigen Schreiben auf farbigem Hintergrund.

Die Differenz der Leuchtdichten der beiden Farben sollte mindestens 128 sein.

Anderenfalls kann man die Schrift nicht deutlich erkennen.

Datentyp Color 3.1.11

Page 647: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufgabe:

Schreibe ein Programm, das

die RGB-Werte fur zwei Farben von der Kommandozeile einliest

und

ein Rechteck mit der einen Farbe malt und

die Leuchtdichten der Farben in der anderen Farbe darauf schreibt.

Die Funktion zur Berechnung der Leuchtdichte soll spater auch in anderen Programmen benutzbar

sein.

Das soll uns verdeutlichen, dass die Schrift bei großem Leuchtdichten-Unterschied besser zu lesen ist.

Datentyp Color 3.1.12

Page 648: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# luminanz.py

#----------------------------------------------------------------------------------------------------

import sys, stddraw, color

#----------------------------------------------------------------------------------------------------

# farbeEinlesen(i) nimmt sys.argv[i], sys.argv[i+1], sys.argv[i+2] als drei RGB-Parameter

# und gibt die Farbe (Typ color) zuruck.

def farbeEinlesen(i):

return color.Color(int(sys.argv[i]),int(sys.argv[i+1]),int(sys.argv[i+2]))

#----------------------------------------------------------------------------------------------------

# luminanz(farbe) gibt die Luminanz von farbe (Typ Color) zuruck.

def luminanz(farbe):

l = 0.299*farbe.getRed() + 0.587*farbe.getGreen() + 0.114*farbe.getBlue()

return int(round(l))

#----------------------------------------------------------------------------------------------------

def modultest():

# Lies zwei Farben f1 und f2 von der Kommandozeile ein.

f1 = farbeEinlesen(1)

f2 = farbeEinlesen(4)

# Male ein Rechteck mit Farbe f1.

stddraw.setPenColor(f1)

stddraw.filledRectangle(0.2,0.4,0.6,0.2)

# Schreibe die Luminanz von f1 und f2 und deren Differenz in Farbe f2 darauf.

stddraw.setPenColor(f2)

stddraw.text( 0.5,0.5, "Die Farben haben Luminanz %d und %d." % (luminanz(f1), luminanz(f2)) )

stddraw.text( 0.5,0.45, "Die Differenz der Luminanzen ist %d." % abs(luminanz(f1)-luminanz(f2)) )

stddraw.show()

#----------------------------------------------------------------------------------------------------

if __name__ == '__main__': modultest()

Datentyp Color 3.1.13

Page 649: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

python3 luminanz.py 50 100 80 167 10 225

python3 luminanz.py 5 220 225 167 10 225

Datentyp Color 3.1.14

Page 650: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Datentyp Color 3.1.15

Page 651: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Datentyp Color 3.1.15

Page 652: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Modulname

Datentyp Color 3.1.15

Page 653: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Datentyp Color 3.1.15

Page 654: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Variablenname

Datentyp Color 3.1.15

Page 655: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Methode fur Objekt vom Typ ColorVariablenname

Datentyp Color 3.1.15

Page 656: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Methode fur Objekt vom Typ Color

Aufruf einer Color Methode

Variablenname

Datentyp Color 3.1.15

Page 657: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Methode fur Objekt vom Typ Color

Aufruf einer Color Methode

Variablenname

Datentyp Color 3.1.15

Page 658: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Methode fur Objekt vom Typ Color

Aufruf einer Color Methode

Variablenname

Funktion aus Modul stddraw

Datentyp Color 3.1.15

Page 659: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Der Unterschied zwischen Methoden und Funktionen

a = 100

f = color.Color(a,a/2,a/3)

g = f.getGreen()

stddraw.setPenColor(f)

Objekt vom Typ int

Objekt vom Typ Color

Modulname

Methode fur Objekt vom Typ Color

Aufruf einer Color Methode

Variablenname

Funktion aus Modul stddraw

Aufruf einer Funktion aus Modul stddraw

Datentyp Color 3.1.15

Page 660: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Datentypen fur Strings und Datenstrome

API einiger Methoden (es gibt sehr viele) fur den Datentyp str:

str('text') gibt ein str-Objekt mit dem Inhalt text zuruck;

abkurzende Schreibweise ist 'text'

s[i] gibt das i-te Zeichen von String s zuruck;

wie bei Arrays beginnt die Zahlung mit 0

s.split() gibt ein Array mit den Token von String s zuruck;

ein Token ist eine verbundene Folge von Zeichen ohne Leerzeichen, Tabulator und

Zeilenumbruch

s.rstrip() gibt das str-Objekt zuruck, das aus String s entsteht, indem Leerz., Tabulat. und

Zeilenumbruche am Ende entfernt werden

s.isnumeric() gibt True zuruck, falls String s nur aus Ziffern besteht (Python3)

s.find(t) gibt den kleinsten Index (int) zuruck, an dem String t in String s beginnt (bzw.

´1, falls t nicht vorkommt)

s.replace(alt,neu) gibt ein str-Objekt zuruck, das aus String s entsteht,

indem jedes Vorkommen des Strings alt durch den String neu ersetzt wird.

Datentypen str und TextIOWrapper 3.1.16

Page 661: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Datentyp fur Datenstrome

API wichtiger Methoden zum Lesen eines Datenstroms:

open(name, 'r') ein Datenstrom wird geoffnet und ein DS-Objekt zum Lesen wird

zuruckgegeben; es entsteht aus der Datei name

d.readline() die nachste Zeile (string) im Datenstrom d; das Zeilenende '\n'

steht am Ende der Zeile; falls das Dateiende erreicht ist, wird der

leere String '' zuruckgegeben

d.readlines() alle Zeilen (string) des Datenstroms d

d.close() schließt den Datenstrom d

sys.stdin ist DS-Objekt fur standard input.

Datentypen str und TextIOWrapper 3.1.17

Page 662: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

API wichtiger Methoden zum Schreiben eines Datenstroms:

open(name, 'w') ein Datenstrom wird geoffnet und ein DS-Objekt zum Schreiben wird

zuruckgegeben;

der Datenstrom schreibt in die Datei name; falls die Datei bereits existiert,

wird ihr alter Inhalt geloscht

open(name, 'a') ein Datenstrom wird geoffnet und ein DS-Objekt zum Schreiben wird

zuruckgegeben;

der Datenstrom schreibt in die Datei name; falls die Datei bereits existiert,

wird der Datenstrom angehangt

d.write(s) hangt s (Typ string) an den Datenstrom d

d.close() schließt den Datenstrom d

sys.stdout ist DS-Objekt fur standard output.

Datentypen str und TextIOWrapper 3.1.18

Page 663: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Graphische Darstellung der Entwicklung der

Jahresdurchschnittstemperaturen

Aufgabe:

Stelle die Entwicklung der durchschnittlichen Jahrestemperaturen (in Jena) graphisch durch ein

Streifendiagramm dar. Fur jedes Jahr wird ein Streifen gemalt. Seine Farbe stellt die Abweichung

von der Durchschnittstemperatur aller Jahre dar.

Ist die Abweichung negativ, wird sie durch den Farbverlauf von blau von dunkel zu hell dargestellt.

Je weiter ein Jahr unter der Durschnittstemperatur liegt, desto dunkler wird es blau dargestellt.

Ist die Abweichung positiv, wird sie durch den Farbverlauf von rot von hekk zu dunkel dargestellt.

Je weiter ein Jahr uber der Durchschnittstemperatur liegt, desto dunkler wird es ro dargestellt.

Jahre mit einer durchschnittlichen Temperatur werden sehr hell dargestellt.

Datentypen str und TextIOWrapper 3.1.19

Page 664: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Grobe Struktur des Programmablaufs

Eingabe: 1824 13.50

1825 13.38

...

2017 15.85

2018 16.94

filtere die Temperaturen aus der Datei

[ 13.50, 13.38, ..., 15.85, 16.94 ]

wandele die Temperaturen in Farben um

und male sie als Streifen auf die Leinwand

Modul farbverlaeufe.py

rot(n) gibt Farbe mit Rot-Ton n zuruck

gruen(n) gibt Farbe mit Grun-Ton n zuruck

blau(n) gibt Farbe mit Blau-Ton n zuruck

Datentypen str und TextIOWrapper 3.1.20

Page 665: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# temperaturStreifen.py

#------------------------------------------------------------------------------------------------------

# Liest den Namen einer Datei von der Kommandozeile, deren Zeilen aus einer Jahreszahl und

# einem Zahlenwert (float) bestehen (z.B. Jahresdurchschnittstemperaturen).

# Die Zahlenwerte werden als Streifendiagramm graphisch dargestellt.

# Die Werte unter dem Durchschnitt werden durch blaue Streifen dargestellt (je kleiner, umso dunkler),

# die Werte uber dem Durchschnitt werden durch rote Striefen dargestellt (je großer, unso dunkler).

#------------------------------------------------------------------------------------------------------

import sys, stddraw, color

from farbverlaeufe import blau, rot

#------------------------------------------------------------------------------------------------------

# liesEingabe(dateiname) liest die Eingabedatei aus der Datei mit Namen dateiname (string).

# Die Datei wird als Tabelle aus zwei Spalten (getrennt durch ' ') aufgefasst.

# Die zweite Spalte wird in einem Array zuruckgegeben.

def liesEingabe(dateiname):

# Offne die Datei und lies die erste Zeile.

datei = open(dateiname, 'r')

zeile = datei.readline()

# werte speichert die Werte der zweiten Spalte.

werte = []

# Solange aus der Datei noch eine Zeile gelesen werden konnte:

# speichere den Wert aus der 2.Spalte in werte und lies die nachste Zeile.

while zeile != '':

wert = float( zeile.split()[1] )

werte += [wert]

zeile = datei.readline()

# Gib alle eingelesenen Werte zuruck.

return werte

Datentypen str und TextIOWrapper 3.1.21

Page 666: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# Fortsetzung von temperaturStreifen.py

#-------------------------------------------------------------------------------------------------------------------

# Gibt einen ganzzahligen Wert aus dem Bereich 0..510 zuruck, der dem "Farbton" von wert auf der

# Skala von unten (entspricht 0, schwarz) bis oben (entspricht 510, weiß) entspricht.

def farbton(wert, unten, oben):

m = 510*(wert-unten)/(oben-unten)

return int(round(m))

#-------------------------------------------------------------------------------------------------------------------

# Erhalt ein Array aus Zahlenwerten und wandelt sie in Farben um.

# Werte unter dem Mittelwert werden in Blautone umgewandelt. Kleine Werte haben dunklere Blautone als großere Werte.

# Wert uber dem Mittelwert werden in Rottone umgewandelt. Kleine Werte haben hellere Rottone als großere Werte.

# Das Array mit den in Farben umgewandelten Werten wird zuruckgegeben.

def werteZuFarben(werte):

durchschnittsWert = sum(werte)/len(werte)

minWert = min(werte)

maxWert = max(werte)

farben = []

for w in werte:

# Falls der Wert kleiner als der Durchschnitt ist, wird er durch einen Blauton dargestellt: je kleiner, umso dunkler.

if w<=durchschnittsWert:

farben += [ blau( farbton(w, minWert, durchschnittsWert) ) ]

else:

# Falls der Wert großer als der Durchschnitt ist, wird er durch einen Rotton dargestellt: je kleiner, umso heller.

farben += [ rot( 510 - farbton(w, durchschnittsWert, maxWert) ) ]

return farben

Datentypen str und TextIOWrapper 3.1.22

Page 667: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# Fortsetzung von temperaturStreifen.py

#------------------------------------------------------------------------------------------------------

# Das Hauptprogramm liest die darzustellenden Wert aus einer Datei,

# wandelt sie in Farben um und stellt sie Streifen auf der Leinwand dar.

def hauptprogramm():

# Lies die darzustellenden Wert aus der Datei, deren Name von der Kommandozeile gelesen wird.

werte = liesEingabe(sys.argv[1])

farben = werteZuFarben(werte)

# Die Leinwand wird eingerichtet.

stddraw.setCanvasSize(1200,800)

stddraw.setXscale(0, len(werte))

# Die Farben der Reihe nach von links nach rechts als Streifen auf die Leinwand gemalt.

for i in range(0,len(farben)):

# Der Streifen wird in der durch den Wert bestimmten Farbe gemalt.

stddraw.setPenColor(farben[i])

stddraw.filledRectangle(i, 0, 1.1, 1)

# stddraw.show(50)

# Das Ergebnis wird angezeigt.

stddraw.show()

#------------------------------------------------------------------------------------------------------

if __name__=='__main__': hauptprogramm()

#------------------------------------------------------------------------------------------------------

Datentypen str und TextIOWrapper 3.1.23

Page 668: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

python temperaturStreifen.py Jena-JahresMittel-Temp.txt

Datentypen str und TextIOWrapper 3.1.24

Page 669: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Um die fast schwarzen Streifen etwas aufzuhellen, kann man Minimum und Maximum aus dem Bereich

hinausschieben, in dem Werte vorkommen.Ersetze minWert = min(werte) durch minWert = min(werte)-0.7

maxWert = max(werte) maxWert = max(werte)+0.7

Dadurch wird die Graphik insgesamt etwas heller.

python temperaturStreifen.py Jena-JahresMittel-Temp.txt

Datentypen str und TextIOWrapper 3.1.25

Page 670: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Um die vielen hellen Streifen etwas abzudunkeln, kann man den Mittelwert bei den Blautonen nach oben

und bei den Rottonen nach unten verschieben.

Mache die Farbwahl mit farben += [ blau( farbton(w, minWert, durchschnittsWert+0.3) ) ]

farben += [ rot( 510 - farbton(w, durchschnittsWert-0.3, maxWert) ) ]

Dadurch wird die Graphik insgesamt etwas dunkler.

python temperaturStreifen.py Jena-JahresMittel-Temp.txt

Datentypen str und TextIOWrapper 3.1.26

Page 671: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Digitale BilderDer Datentyp Picture

Pixel p0, 0q Spalte 9

Zeile 5

Breite

Hohe

Ein digitales Bild stellt man sich als ein Gitter aus Pixeln vor.

Jedes Pixel hat eine Position (Spalte,Zeile) und eine Farbe.

Die Zahlung beginnt oben links mit Spalte 0 und Zeile 0.

Im Beispiel links ist das Pixel p9, 5q rot.

Der Datentyp Picture ist im Modul picture.py definiert.

Er stellt Methoden zum Lesen und Schreiben von Bildern und deren Pixeln zur Verfugung.

Datentyp Picture 3.1.27

Page 672: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die API fur den Datentyp Picture in picture.py

Datentyp Picture 3.1.28

Page 673: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anzeigen eines Bildes

# bildAnzeigen.py

# Liest den Dateinamen eines Bildes von der Komandozeile und zeigt das Bild an.

#----------------------------------------------------------------------------------------------

import sys, stddraw

from picture import Picture

#----------------------------------------------------------------------------------------------

# Richte die Leinwand von stddraw so ein, dass ihre Breite bzw. Hohe

# die Breite bzw. Hohe des anzuzeigenden Bildes ist.

def richteLeinwandEin(bild):

breite = bild.width()

hoehe = bild.height()

stddraw.setCanvasSize(breite,hoehe)

#------------------------------------------------------------------------------

# Zeige das Bild bild (Picture) auf der Leinwand von stddraw an.

def bildAnzeigen(bild):

richteLeinwandEin(bild)

stddraw.picture(bild)

stddraw.show()

#-----------------------------------------------------------------------------------------

# Lies den Dateinamen eines Bildes (.jpg oder .png) von der Kommandozeile und zeige es an.

def modultest():

dateiname = sys.argv[1]

bild = Picture(dateiname)

bildAnzeigen(bild)

#------------------------------------------------------------------------------------

if __name__ == '__main__': modultest()

#------------------------------------------------------------------------------------

# python bildAnzeigen.py Spektraltorte.jpg

#--------------------------------------------

# python bildAnzeigen.py Spektraltorte.jpg

Datentyp Picture 3.1.29

Page 674: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Umwandeln eines Farbbildes in ein Schwarzweißbild

Idee:

Andere die Farbe jedes Pixels in seine Graustufe.

Die Graustufe einer Farbe f ist die Farbe,

die fur jeden der drei RGB-Werte die Luminanz von f hat.

Datentyp Picture 3.1.30

Page 675: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# farbeNachSW.py

#-------------------------------------------------------------------------------------------------

# Liest den Dateinamen eines Bildes von der Kommandozeile und zeigt es in schwarz-weiß an.

#-------------------------------------------------------------------------------------------------

import sys, stddraw, color, luminanz, picture, bildAnzeigen

#-------------------------------------------------------------------------------------------------

# graustufe(f) gibt die Graustufe (Typ Color) der Farbe f (Typ Color) zuruck.

def graustufe(f):

l = luminanz.luminanz(f)

return color.Color(l,l,l)

#----- Hauptprogramm ----------------------------------------------------------------------------

# Lies den Dateinamen des Bildes von der Kommandozeile und erzeuge das Picture-Objekt foto daraus.

foto = picture.Picture(sys.argv[1])

# Zeige das Bild an.

bildAnzeigen.richteLeinwandEin(foto)

stddraw.picture(foto)

stddraw.show(1)

# Gehe Zeilen- und Spaltenweise alle Pixel des Bildes durch

# und ersetze dabei jede Pixel-Farbe durch ihre Luminanz.

# Wenn eine Zeile ersetzt wurde, dann zeige das Bild an.

for z in range(foto.height()):

for s in range(foto.width()):

pixel_farbe = foto.get(s,z)

g = graustufe(pixel_farbe)

foto.set(s,z,g)

stddraw.picture(foto)

stddraw.show(1)

stddraw.show()

Datentyp Picture 3.1.31

Page 676: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Farbverlaufe

Wir haben Farbverlaufe bereits mit stddraw gemalt.

Es geht auch mit Picture. Dabei mussen wir selber jedes Pixel des Bildes bemalen.

Das Problem der”weißen Streifen“ durch Rundungsfehler bei der Pixel-Berechnung entfallt dabei.

# farbverlaeufePicture.py

#------------------------------------------------------------------

from picture import Picture

from bildAnzeigen import bildAnzeigen

from farbverlaeufe import rot, blau

#------------------------------------------------------------------

# Das Programm malt den Farbverlauf von blau beginnend mit schwarz

# und dahinter den Farbverlauf von rot beginnend mit weiß.

#------------------------------------------------------------------

p = Picture(1021, 800)

for i in range(0,511):

c = blau(i)

for j in range(800): p.set(i,j, c)

for i in range(0,511):

c = rot(510-i)

for j in range(800): p.set(510+i,j, c)

bildAnzeigen(p)

#------------------------------------------------------------------

# python3 farbverlaeufePicture.py

python3 farbverlaeufePicture.py

Datentyp Picture 3.1.32

Page 677: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

§ Mit Datentypen werden verschiedenste Daten zum Rechnen nutzbar gemacht. In einer API

liest man, welche Nutzung moglich ist.

§ Methoden fur Datentypen ermoglichen eine abstrakte Handhabung der Daten.

§ Wir kennen die Schreibweise fur die Anwendung von Methoden auf Daten-Objekte und den

Unterschied zur Anwendung von Funktionen.

3.1.33

Page 678: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Abschluss-Beispiel: Schreiben wie Goethe oder SchillerZufallige Texte erzeugen, bei denen Goethes Faust den Zufall steuert

Einen Text kann man statistisch analysieren:

man schaut sich alle Text-Schnipsel der Lange 5 an

und gibt an, welche Schnipsel der Lange 5 dahinter kommen.

Beispiel: bei der Analyse von Goethes Faust findet man z.B.:

hinter . . . kommen im Faust . . .

' Da d' 'u, o ' | 'ank’ ' | 'ie? S' | 'u dic'

'u dic' 'h? Me' | 'h das' | 'h spr' | 'h nun' | 'h uns' | 'h aus' | 'h vor'

'h uns' 'rer B' | ', den' | ' besi' | ' ein ' | 'er La' | '? Fau'

'? Fau' 'st ab' | 'st. W' | 'st. S' | 'st. D' | 'st. I' | ...

'st. I' 'n Leb' | 'ch ne' | 'ch se' | 'ch ha' | 'ch ha' | 'hr se' | ...

'hr se' 'yd ei' | 'ht di' | 'yd ei' | 'yd wo' | 'hr gu' | 'lig m' | ...

'yd ei' 'n vie' | 'n Sch' | 'n lie'

'n vie' 'lgeli' | 'l, Zu' | 'l zu ' | 'l gew' | 'len G'

Schreiben wie Goethe oder Schiller 3.1.34

Page 679: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Abschluss-Beispiel: Schreiben wie Goethe oder SchillerZufallige Texte erzeugen, bei denen Goethes Faust den Zufall steuert

Beispiel: bei der Analyse von Goethes Faust findet man z.B.:

hinter . . . kommen im Faust . . .

' Da d' 'u, o ' | 'ank’ ' | 'ie? S' | 'u dic'

'u dic' 'h? Me' | 'h das' | 'h spr' | 'h nun' | 'h uns' | 'h aus' | 'h vor'

'h uns' 'rer B' | ', den' | ' besi' | ' ein ' | 'er La' | '? Fau'

'? Fau' 'st ab' | 'st. W' | 'st. S' | 'st. D' | 'st. I' | ...

'st. I' 'n Leb' | 'ch ne' | 'ch se' | 'ch ha' | 'ch ha' | 'hr se' | ...

'hr se' 'yd ei' | 'ht di' | 'yd ei' | 'yd wo' | 'hr gu' | 'lig m' | ...

'yd ei' 'n vie' | 'n Sch' | 'n lie'

'n vie' 'lgeli' | 'l, Zu' | 'l zu ' | 'l gew' | 'len G'

Nun konnen wir einen Text mit”der gleichen Wahrscheinlichkeit wie Goethes Faust“ schreiben,

indem wir mit einem Schnipsel beginnen,

immer wieder zufallig ein Folgeschnipsel auswahlen . . .

Bsp.: Da du dich uns? Faust. Ihr seyd ein viel, ZuSchreiben wie Goethe oder Schiller 3.1.34

Page 680: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Aufgabe:

schreibe ein Programm,

das einen Text und eine Schnipsellange liest,

die”Tabelle“ der im Text aufeinanderfolgenden Schnipsel berechnet

und daraus einen Zufallstext (einer vorgegebenen Lange) erzeugt.

Zum Einlesen (und Saubern) des Textes benutzen wir aus Modul dateiEinlesen.py die

Funktion textdateiAlsString(dateiname).

API von dateiEinlesen.py:

textdateiAlsString(dateiname) liest Datei dateiname und gibt ihren Inhalt

als einen String zuruck. Aus dem String wurden alle Sonderzeichen entfernt.

Zwei Worter im String sind durch ein Leerzeichen getrennt.

Schreiben wie Goethe oder Schiller 3.1.35

Page 681: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie soll die”

Tabelle“ gespeichert werden?

Die Daten-Frage

Wir speichern die”Tabelle“ als Dictionary.

Die Schlussel sind die Schnipsel,

und ein Wert ist ein Array aus allen Schnipseln,

die hinter dem Schlussel vorkommen.

Beispiel:

aus Tabellenzeile

hinter . . . kommen im Faust . . .

' Da d' 'u, o ' | 'anke ' | 'ie? S' | 'u dic'

wird im Dictionary

Schlussel ' Da d'

mit Wert ['u, o ', 'anke ', 'ie? S', 'u dic']Schreiben wie Goethe oder Schiller 3.1.36

Page 682: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# textAutomat.py

#-----------------------------------------------------------------------------------

import sys, random, dateiEinlesen

#-----------------------------------------------------------------------------------

# Die Funktion erzeugeSchnipselAutomat(text, sl) gibt das Dictionary fur

# text und sl zuruck. Die Zustandsubergange sind als Dictionary gespeichert.

# Jeder Zustand x ist ein Schlussel. Der zugehorige Wert ist ein Array

# ein Array, das fur jedes Vorkommen von xy in text einen Eintrag y

# hat. Wenn xy mehrmals vorkommt, kommt y auch entsprechend oft im

# Array vor (damit sparen wir uns das Berechnen der Gewichte).

def erzeugeSchnipselAutomat(text, sl):

automat = {}

for i in range(len(text)-2*sl):

schluessel = text[i:i+sl]

if not schluessel in automat:

automat[schluessel] = []

automat[schluessel] += [text[i+sl:i+2*sl]]

return automat

#-----------------------------------------------------------------------------------

# startSchnipsel(automat) gibt ein Array aller Schnipsel (Zustande)

# zuruck, die im Automat auf ein Satzendezeichen folgen konnen.

def startSchnipsel(automat):

startschnipsel = []

for s in automat:

if s[-2] in '.!?': startschnipsel += automat[s]

return startschnipselSchreiben wie Goethe oder Schiller 3.1.37

Page 683: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

#-----------------------------------------------------------------------------------

# zufallsText(automat,sl,laenge) gibt einen Text der Lange laenge zuruck,

# der vom WSA mit Schnipsellange sl erzeugt werden kann.

def zufallsText(automat, sl, laenge):

# Wahle zufallig einen Satzanfang.

satz = random.choice(startSchnipsel(automat))

# Laufe durch den Automat, bis ein Text der gewunschten Lange erzeugt wurde.

for i in range(0,laenge,sl):

endschnipsel = satz[i:i+sl]

if endschnipsel in automat:

# print(endschnipsel + ': ' + str(automat[endschnipsel]))

folgeschnipsel = random.choice(automat[endschnipsel])

satz += folgeschnipsel

return satz

#-----------------------------------------------------------------------------------

def modultest():

dateiname = sys.argv[1]

schnipselLaenge = int(sys.argv[2])

textLaenge = int(sys.argv[3])

# Lies eine Textdatei ein und wandele sie in einen String um.

text = dateiEinlesen.textdateiAlsString(dateiname)

# Erzeuge daraus einen Wort-Schnipsel-Automat.

automat = erzeugeSchnipselAutomat(text, schnipselLaenge)

# Erzeuge einen Zufallstext mit dem Automaten.

print(zufallsText(automat, schnipselLaenge, textLaenge))

#-----------------------------------------------------------------------------------

if __name__ == '__main__': modultest()

Schreiben wie Goethe oder Schiller 3.1.38

Page 684: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# python textAutomat.py Goethe-ItalienischeReise1.txt 3 200

# Winder Reihen wieder gerett, habe. Hierauf wohl eben konnten, Ture und uber.

# Den Januar 1787. Verwahre ich vor Herr alles aus dem Zwergoldener

# dem Hafer, wegenitunterdreichzug gern hunden. Indes schon

# python textAutomat.py Goethe-ItalienischeReise1.txt 6 200

# Hamilton und seines Lebens. Die Zimmer nur durch denselben zu trennen und bewegten.

# Wer hat es die letzte bewohnt und fugte hinzu, daß ich denn

# als Mitternacht aus diesem Tiere ein Jammer, Gange fand ich di

# python textAutomat.py Goethe-ItalienischeReise1.txt 12 200

# Heute gesellten sich reitend ein Herr und eine Dame zu uns, ein Englander sprechen,

# der mir uber meinen Werther etwas zu sagen habe.

# Vor einem halben Jahre wurde hierauf, und ware sie mir doppelt wert gewesen, g

# python3 textAutomat.py textAutomat.py 4 200

# !? startschnipsel in automattext, sl automat, sl, laenge Erzeuge daraus eine Ausgabelange

# sl erzeuge einen Stringdateinander folgeschnipselAutomat if s1 in der vom WSA

# mit der TextDatei. import sys, rando

Schreiben wie Goethe oder Schiller 3.1.39

Page 685: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4 Algorithmen

Wir haben bisher Programme zur Losung verschiedener Probleme geschrieben. Jedes Programm

basiert auf einer Idee (Algorithmus), die man in jeder Programmierprache aufschreiben kann.

Beim Entwickeln von Algorithmen geht es u.a. darum, moglichst schnelle Algorithmen mit wenig

Speicherplatzbedarf zu finden.

In diesem Kapitel schauen wir uns zuerst an, wie man experimentell feststellt, wie”schnell“ ein

Algorithmus ist.

Anschließend schauen wir uns Algorithmen zum Suchen von Verbindungen in Netzwerken an.

Mehr uber Algorithmen gibt es im zweiten Teil der Vorlesung.

Page 686: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1. Elemente des Programmierens

2. Funktionen und Module

3. Objekt-orientierte Programmierung (erste Schritte)

4. Algorithmen

4.1 Rechenzeit

4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken

Schreiben wie Goethe oder Schiller 4.0.41

Page 687: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 11

4. Algorithmen

4.1 RechenzeitExperimentelle Bestimmung/Schatzung der Rechenzeit

Abstrakte Schatzung der Rechenzeit

Beispiele fur Rechenzeitanalysen

4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken

Schreiben wie Goethe oder Schiller 4.1.1

Page 688: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4.1 Rechenzeit von Programmen

Wir haben z.B. beim

§ Berechnen von Potenzen 2**n

§ Berechnen von Fibonacci-Zahlen

§ Sortieren von Zahlenfolgen

gesehen, dass verschiedene Programme zwar das gleiche Ergebnis berechnen,

jedoch fur die betrachteten Eingaben sehr unterschiedlich schnell sind.

Wann kann man sagen, dass ein Programm schneller als ein anderes ist?

Wie kann man die Rechenzeit von Programmen analysieren?

Kann man auch die Rechenzeit von (noch nicht implementierten) Algorithmen analysieren?

Wir betrachten jetzt der Einfachheit halber nur Funktionen/Programme mit einem Argument.

Einleitung 4.1.2

Page 689: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1. Problem: Rechenzeiten von Programmen sind unvergleichbar

Wir haben gemessen, dass die Funktion bubblesort(a) ein Array a aus 16000 Zahlen in 0.003 Sek. sortiert,

und heapsort(a) das gleiche Array in 0.106 Sek. sortiert.

Bei einem Array b aus 16000 Zahlen braucht bubblesort(b) 23.593 Sek. und heapsort(b) 0.101 Sek.

In Grundvorlesungen lernt man, dass Heapsort schneller ist als Bubblesort. Was stimmt nun?

Einleitung 4.1.3

Page 690: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1. Problem: Rechenzeiten von Programmen sind unvergleichbar

Wir haben gemessen, dass die Funktion bubblesort(a) ein Array a aus 16000 Zahlen in 0.003 Sek. sortiert,

und heapsort(a) das gleiche Array in 0.106 Sek. sortiert.

Bei einem Array b aus 16000 Zahlen braucht bubblesort(b) 23.593 Sek. und heapsort(b) 0.101 Sek.

In Grundvorlesungen lernt man, dass Heapsort schneller ist als Bubblesort. Was stimmt nun?

Wenn man die Rechenzeiten fur jede Eingabe vergleicht,

ist die Rechenzeit vieler Funktionen nicht miteinander vergleichbar.

Deshalb vergleicht man die Rechenzeit nur fur jede Eingabelange.

Die Rechenzeit einer Funktion fur eine Eingabelange n ist

ihre großte Rechenzeit fur alle Eingaben der Lange n.

§ Bei int-Argumenten ist die Eingabelange die Lange der int-Zahl in Binardarstellung.§ Bei Array-Argumenten ist die Eingabelange die Lange des Arrays.§ Bei Netzwerk-Argumenten ist die Eingabelange die Anzahl der Knoten/Kanten des Netzwerks.

Einleitung 4.1.3

Page 691: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1. Problem: Rechenzeiten von Programmen sind unvergleichbar

Wenn man die Rechenzeiten fur jede Eingabe vergleicht,

ist die Rechenzeit vieler Funktionen nicht miteinander vergleichbar.

Deshalb vergleicht man die Rechenzeit nur fur jede Eingabelange.

Die Rechenzeit einer Funktion fur eine Eingabelange n ist

ihre großte Rechenzeit fur alle Eingaben der Lange n.

§ Bei int-Argumenten ist die Eingabelange die Lange der int-Zahl in Binardarstellung.

§ Bei Array-Argumenten ist die Eingabelange die Lange des Arrays.

§ Bei Netzwerk-Argumenten ist die Eingabelange die Anzahl der Knoten/Kanten des Netzwerks.

Die Zahl 1234567890 hat Binardarstellung 1001001100101100000001011010010, also Lange 31.

Es gibt 230 « 109 Zahlen der Lange 31.

Einleitung 4.1.3

Page 692: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1. Problem: Rechenzeiten von Programmen sind unvergleichbar

Wenn man die Rechenzeiten fur jede Eingabe vergleicht,

ist die Rechenzeit vieler Funktionen nicht miteinander vergleichbar.

Deshalb vergleicht man die Rechenzeit nur fur jede Eingabelange.

Die Rechenzeit einer Funktion fur eine Eingabelange n ist

ihre großte Rechenzeit fur alle Eingaben der Lange n.

§ Bei int-Argumenten ist die Eingabelange die Lange der int-Zahl in Binardarstellung.

§ Bei Array-Argumenten ist die Eingabelange die Lange des Arrays.

§ Bei Netzwerk-Argumenten ist die Eingabelange die Anzahl der Knoten/Kanten des Netzwerks.

Das Array [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] hat Lange 10.

Es gibt 1010 Arrays mit 10 Elementen aus dem Bereich 1 . . . 10.

Einleitung 4.1.3

Page 693: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1. Problem: Rechenzeiten von Programmen sind unvergleichbar

Wenn man die Rechenzeiten fur jede Eingabe vergleicht,

ist die Rechenzeit vieler Funktionen nicht miteinander vergleichbar.

Deshalb vergleicht man die Rechenzeit nur fur jede Eingabelange.

Die Rechenzeit einer Funktion fur eine Eingabelange n ist

ihre großte Rechenzeit fur alle Eingaben der Lange n.

§ Bei int-Argumenten ist die Eingabelange die Lange der int-Zahl in Binardarstellung.

§ Bei Array-Argumenten ist die Eingabelange die Lange des Arrays.

§ Bei Netzwerk-Argumenten ist die Eingabelange die Anzahl der Knoten/Kanten des Netzwerks.

Das Netzwerk von Seite 4.2.2 hat Lange 10 (10 Knoten).

Es gibt 210¨9

2 « 3.5 ¨ 1013 (nicht-isomorphe) Netzwerke der Große 10.

Einleitung 4.1.3

Page 694: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2. Problem: Es gibt zu viele Eingaben

Das Alter des Universums ist etwa 4 ¨ 1017 Sekunden.

Es gibt 1919 ě 4 ¨ 1023 Arrays der Lange 19 aus Zahlen 1 . . . 19.

Wenn Heapsort zum Sortieren eines solchen Arrays mindestens 10´6 Sekunden braucht,

dann braucht man mehr Zeit als das Alter des Universums,

um alle Arrays der Lange 19 zu sortieren

und die Rechenzeit meiner Heapsort-Funktion fur Eingaben der Lange 19 zu bestimmen.

Fazit: man kann die Rechenzeit einer Funktion nicht praktisch bestimmen – dafur braucht man

eine gute Theorie.

Einleitung 4.1.4

Page 695: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Um die Theorie zu untermauern,

beginnen wir in dieser Vorlesung mit ein paar praktischen Messungen.

Dazu schatzen wir die”praktische“ Rechenzeit einer Funktion fur eine Eingabelange n dadurch ab,

dass wir

(zufallig) eine Eingabe der Lange n wahlen und

die Rechenzeit fur diese Eingabe

als maximale Rechenzeit fur alle Eingaben gleicher Lange nehmen.

Die Messungen geben uns einen Hinweis auf die”theoretische“ Rechenzeit.

Einleitung 4.1.5

Page 696: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Experimentelles Messen der Rechenzeit einer Funktion fur ein

Argument/Eingabe

Zum Messen der Rechenzeit benutzen wir die Funktion time() aus dem Modul time.py,

die die Zeit seit dem 1.1.1970 in Sekunden als float zuruckgibt.

Jede Messung sieht wie folgt aus:

schaue auf die Uhr

starte die zu messende Funktion und warte, bis sie beendet ist

schaue auf die Uhr

die Differenz der Uhrzeiten ist die Rechenzeit

Wir werden eine Messreihe aus einer Reihe von Messungen durchfuhren,

bei denen das Argument fur die Funktion immer großer wird.

Der Einfachheit halber wollen wir nur Funktionen betrachten,

die nur von einem Argument abhangig sind.Messen der Rechenzeit 4.1.6

Page 697: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# messreihe.py

#---------------------------------------------------------------------------------------

# Funktionen zum Durchfuhren von Rechenzeitmessungsexperimenten.

#---------------------------------------------------------------------------------------

import sys, time, random

#---------------------------------------------------------------------------------------

# randomArray(n) erzeugt ein Array der Lange n mit zufalligen Eintragen aus -10n...10n.

def randomArray(n):

a = [0]*n

for i in range(n):

a[i] = random.randrange(-10*n, 10*n+1)

return a

#---------------------------------------------------------------------------------------

# miss(testfunktion, n) ruft testfunktion(n) auf und gibt die Zeit (in Sekunden)

# zuruck, die dieser Aufruf gedauert hat.

def miss(testfunktion, n):

messAnfang = time.time()

testfunktion(n)

messEnde = time.time()

return messEnde - messAnfang

Messen der Rechenzeit 4.1.7

Page 698: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Beispiel: finde im Array drei Eintrage mit Summe 0

Als ausfuhrliches Beispiel wollen wir die Rechenzeit der Funktion countTriples(a) im Modul

threesum.py untersuchen.

Die Funktion erhalt als Argument ein Array a aus Zahlen

und sucht darin nach drei Eintragen (Tripel), deren Summe 0 ist (und gibt sie aus).

Die Anzahl solcher Tripel wird zuruckgegeben. (Ggf. werden die gefundenen Tripel ausgegeben.)

Das Hauptprogramm liest n von der Kommandozeile,

erzeugt ein Array der Lange n mit zufallig gewahlten Eintragen aus dem Bereich ´10 ¨ n . . . 10 ¨ n,

gibt das Array aus (falls es nicht zu groß ist)

und gibt aus, wieviele Tripel im Array Summe 0 haben.

$ python3 threesum.py 5

Array: [-1, 3, -3, 0, 3]

Tripel 1: 3 -3 0

Tripel 2: -3 0 3

Anzahl gefundener Tripel: 2

$ python3 threesum.py 10

Array: [-2, -10, 1, -4, -10, -4, 10, 10, -3, 6]

Tripel 1: -2 -4 6

Tripel 2: -2 -4 6

Anzahl gefundener Tripel: 2Rechenzeitanalyse von countTriples 4.1.8

Page 699: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# threesum.py

#-------------------------------------------------------------------------------------------------------------------

import sys, random

from messreihe import randomArray

#-------------------------------------------------------------------------------------------------------------------

# countTriples(a) probiert systematisch alle Tripel aus Eintragen im Array a

# durch und zahlt, wieviel Summe 0 haben.

# Diese Anzahl wird zuruckgegeben.

# Die Rechenzeit hat Großenordnung n**3 (n ist die Große von a).

def countTriples(a):

n = len(a)

count = 0

for i in range(n-2):

for j in range(i+1,n-1):

for k in range(j+1,n):

if (a[i] + a[j] + a[k]) == 0:

count += 1

if n<20: print( 'Tripel %2d: %d %d %d' % (count, a[i], a[j], a[k]) )

return count

#-------------------------------------------------------------------------------------------------------------------

def hauptprogramm():

a = randomArray(int(sys.argv[1])) # Lies n von der Kommandozeile und erzeuge ein zufalliges Array der Lange n.

if len(a)<20: print( 'Array: %s' % str(a) )

ergebnis = countTriples(a) # Zahle die Tripel in a mit Summe 0.

print( 'Anzahl gefundener Tripel: %d' % ergebnis ) # Gib das Ergebnis aus.

#-------------------------------------------------------------------------------------------------------------------

if __name__=='__main__': hauptprogramm()

#-------------------------------------------------------------------------------------------------------------------

Rechenzeitanalyse von countTriples 4.1.9

Page 700: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Problem 3: Die Rechenzeit ist abhangig vom Rechner

Wir wollen eine Aussage daruber treffen konnen,

wie die Rechenzeit der Funktion countTriples(a) fur beliebig große Arrays a ist.

Dazu machen wir erstmal ein paar Messungen.Rechner 1:

Große Zeit (s)

------------------

40 0.00

60 0.00

80 0.01

100 0.02

120 0.04

140 0.06

160 0.08

180 0.12

200 0.16

220 0.21

240 0.27

260 0.34

280 0.43

300 0.53

320 0.64

340 0.77

360 0.92

380 1.09

Rechner 2:

Große Zeit (s)

------------------

40 0.00

60 0.01

80 0.02

100 0.03

120 0.04

140 0.07

160 0.09

180 0.11

200 0.18

220 0.26

240 0.30

260 0.39

280 0.53

300 0.63

320 0.79

340 0.89

360 1.12

380 1.14

Auf den ersten Blick kann man nichts

erkennen.

Die genauen Rechenzeiten hangen vom

Rechner ab, auf dem das Programm lauft.

Rechenzeitanalyse von countTriples 4.1.10

Page 701: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen eine Aussage daruber treffen konnen,

wie die Rechenzeit der Funktion countTriples(a) fur beliebig große Arrays a ist.

Dazu machen wir erstmal ein paar Messungen und zeichnen daraus eine Kurve.

Rechner 1:

Große Zeit (ms)

------------------

40 0.00

60 0.00

80 0.01

100 0.02

120 0.04

140 0.06

160 0.08

180 0.12

200 0.16

220 0.21

240 0.27

260 0.34

280 0.43

300 0.53

320 0.64

340 0.77

360 0.92

380 1.09

400 1.28

420 1.52

440 1.72

460 1.98

480 2.28

500 2.54

520 2.94

540 3.22

560 3.65

0 200 400 600 800 1,000

0

10

20

Anzahl der Eintrage im Array

Rec

hen

zeit

inS

eku

nd

en

Blaue Kurve: Rechner 1

Rote Kurve: Rechner 2

Schwarze Kurve: Rechner 3

(doppelt so schnell wie Rechner 2)

Rechenzeiten auf

unterschiedlichen Rechnern

ergeben von der”Form“ her

ahnliche Kurven.

Die Kurve ist von der”Form“

her anders als jede lineare

Kurve.

Rechenzeitanalyse von countTriples 4.1.11

Page 702: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir wollen eine Aussage daruber treffen konnen,

wie die Rechenzeit der Funktion countTriples(a) fur beliebig große Arrays a ist.

Dazu machen wir erstmal ein paar Messungen und zeichnen daraus eine Kurve.

Rechner 1:

Große Zeit (ms)

------------------

40 0.00

60 0.00

80 0.01

100 0.02

120 0.04

140 0.06

160 0.08

180 0.12

200 0.16

220 0.21

240 0.27

260 0.34

280 0.43

300 0.53

320 0.64

340 0.77

360 0.92

380 1.09

400 1.28

420 1.52

440 1.72

460 1.98

480 2.28

500 2.54

520 2.94

540 3.22

560 3.65

0 200 400 600 800 1,000

0

10

20

Anzahl der Eintrage im Array

Rec

hen

zeit

inS

eku

nd

en

Blaue Kurve: Rechner 1

Rote Kurve: Rechner 2

Schwarze Kurve: Rechner 3

(doppelt so schnell wie Rechner 2)

Rechenzeiten auf

unterschiedlichen Rechnern

ergeben von der”Form“ her

ahnliche Kurven.

Die Kurve ist von der”Form“

her anders als jede lineare

Kurve.

Rechenzeitanalyse von countTriples 4.1.11

Page 703: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wie konnen wir experimentell abschatzen, wie die Rechenzeitkurven sich weiter entwickeln?D.h. wie konnen wir – ohne die Funktion z.B. auf einem Array der Große 1000000 zu starten – abschatzen,

wielange die Berechnung der Funktion dauert?

Wie konnen wir eine Aussage uber die Schnelligkeit des Programms machen,

die fur alle unterschiedlich schnellen Rechner nutzlich ist?

Dazu starten wir folgende Messreihe:

wir messen, wie stark sich die Rechenzeit vergroßert, wenn man die Eingabegroße verdoppelt.

Rechenzeitanalyse von countTriples 4.1.12

Page 704: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Messreihe wird vom Programm messreiheArray.py durchgefuhrt.

In der Messreihe wird die Rechenzeit der Funktion testfunktion untersucht.

testfunktion hat ein Array a als Argument.

Rechenzeitanalyse von countTriples 4.1.13

Page 705: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Messreihe wird vom Programm messreiheArray.py durchgefuhrt.

In der Messreihe wird die Rechenzeit der Funktion testfunktion untersucht.

testfunktion hat ein Array a als Argument.

In jeder Messung der Messreihe wird die Rechenzeit von testfunktion(a) gemessen,

wobei a ein zufallig gewahltes Array einer bestimmten Lange ist.

Beim Start der Messreihe hat a eine vorgegebene Lange.

Die Lange von a wird von Messung zu Messung verdoppelt.

Nach jeder Messung wird ausgegeben,

wie sich die Rechenzeit im Vergleich zur vorherigen Messung vergroßert hat.

Die Messreihe wird beendet, wenn eine vorgegebene Zeit erreicht wurde.

Rechenzeitanalyse von countTriples 4.1.13

Page 706: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

In jeder Messung der Messreihe wird die Rechenzeit von testfunktion(a) gemessen,

wobei a ein zufallig gewahltes Array einer bestimmten Lange ist.

Beim Start der Messreihe hat a eine vorgegebene Lange.

Die Lange von a wird von Messung zu Messung verdoppelt.

Nach jeder Messung wird ausgegeben,

wie sich die Rechenzeit im Vergleich zur vorherigen Messung vergroßert hat.

Die Messreihe wird beendet, wenn eine vorgegebene Zeit erreicht wurde.

$ python3 messreiheArray.py threesum countTriples 100 1000

Eing.lange | Rechenzeit | Faktor

------------------------------------

100 | 0.021 |

200 | 0.153 | 7.42

400 | 1.263 | 8.25

800 | 10.181 | 8.06

1600 | 82.237 | 8.08

3200 | 664.290 | 8.08Rechenzeitanalyse von countTriples 4.1.13

Page 707: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

In jeder Messung der Messreihe wird die Rechenzeit von testfunktion(a) gemessen,

wobei a ein zufallig gewahltes Array einer bestimmten Lange ist.

Beim Start der Messreihe hat a eine vorgegebene Lange.

Die Lange von a wird von Messung zu Messung verdoppelt.

Nach jeder Messung wird ausgegeben,

wie sich die Rechenzeit im Vergleich zur vorherigen Messung vergroßert hat.

Die Messreihe wird beendet, wenn eine vorgegebene Zeit erreicht wurde.

python3 messreiheArray.py modul funktion startgroesse dauer

fuhrt die Messreihe fur die Funktion funktion aus dem Modul modul.py durch.

Die erste Messung wird auf einem Array der Lange startgroesse durchgefuhrt.

Die Messreihe dauert dauer Sekunden.

Rechenzeitanalyse von countTriples 4.1.13

Page 708: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# messreiheArray.py

#--------------------------------------------------------------------------------------------------

import sys, time

from messreihe import miss, randomArray

# Importiere das Modul mit der Funktion, die fur die Messreihe benutzt wird.

exec('from ' + sys.argv[1] + ' import ' + sys.argv[2] + ' as testfunktion')

n = int(sys.argv[3]) # die Lange des Arrays bei der ersten Messung

versuchsdauer = float(sys.argv[4]) # die Dauer der Messreihe in Sekunden

versuchsEnde = time.time() + versuchsdauer # die Uhrzeit, bei der der Versuch beendet wird

letzteMessung = 0 # die Rechenzeit der letzten Messung

# Gib den Kopf fur die Tabelle mit den Messergebnissen aus.

print( ' %11s | %12s | %6s \n%s' % ('Eing.lange', ' Rechenzeit', 'Faktor', ' '+'-'*36) )

# Fuhre die Messreihe mit wachsendem n durch, bis die Zeit abgelaufen ist.

while time.time() < versuchsEnde:

# Erzeuge das zufallige Array der Lange n fur die nachste Messung.

a = randomArray(n)

# Miss die Rechenzeit von testfunktion(a).

messErgebnis = miss(testfunktion, a)

# Gib das Ergebnis der Messung aus.

if letzteMessung==0: print( '# %12d | %10.3f |' % (n, messErgebnis) )

else: print( '# %12d | %10.3f | %6.2f ' % (n, messErgebnis, messErgebnis/letzteMessung) )

# Bereite die nachste Messung vor.

letzteMessung = messErgebnis

n *= 2

Rechenzeitanalyse von countTriples 4.1.14

Page 709: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 messreiheArray.py threesum countTriples 100 1000

Eing.lange | Rechenzeit | Faktor

-------------------------------------

100 | 0.021 |

200 | 0.153 | 7.42

400 | 1.263 | 8.25

800 | 10.181 | 8.06

1600 | 82.237 | 8.08

3200 | 664.290 | 8.08

Wir sehen, dass die Verdoppelung der Eingabelange die Rechenzeit etwa verachtfacht.

Wenn t die Funktion ist, die die Eingabelange auf die Rechenzeit abbildet,

gilt also tp2 ¨ nq “ 8 ¨ tpnq

Da p2 ¨ nq3 “ 23 ¨ n3 “ 8 ¨ n3,

konnen wir schließen,

dass die Funktion t eine Funktion der Großenordnung tpnq “ n3 ist.

(Eine genauere Abschatzung ist tpnq “ n3

50673000, aber konstante Faktoren werden z.B.

durch die Geschwindigkeit des Rechners beeinflusst, und deshalb lassen wir sie weg.)

n n3

1 1

2 8

4 64

8 544Rechenzeitanalyse von countTriples 4.1.15

Page 710: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Das Ergebnis der experimentellen Analyse ist also,

dass countTriples bei Eingabe eines Arrays der Lange n

eine Rechenzeit der Großenordnung n3 zu haben scheint.

Lasst sich das auch ohne Experimente am Programm erkennen?

Dazu wollen wir zahlen,

wie oft einzelne Programmzeilen bei der Ausfuhrung des Programms durchlaufen werden.

Bevor wir die Zahlung abstrakt mathematisch machen, machen wir sie experimentell.

Wir konnen unser Programm zur Durchfuhrung und Analyse der Messreihe so umbauen,

dass es die Anzahl aller (wiederholt) ausgefuhrten Programmzeilen zahlt.

Aus Programm arrayMessreihe.py machen wir das Programm arrayMessreiheZ.py

indem Zeile messErgebnis = miss(testfunktion, a) durch

messErgebnis = testfunktion(a) ersetzen.

Das Wort Rechenzeit in der Ausgabe wird durch Zeilenzahler ersetzt.

Das Ausgabeformat in der Spalte Zeilenzahler wird von %10.3f auf %10d geandert.Rechenzeitanalyse von countTriples 4.1.16

Page 711: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# threesumlinecount.py

#----------------------------------------------------

def countTlines(a):

# Fast wie countTriples() in threesum.py,

# aber zusatzlich wird ein Zahler zz mitgefuhrt,

# der nach jeder Ausfuhrung einer Programmzeile

# um 1 erhoht wird. Am Ende des Funktionsaufrufs

# wird der Zahlerwert zuruckgegeben.

zz = 0

n = len(a)

zz += 1

count = 0

zz += 1

for i in range(n-2):

zz += 1

for j in range(i+1,n-1):

zz += 1

for k in range(j+1,n):

zz += 2

if (a[i] + a[j] + a[k]) == 0:

zz += 1

count += 1

return zz

def countTriples(a):

n = len(a)

count = 0

for i in range(n-2):

for j in range(i+1,n-1):

for k in range(j+1,n):

if (a[i] + a[j] + a[k]) == 0:

count += 1

return count

Rechenzeitanalyse von countTriples 4.1.17

Page 712: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir starten nun eine Messreihe, mit der wir herausfinden wollen,

wie stark die Verdopplung der Eingabegroße die Anzahl der ausgefuhrten Zeilen (d.h. den

Ruckgabewert von countTlines) erhoht.

Das Ergebnis ist”verbluffend“ und bestatigt die Interpretation der vorherigen Experimente.

$ python3 messreiheArrayZ.py threesumlinecount countTlines 100 200

Eing.lange | Zeilenzahler | Faktor

-------------------------------------

100 | 166718 |

200 | 1333545 | 8.00

400 | 10667556 | 8.00

800 | 85336967 | 8.00

1600 | 682682381 | 8.00

3200 | 5461396585 | 8.00

Wir konnen also die Großenordnung der Rechenzeit auch durch Zahlen der ausgefuhrten

Programmzeilen bestimmen.

Muss man tatsachlich alle ausgefuhrten Programmzeilen zahlen? Rechenzeitanalyse von countTriples 4.1.18

Page 713: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir zahlen jetzt nur noch, wie oft die am haufigsten ausgefuhrte Programmzeile ausgefuhrt wird.

# threesumlinecount.py

#---------------------------------------------------------------------------------

# countTinnerline(a) gibt zuruck, wie oft (ungefahr) die "innerste" Programmzeile

# in den verschachtelten Schleifen von threesum.countTriples ausgefuhrt wird.

# Dazu wird ein Zahler zz eingefuhrt, der entsprechend hochgezahlt wird.

def countTinnerline(a):

zz = 0

n = len(a)

count = 0

for i in range(n-2):

for j in range(i+1,n-1):

for k in range(j+1,n):

zz += 1

if (a[i] + a[j] + a[k]) == 0:

count += 1

return zz

def countTriples(a):

n = len(a)

count = 0

for i in range(n-2):

for j in range(i+1,n-1):

for k in range(j+1,n):

if (a[i] + a[j] + a[k]) == 0:

count += 1

return count

Rechenzeitanalyse von countTriples 4.1.19

Page 714: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir starten nun eine Messreihe, mit der wir nachschauen,

wie stark die Verdoppelung der Eingabegroße die Anzahl der Ausfuhrungen der”innersten“ Zeile

der Funktion (d.h. den Ruckgabewert von counTinnerline) vergroßert.

Es kommt”im Prinzip“ das gleiche Ergebnis heraus wie zuvor:

Eing.lange | Zeilenzahler | Faktor

-------------------------------------

100 | 161700 |

200 | 1313400 | 8.12

400 | 10586800 | 8.06

800 | 85013600 | 8.03

1600 | 681387200 | 8.02

3200 | 5456214400 | 8.01

Wir haben jetzt auf unterschiedliche Arten (Rechenzeit in Sekunden, Haufigkeit der Ausfuhrung

aller Programmzeilen, Haufigkeit der Ausfuhrung der am haufigsten ausgefuhrten Programmzeile)

experimentell herausgefunden, dass die Rechenzeit bei Eingabegroße n die Großenordnung n3 hat.

Lasst sich das mit einem mathematischen Modell bestatigen?Rechenzeitanalyse von countTriples 4.1.20

Page 715: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Abstrakte Schatzung der Rechenzeit

Zuerst versuchen wir abstrakt, die Haufigkeit der Ausfuhrung jeder Programmzeile zu bestimmen.

Programm Haufigkeit der Ausfuhrung der Zeile «

n = len(a) 1

counter = 0 1

for i in range(n-2): n ´ 2 n

for j in range(i+1,n-1): pn ´ 3q ` pn ´ 4q ` . . .` 1 n2

2

for k in range(j+1,n): n3

6

if (a[i]+a[j]+a[k]) == 0: n3

6

counter += 1 abhangig von der Eingabe

die Summe ist: ?

Wir sehen:

1. Wir wissen nicht, wie man zahlen soll, wenn die Ausfuhrung einer Programmzeile von der Eingabe

(und nicht nur von der Eingabegroße) abhangig ist.

2. Eine exakte Zahlung ist da unmoglich.Rechenzeitanalyse von countTriples 4.1.21

Page 716: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Abstrakte Schatzung der Rechenzeit

Zuerst versuchen wir abstrakt, die Haufigkeit der Ausfuhrung jeder Programmzeile zu bestimmen.

Programm Haufigkeit der Ausfuhrung der Zeile «

n = len(a) 1

counter = 0 1

for i in range(n-2): n ´ 2 n

for j in range(i+1,n-1): pn ´ 3q ` pn ´ 4q ` . . .` 1 n2

2

for k in range(j+1,n): n3

6

if (a[i]+a[j]+a[k]) == 0: n3

6

counter += 1 abhangig von der Eingabe n3

6

die Summe ist: ?

Wir mussen die Sache also vereinfachen und aufs exakte Zahlen verzichten (Faustregeln):

1. Gehe bei den ausgefuhrten Zeilen vom ungunstigsten Fall aus.

D.h., wenn die Ausfuhrung einer Programmzeile von der Eingabe abhangig ist,

dann nimm an, dass die Eingabe so ist, dass die Zeile ausgefuhrt wird.Rechenzeitanalyse von countTriples 4.1.21

Page 717: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Abstrakte Schatzung der Rechenzeit

Zuerst versuchen wir abstrakt, die Haufigkeit der Ausfuhrung jeder Programmzeile zu bestimmen.

Programm Haufigkeit der Ausfuhrung der Zeile «

n = len(a) 1

counter = 0 1

for i in range(n-2): n ´ 2 n

for j in range(i+1,n-1): pn ´ 3q ` pn ´ 4q ` . . .` 1 n2

for k in range(j+1,n): n3

if (a[i]+a[j]+a[k]) == 0: n3

counter += 1 abhangig von der Eingabe n3

die Großenordnung ist n3

Wir mussen die Sache also vereinfachen und aufs exakte Zahlen verzichten (Faustregeln):

2. Bei einem Produkt streicht man alle konstanten Faktoren.

Bei einer Summe nimmt man nur den großten Summanden.

Statt der exakten Schrittzahl erhalt man so ihre Großenordnung.

Rechenzeitanalyse von countTriples 4.1.21

Page 718: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung der Rechenzeitanalyse von countTriples(a)

Mit der experimentellen Analyse haben wir gesehen,

dass sich fur Eingaben bis zur Lange 3200 die Rechenzeit verachtfacht,

wenn die Eingabelange verdoppelt wird.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion die Großenordnung n3 hat

(n ist die Eingabelange).

Bei der abstrakten Analyse haben wir gesehen,

dass die Funktion aus drei ineinandergeschachtelten Schleifen besteht,

die jeweils im (nicht eintretenden) schlechtesten Fall fur Werte 1 . . . n durchlaufen werden.

Deshalb hat die Rechenzeitfunktion die Großenordnung n3.

Diese Analyse liefert eine obere Schranke der Rechenzeit.

Die”echte“ Rechenzeit kann auch eine kleinere Großenordnung haben . . .

Rechenzeitanalyse von countTriples 4.1.22

Page 719: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Weitere Beispiele fur Rechenzeitanalysen

§ Sortieren mit Bubblesort

§ Sortieren mit Pythons Sortierfunktion list.sort()

§ Berechnung der Halfte einer int-Zahl

§ Berechnung des Quadrats einer int-Zahl (auch Multiplikation)

§ Berechnung des ganzzahligen Logarithmus zur Basis 2

§ Berechnung einer Fibonacci-Zahl (nicht rekursiv, langsam)

§ Berechnung einer Fibonacci-Zahl (schnell)

§ Berechnung der Potenz 2n (schnell)

§ Berechnung der Potenz 2n (langsam)

Beispiele fur Rechenzeitanalysen 4.1.23

Page 720: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von bubblesort(a)

# sortierenUndSuchen.py

#--------------------------------------------------------

# bubblesort(liste) sortiert das Array liste aufsteigend

# mit dem Bubblesort-Algorithmus.

def bubblesort(liste):

getauscht = True

while getauscht:

getauscht = False

for i in range(len(liste)-1):

if liste[i]>liste[i+1]:

liste[i], liste[i+1] = liste[i+1], liste[i]

getauscht = True

Experimentelle Analyse:

python3 messreiheArray.py sortierenUndSuchen \

bubblesort 1000 100

Eing.lange | Rechenzeit | Faktor

------------------------------------

1000 | 0.231 |

2000 | 0.912 | 3.95

4000 | 3.970 | 4.35

8000 | 14.747 | 3.71

16000 | 59.679 | 4.05

32000 | 250.239 | 4.19

Bei Verdoppelung der Eingabelange vervierfacht sich die

Rechenzeit. Das fuhrt zu der Vermutung, dass die

Rechenzeitfunktion t die Eigenschaft tp2 ¨ nq “ 4 ¨ tpnq.

Da p2 ¨ nq2 “ 4 ¨ n2 bzw. da log2 4 “ 2, hat dann

die Rechenzeitfunktion tpnq die Großenordnung n2.Beispiele fur Rechenzeitanalysen 4.1.24

Page 721: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von bubblesort(a)

# sortierenUndSuchen.py

#--------------------------------------------------------

# bubblesort(liste) sortiert das Array liste aufsteigend

# mit dem Bubblesort-Algorithmus.

def bubblesort(liste):

getauscht = True

while getauscht:

getauscht = False

for i in range(len(liste)-1):

if liste[i]>liste[i+1]:

liste[i], liste[i+1] = liste[i+1], liste[i]

getauscht = True

Abstrakte Analyse:

Die Funktion hat zwei ineinandergeschachtelte Schleifen.

Die innere Schleife (for-Schleife) wird jedesmal, wenn sie

erreicht wird, etwa n-mal durchlaufen.

Die außere Schleife (while-Schleife) hat folgende

Eigenschaft: die Schleife wird nicht mehr wiederholt, wenn

das Array sortiert ist.

Nach dem ersten Durchlauf steht das großte Element an

der richtigen Stelle und wird nie wieder getauscht, nach

dem zweiten Durchlauf steht auch das zweitgroßte an der

richtigen Stelle und wird nie wieder getauscht usw. Also

ist das Array spatestens nach n Durchlaufen der

while-Schleife sortiert.

Da jede der ineinandergeschachtelten Schleifen bei

Erreichen hochstens n-mal durchlaufen wird, hat die

Rechenzeitfunktion die Großenordnung n2.

Beispiele fur Rechenzeitanalysen 4.1.24

Page 722: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von Pythons Sortierfunktion list.sort()

python3 messreiheArray.py sortierenUndSuchen pythonsListSort 1000 100

Eing.lange | Rechenzeit | Faktor

------------------------------------

1000 | 0.000 |

2000 | 0.001 | 2.18

4000 | 0.001 | 2.21

8000 | 0.003 | 2.24

16000 | 0.007 | 2.17

32000 | 0.015 | 2.15

64000 | 0.032 | 2.14

128000 | 0.069 | 2.15

256000 | 0.150 | 2.19

512000 | 0.344 | 2.29

1024000 | 0.797 | 2.32

2048000 | 1.825 | 2.29

4096000 | 4.136 | 2.27

8192000 | 9.338 | 2.26

16384000 | 20.999 | 2.25

Experimentelle Analyse:

Bei Verdoppelung der Eingabelange wachst die Rechenzeit

etwa um einen Faktor 2.2. Das fuhrt zu der Vermutung,

dass die Rechenzeitfunktion t eine Großenordnung etwas

großer als n hat.

Eine solche Großenordnung ist z.B. n ¨ log n.

Optimale Sortierverfahren haben diese Großenordnung.

Beispiele fur Rechenzeitanalysen 4.1.25

Page 723: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Analyse der Rechenzeit von Funktionen mit int-Argument

Die Messreihe geht genauso wie fur Funktionen mit Array-Argument,

aber statt des Array-Arguments wird ein int-Argument genommen,

dessen Lange von Messung zu Messung verdoppelt wird.

Die Verdoppelung der Lange wird (ungefahr) durch Quadrieren erreicht.

Beispiele fur Rechenzeitanalysen 4.1.26

Page 724: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# messreiheInt.py

#-----------------------------------------------------------------------------------

import sys, time

from messreihe import miss

from funktionen import logd as laenge

# Importiere das Modul mit der Funktion, die fur die Messreihe benutzt wird.

exec('from ' + sys.argv[1] + ' import ' + sys.argv[2] + ' as testfunktion')

n = int(sys.argv[3]) # das Argument fur die erste Messung

versuchsdauer = float(sys.argv[4]) # die Dauer der Messreihe in Sekunden

versuchsEnde = time.time() + versuchsdauer # die Uhrzeit, bei der der Versuch beendet wird

letzteMessung = 0 # die Rechenzeit der letzten Messung

# Gib den Kopf fur die Tabelle mit den Messergebnissen aus.

print( ' %12s | %12s | %6s \n%s' % ('Eing.lange', ' Rechenzeit', 'Faktor', '-'*42) )

# Fuhre die Messreihe mit wachsendem n durch, bis die Zeit abgelaufen ist.

while time.time() < versuchsEnde:

# Miss die Rechenzeit von testfunktion(a).

messErgebnis = miss(testfunktion, n)

# Gib das Ergebnis der Messung aus.

if letzteMessung==0: print( ' %15d | %10.3f |' % (laenge(n), messErgebnis) )

else: print( ' %15d | %10.3f | %6.2f ' % (laenge(n), messErgebnis, messErgebnis/letzteMessung) )

# Bereite die nachste Messung vor.

letzteMessung = messErgebnis

n *= n

Beispiele fur Rechenzeitanalysen 4.1.27

Page 725: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse der Halbierung x//2

# funktionen.py

#------------------------------------------

# halbiere(x) gibt die ganzzahlige Halfte

# von x (Typ int) zuruck.

def halbiere( x ):

x = x//2

return x

Experimentelle Analyse:

python3 messreiheInt.py funktionen halbiere 1000000 200

Eing.lange | Rechenzeit | Faktor

-------------------------------------

19 | 0.000 |

39 | 0.000 | 0.11

79 | 0.000 | 1.00

159 | 0.000 | 1.00

318 | 0.000 | 1.00

637 | 0.000 | 7.50

1275 | 0.000 | 0.27

2551 | 0.000 | 1.50

5102 | 0.000 | 4.50

10204 | 0.000 | 0.93

20409 | 0.000 | 1.88

40819 | 0.000 | 1.70

81639 | 0.000 | 1.93

163279 | 0.000 | 1.89

326558 | 0.000 | 2.06

653117 | 0.000 | 1.92

1306235 | 0.001 | 2.32

Bei Verdoppelung der Eingabelange n verdoppelt sich die

Rechenzeit.

Beispiele fur Rechenzeitanalysen 4.1.28

Page 726: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse der Halbierung x//2

# funktionen.py

#------------------------------------------

# halbiere(x) gibt die ganzzahlige Halfte

# von x (Typ int) zuruck.

def halbiere( x ):

x = x//2

return x

Experimentelle Analyse:

Bei Verdoppelung der Eingabelange n verdoppelt sich die

Rechenzeit. Das fuhrt zu der Vermutung, dass die

Rechenzeitfunktion t die Eigenschaft tp2 ¨ nq “ 2 ¨ tpnq.

Da p2 ¨ nq “ 2 ¨ n bzw. da log2 2 “ 1, hat dann

die Rechenzeitfunktion tpnq die Großenordnung n1 (d.h. n).

Beispiele fur Rechenzeitanalysen 4.1.28

Page 727: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse der Halbierung x//2

# funktionen.py

#------------------------------------------

# halbiere(x) gibt die ganzzahlige Halfte

# von x (Typ int) zuruck.

def halbiere( x ):

x = x//2

return x

Abstrakte Analyse:

Die Funktion hat keine Schleifen und nur die Anweisung

x = x//2.

Die Halbierung findet wie mittels”schriftlicher Addition“ statt.

Dabei geht man einmal alle Ziffern der zu halbierenden Zahl

durch und macht fur jede Ziffer eine kleine Anzahl Operationen.

Also erhalt man die Anzahl der Ziffern der Zahl (d.h. ihre

Lange) als Großenordnung der Rechenzeitfunktion, d.h.

tpnq “ n.

Beispiele fur Rechenzeitanalysen 4.1.28

Page 728: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des Quadrierens x*x

# funktionen.py

#------------------------------------------

# quadriere(x) gibt fur x vom Typ int

# gibt x*x zuruck.

def quadriere( x ):

x = x*x

return x

Experimentelle Analyse:

python3 messreiheInt.py funktionen quadriere 10000 100

Eing.lange | Rechenzeit | Faktor

-------------------------------------

13 | 0.000 |

26 | 0.000 | 1.00

53 | 0.000 | 1.50

106 | 0.000 | 1.00

212 | 0.000 | 1.00

425 | 0.000 | 1.33

850 | 0.000 | 1.50

1700 | 0.000 | 2.50

3401 | 0.000 | 4.47

6803 | 0.000 | 2.82

13606 | 0.000 | 2.39

27213 | 0.000 | 2.94

54426 | 0.001 | 2.84

108852 | 0.003 | 3.09

217705 | 0.008 | 2.96

435411 | 0.025 | 2.99

870823 | 0.073 | 2.98

Bei Verdoppelung der Eingabelange n verdreifacht sich die

Rechenzeit.

Beispiele fur Rechenzeitanalysen 4.1.29

Page 729: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des Quadrierens x*x

# funktionen.py

#------------------------------------------

# quadriere(x) gibt fur x vom Typ int

# gibt x*x zuruck.

def quadriere( x ):

x = x*x

return x

Experimentelle Analyse:

Bei Verdoppelung der Eingabelange n verdreifacht sich die

Rechenzeit. Das fuhrt zu der Vermutung, dass die

Rechenzeitfunktion t die Eigenschaft tp2 ¨ nq “ 3 ¨ tpnq hat.

Da p2 ¨ nqlog2 3“ 2 ¨ nlog2 3, hat

die Rechenzeitfunktion tpnq die Großenordnung nlog2 3« n1.58.

Beispiele fur Rechenzeitanalysen 4.1.29

Page 730: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des Quadrierens x*x

# funktionen.py

#------------------------------------------

# quadriere(x) gibt fur x vom Typ int

# gibt x*x zuruck.

def quadriere( x ):

x = x*x

return x

Abstrakte Analyse:

Wenn man wie bei der”schriftlichen Multiplikation“ quadriert,

erhalt man eine Rechenzeit der Großenordnung n2.

Es gibt aber auch andere Algorithmen zum Multiplizieren.

Der Karazuba-Algorithmus hat eine Rechenzeit der

Großenordnung nlog2 3.

Jetzt kann man stark vermuten, dass Python diesen

Algorithmus verwendet.

Bemerkung zur Multiplikation zweier Zahlen:

Die Multiplikation von a und b hat die entsprechende

Rechenzeit der Großenordnung

pLange von a` Lange von bqlog2 3.

Beispiele fur Rechenzeitanalysen 4.1.29

Page 731: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von logd(x)

# funktionen.py

#------------------------------

# logd(x) gibt den ganzzahligen

# 2er-Logarithmus von x zuruck.

def logd( x ):

i = 0

while x>1:

x = x//2

i += 1

return i

Experimentelle Analyse:

python3 messreiheInt.py funktionen logd 1000000 200

Eingabelange n | Rechenzeit | Faktor

--------------------------------------

19 | 0.000 |

39 | 0.000 | 1.63

79 | 0.000 | 1.81

159 | 0.000 | 2.21

318 | 0.000 | 2.41

637 | 0.000 | 2.78

1275 | 0.001 | 2.83

2551 | 0.002 | 3.43

5102 | 0.007 | 3.68

10204 | 0.027 | 3.76

20409 | 0.099 | 3.74

40819 | 0.390 | 3.92

81639 | 1.542 | 3.96

163279 | 6.185 | 4.01

326558 | 24.649 | 3.99

653117 | 98.404 | 3.99

Bei Verdoppelung der Eingabelange vervierfacht sich die Rechenzeit.Beispiele fur Rechenzeitanalysen 4.1.30

Page 732: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von logd(x)

# funktionen.py

#------------------------------

# logd(x) gibt den ganzzahligen

# 2er-Logarithmus von x zuruck.

def logd( x ):

i = 0

while x>1:

x = x//2

i += 1

return i

Experimentelle Analyse:

Bei Verdoppelung der Eingabelange vervierfacht sich die Rechenzeit.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion t die

Eigenschaft tp2 ¨ nq “ 4 ¨ tpnq hat.

Da p2 ¨ nq2 “ 4 ¨ n2 bzw. da log2 4 “ 2, hat

die Rechenzeitfunktion tpnq die Großenordnung n2.

Beispiele fur Rechenzeitanalysen 4.1.30

Page 733: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von logd(x)

# funktionen.py

#------------------------------

# logd(x) gibt den ganzzahligen

# 2er-Logarithmus von x zuruck.

def logd( x ):

i = 0

while x>1:

x = x//2

i += 1

return i

Abstrakte Analyse:

Die Funktion hat eine Schleife.

Bei Eingabelange n wird sie (etwa) n-mal durchlaufen.

In der Schleife findet eine Halbierung statt.

Die Rechenzeit der Halbierung einer Zahl der Lange n hat

Großenordnung n.

Also hat jeder Schleifendurchlauf Rechenzeit der Großenordnung n.

Da die Schleife n-mal durchlaufen wird,

hat die Rechenzeit tpnq die Großenordnung n ¨ n “ n2.

Die innere Schleife (for-Schleife) wird jedesmal, wenn sie erreicht

wird, etwa n-mal durchlaufen.

Beispiele fur Rechenzeitanalysen 4.1.30

Page 734: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des schnellen Potenzierens potenziere(x)

# funktionen.py

#---------------------------------------

# potenziere(n) berechnet "2 hoch n"

# mittels wiederholtem Quadrieren.

def potenziere(x):

if x==0: return 1

elif x==1: return 2

else:

b = potenziere(x//2)

q = b*b

if x%2==0: return q

else: return q*2

Experimentelle Analyse:

python3 messreiheInt.py funktionen potenziere 10 200

Eing.lange | Rechenzeit | Faktor

-------------------------------------

3 | 0.000 |

6 | 0.000 | 1.00

13 | 0.000 | 8.94

26 | 0.647 | 17852.82

Killed

Es scheint keinen festen Faktor zu geben, um den sich die Rechenzeit

bei Verdoppelung der Eingabelange vergroßert.

Beispiele fur Rechenzeitanalysen 4.1.31

Page 735: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des schnellen Potenzierens potenziere(x)

# funktionen.py

#---------------------------------------

# potenziere(n) berechnet "2 hoch n"

# mittels wiederholtem Quadrieren.

def potenziere(x):

if x==0: return 1

elif x==1: return 2

else:

b = potenziere(x//2)

q = b*b

if x%2==0: return q

else: return q*2

Experimentelle Analyse:

Es scheint keinen festen Faktor zu geben, um den sich die Rechenzeit

bei Verdoppelung der Eingabelange vergroßert.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion tpnq keine

Großenordnung n, n2, n3, n4, . . . hat.

D.h. die Funktion hat keine polynomielle Rechenzeit.

Wir konnen sie auf exponentielle Rechenzeit testen.

Dazu andern wir in der Messreihe die Vergroßerung der Eingabelange

von Messung zu Messung.

Bisher – beim Test auf polynomielle Rechenzeit – wird die

Eingabelange von Messung zu Messung verdoppelt (indem der

Eingabewert quadriert wird).

Beim Test auf exponentielle Rechenzeit wird die Eingabelange von

Messung zu Messung um 1 vergroßert (indem der Eingabewert

verdoppelt wird).

Beispiele fur Rechenzeitanalysen 4.1.31

Page 736: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

# messreiheIntExpo.py

#-----------------------------------------------------------------------------------

# wie messreiheInt.py, aber die Lange des Arguments fur die Testfunktionen wird von

# Messung zu Messung um 1 vergroßert, indem das Argument verdoppelt wird.

#-----------------------------------------------------------------------------------

import sys, time

from messreihe import miss

from funktionen import logd as laenge

# Importiere das Modul mit der Funktion, die fur die Messreihe benutzt wird.

exec('from ' + sys.argv[1] + ' import ' + sys.argv[2] + ' as testfunktion')

n = int(sys.argv[3]) # das Argument fur die erste Messung

versuchsdauer = float(sys.argv[4]) # die Dauer der Messreihe in Sekunden

versuchsEnde = time.time() + versuchsdauer # die Uhrzeit, bei der der Versuch beendet wird

letzteMessung = 0 # die Rechenzeit der letzten Messung

# Gib den Kopf fur die Tabelle mit den Messergebnissen aus.

print( ' %14s | %12s | %6s \n%s' % ('Eingabelange n', ' Rechenzeit', 'Faktor', '-'*42) )

# Fuhre die Messreihe mit wachsendem n durch, bis die Zeit abgelaufen ist.

while time.time() < versuchsEnde:

# Miss die Rechenzeit von testfunktion(a).

messErgebnis = miss(testfunktion, n)

# Gib das Ergebnis der Messung aus.

if letzteMessung==0: print( ' %15d | %10.3f |' % (laenge(n), messErgebnis) )

else: print( ' %15d | %10.3f | %6.2f ' % (laenge(n), messErgebnis, messErgebnis/letzteMessung) )

# Bereite die nachste Messung vor.

letzteMessung = messErgebnis

n *= 2

Beispiele fur Rechenzeitanalysen 4.1.32

Page 737: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von fiboDirekt(x)

# funktionen.py

#---------------------------------------------------

# fiboDirekt(x) gibt die x-te Fibonacci-Zahl zuruck.

# Die Berechnung erfolgt iterativ.

def fiboDirekt(x):

a = 0

b = 1

for i in range(2,x+1):

b, a = a+b, b

return b

Experimentelle Analyse auf exponentielle Rechenzeit:

python3 messreiheIntExpo.py funktionen fiboDirekt 10000 40

Eing.lange | Rechenzeit | Faktor

------------------------------------

13 | 0.004 |

14 | 0.011 | 2.68

15 | 0.034 | 3.12

16 | 0.115 | 3.33

17 | 0.409 | 3.57

18 | 1.556 | 3.80

19 | 6.089 | 3.91

20 | 24.310 | 3.99

21 | 98.427 | 4.05

Bei Vergroßerung der Eingabelange um 1 vervierfacht sich die

Rechenzeit.

Beispiele fur Rechenzeitanalysen 4.1.33

Page 738: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von fiboDirekt(x)

# funktionen.py

#---------------------------------------------------

# fiboDirekt(x) gibt die x-te Fibonacci-Zahl zuruck.

# Die Berechnung erfolgt iterativ.

def fiboDirekt(x):

a = 0

b = 1

for i in range(2,x+1):

b, a = a+b, b

return b

Experimentelle Analyse auf exponentielle Rechenzeit:

Bei Vergroßerung der Eingabelange um 1 vervierfacht sich die

Rechenzeit.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion t die

Eigenschaft tpn ` 1q “ 4 ¨ tpnq hat.

Da 4n`1“ 4 ¨ 4n, hat dann

die Rechenzeitfunktion tpnq die Großenordnung 4n.

Beispiele fur Rechenzeitanalysen 4.1.33

Page 739: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von fiboDirekt(x)

# funktionen.py

#---------------------------------------------------

# fiboDirekt(x) gibt die x-te Fibonacci-Zahl zuruck.

# Die Berechnung erfolgt iterativ.

def fiboDirekt(x):

a = 0

b = 1

for i in range(2,x+1):

b, a = a+b, b

return b

Abstrakte Analyse:

Die Funktion hat eine Schleife.

Bei Eingabelange n wird sie (etwa) 2n-mal durchlaufen.

Die Fibonacci-Zahlen wachsen sehr schnell.

Die Großenordnung der Fibonacci-Funktion fibpxq ist 2x .

Da fibpxq in der Funktion im Extremfall etwa 22n ist,

benotigt die Addition in der Schleife Zeit der Großenordnung

log2 22n“ 2n.

Da die Schleife 2n-mal durchlaufen wird,

hat die Rechenzeit tpnq der Funktion die Großenordnung

2n¨ 2n

“ 22n“ 4n.

Beispiele fur Rechenzeitanalysen 4.1.33

Page 740: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von fiboSchnell(x)

# funktionen.py

#-----------------------------------------------------

# fibo(b) gibt (fib_{b-1},fib_{b}) zuruck.

# Es gilt:

# fib_{2n} = fib_{n}*fib_{n-1} + fib_{n+1}*fib_{n}

# fib_{2n+1} = fib_{n}**2 + fib_{n+1}**2

def fibo(b):

if b<=1: return (0,b)

if b%2==1:

(x,y) = fibo(b//2)

return ( y*x+(x+y)*y, y**2+(x+y)**2 )

(x,y) = fibo(b//2)

return ( x*x+y*y, y*(2*x+y) )

#-----------------------------------------------------

# fiboSchnell(n) gibt fib_n zuruck. Die Berechnung

# erfolgt mit der schnellen Funktion fibo(n)

def fiboSchnell(x):

return fibo(x)[1]

Experimentelle Analyse auf exponentielle Rechenzeit:

python3 messreiheIntExpo.py funktionen fiboSchnell 10000 40

Eing.lange | Rechenzeit | Faktor

-------------------------------------

13 | 0.000 |

14 | 0.000 | 2.54

15 | 0.001 | 2.70

16 | 0.002 | 2.80

17 | 0.005 | 3.11

18 | 0.016 | 3.05

19 | 0.046 | 2.95

20 | 0.135 | 2.95

21 | 0.402 | 2.97

22 | 1.222 | 3.04

23 | 3.644 | 2.98

24 | 11.002 | 3.02

25 | 33.748 | 3.07

Bei Vergroßerung der Eingabelange um 1 verdreifacht sich die

Rechenzeit.Beispiele fur Rechenzeitanalysen 4.1.34

Page 741: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von fiboSchnell(x)

# funktionen.py

#-----------------------------------------------------

# fibo(b) gibt (fib_{b-1},fib_{b}) zuruck.

# Es gilt:

# fib_{2n} = fib_{n}*fib_{n-1} + fib_{n+1}*fib_{n}

# fib_{2n+1} = fib_{n}**2 + fib_{n+1}**2

def fibo(b):

if b<=1: return (0,b)

if b%2==1:

(x,y) = fibo(b//2)

return ( y*x+(x+y)*y, y**2+(x+y)**2 )

(x,y) = fibo(b//2)

return ( x*x+y*y, y*(2*x+y) )

#-----------------------------------------------------

# fiboSchnell(n) gibt fib_n zuruck. Die Berechnung

# erfolgt mit der schnellen Funktion fibo(n)

def fiboSchnell(x):

return fibo(x)[1]

Experimentelle Analyse auf exponentielle Rechenzeit:

Bei Vergroßerung der Eingabelange um 1 verdreifacht sich die

Rechenzeit.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion t die

Eigenschaft tpn ` 1q “ 3 ¨ tpnq hat.

Da 3n`1“ 3 ¨ 3n, hat dann

die Rechenzeitfunktion tpnq die Großenordnung 3n.

Beispiele fur Rechenzeitanalysen 4.1.34

Page 742: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse von fiboSchnell(x)

# funktionen.py

#-----------------------------------------------------

# fibo(b) gibt (fib_{b-1},fib_{b}) zuruck.

# Es gilt:

# fib_{2n} = fib_{n}*fib_{n-1} + fib_{n+1}*fib_{n}

# fib_{2n+1} = fib_{n}**2 + fib_{n+1}**2

def fibo(b):

if b<=1: return (0,b)

if b%2==1:

(x,y) = fibo(b//2)

return ( y*x+(x+y)*y, y**2+(x+y)**2 )

(x,y) = fibo(b//2)

return ( x*x+y*y, y*(2*x+y) )

#-----------------------------------------------------

# fiboSchnell(n) gibt fib_n zuruck. Die Berechnung

# erfolgt mit der schnellen Funktion fibo(n)

def fiboSchnell(x):

return fibo(x)[1]

Abstrakte Analyse:

Die Funktion ist rekursiv.

Die Rekursionstiefe ist log2 x – also ungefahr die Lange n von x .

Das fallt nicht weiter ins Gewicht.

Die Fibonacci-Zahlen wachsen sehr schnell.

Die Großenordnung der Fibonacci-Funktion fibpxq ist 2x .

Da fibpxq in der Funktion im Extremfall Lange 2n hat (n ist die

Lange von x),

benotigen die Multiplikationen in den return-Anweisungen

Rechenzeit der Großenordnung p2nq

1.5“ 21.5¨n

“ 3n.

Beispiele fur Rechenzeitanalysen 4.1.34

Page 743: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des schnellen Potenzierens potenziere(x)

# funktionen.py

#---------------------------------------

# potenziere(n) berechnet "2 hoch n"

# mittels wiederholtem Quadrieren.

def potenziere(x):

if x==0: return 1

elif x==1: return 2

else:

b = potenziere(x//2)

q = b*b

if x%2==0: return q

else: return q*2

Experimentelle Analyse:

python3 messreiheIntExpo.py funktionen potenziere 10000 20

Eingabelange n | Rechenzeit | Faktor

------------------------------------------

13 | 0.000 |

14 | 0.000 | 2.03

15 | 0.001 | 2.48

16 | 0.001 | 1.85

17 | 0.002 | 2.14

18 | 0.004 | 2.12

19 | 0.009 | 2.19

20 | 0.019 | 2.07

21 | 0.041 | 2.11

22 | 0.086 | 2.10

23 | 0.183 | 2.13

24 | 0.389 | 2.13

25 | 0.828 | 2.13

26 | 1.755 | 2.12

27 | 3.712 | 2.12

28 | 7.785 | 2.10

29 | 16.315 | 2.10

Bei Vergroßerung der Eingabelange um 1 verdoppelt sich die

Rechenzeit.

Beispiele fur Rechenzeitanalysen 4.1.35

Page 744: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des schnellen Potenzierens potenziere(x)

# funktionen.py

#---------------------------------------

# potenziere(n) berechnet "2 hoch n"

# mittels wiederholtem Quadrieren.

def potenziere(x):

if x==0: return 1

elif x==1: return 2

else:

b = potenziere(x//2)

q = b*b

if x%2==0: return q

else: return q*2

Experimentelle Analyse:

Bei Vergroßerung der Eingabelange um 1 verdoppelt sich die

Rechenzeit.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion t die

Eigenschaft tpn ` 1q “ 2 ¨ tpnq hat.

Da 2n`1“ 2 ¨ 2n, hat dann

die Rechenzeitfunktion tpnq die Großenordnung 2n.

Beispiele fur Rechenzeitanalysen 4.1.35

Page 745: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des langsamen Potenzierens

potenziereLangsam(x)

# funktionen.py

#---------------------------------------

# Berechne "2 hoch n" mittels

# wiederholtem Multiplizieren.

def potenziereLangsam(n):

e = 1

for i in range(n):

e *= 2

return e

Experimentelle Analyse:

python3 messreiheIntExpo.py funktionen potenziereLangsam 100 20

Eingabelange n | Rechenzeit | Faktor

------------------------------------------

6 | 0.000 |

7 | 0.000 | 1.78

8 | 0.000 | 2.43

9 | 0.000 | 2.59

10 | 0.000 | 2.51

11 | 0.001 | 2.75

12 | 0.004 | 3.19

13 | 0.015 | 3.44

14 | 0.052 | 3.49

15 | 0.194 | 3.69

16 | 0.746 | 3.85

17 | 2.975 | 3.99

18 | 11.914 | 4.00

19 | 47.910 | 4.02

Bei Vergroßerung der Eingabelange um 1 vervierfacht sich die

Rechenzeit.

Beispiele fur Rechenzeitanalysen 4.1.36

Page 746: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse des langsamen Potenzierens

potenziereLangsam(x)

# funktionen.py

#---------------------------------------

# Berechne "2 hoch n" mittels

# wiederholtem Multiplizieren.

def potenziereLangsam(n):

e = 1

for i in range(n):

e *= 2

return e

Experimentelle Analyse:

Bei Vergroßerung der Eingabelange um 1 vervierfacht sich die

Rechenzeit.

Das fuhrt zu der Vermutung, dass die Rechenzeitfunktion t die

Eigenschaft tpn ` 1q “ 4 ¨ tpnq hat.

Da 4n`1“ 4 ¨ 4n, hat dann

die Rechenzeitfunktion tpnq die Großenordnung 4n.

Beispiele fur Rechenzeitanalysen 4.1.36

Page 747: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse der binaren Suche binaereNullSuche(a)

#------------------------------------------------------

# binareSuche(liste, ziel) sucht mittels

# binarer Suche nach ziel im (aufsteigend sortierten)

# Array liste.

def binaereSuche(liste, ziel):

links = 0

rechts = len(liste)-1

mitte = (links+rechts)//2

while not liste[mitte]==ziel and links<rechts:

if liste[mitte]>ziel: rechts = mitte-1

else: links = mitte+1

mitte = (links+rechts)//2

if liste[mitte]==ziel: return mitte

else: return -1

#--------------------------------------------------------

# binareNullSuche(liste) sucht mittels binarer Suche

# nach dem Eintrag 0 im sortierten Array liste.

def binaereNullSuche(liste):

return binaereSuche(liste, 0)

Experimentelle Analyse:

python3 messreiheArray.py sortierenUndSuchen \

binaereNullSuche 1000 10

Eing,lange | Rechenzeit | Faktor

------------------------------------

8000 | 0.000 |

16000 | 0.000 | 1.16

32000 | 0.000 | 0.79

64000 | 0.000 | 1.56

128000 | 0.000 | 1.14

256000 | 0.000 | 1.25

512000 | 0.000 | 1.21

1024000 | 0.000 | 1.08

2048000 | 0.000 | 1.02

4096000 | 0.000 | 1.01

Bei Verdoppelung der Eingabelange vergroßert sich die

Rechenzeit kaum. Das fuhrt zu der Vermutung, dass die

Großenordnung der Rechenzeitfunktion kleiner als

polynomiell (n, n2, . . .) ist.Beispiele fur Rechenzeitanalysen 4.1.37

Page 748: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse der binaren Suche binaereNullSuche(a)

#------------------------------------------------------

# binareSuche(liste, ziel) sucht mittels

# binarer Suche nach ziel im (aufsteigend sortierten)

# Array liste.

def binaereSuche(liste, ziel):

links = 0

rechts = len(liste)-1

mitte = (links+rechts)//2

while not liste[mitte]==ziel and links<rechts:

if liste[mitte]>ziel: rechts = mitte-1

else: links = mitte+1

mitte = (links+rechts)//2

if liste[mitte]==ziel: return mitte

else: return -1

#--------------------------------------------------------

# binareNullSuche(liste) sucht mittels binarer Suche

# nach dem Eintrag 0 im sortierten Array liste.

def binaereNullSuche(liste):

return binaereSuche(liste, 0)

Abstrakte Analyse:

Die Funktion enthalt eine while-Schleife.

In jedem Durchlauf der Schleife wird die Große des

Bereichs links...rechts halbiert. Also wird die Schleife

bei Eingabe eines Arrays der Lange n hochstens log2 n-mal

durchlaufen.

Die Indizes, mit denen gerechnet wird, haben hochstens

Wert n und folglich Lange log2pnq.

Halbieren und Addieren mit diesen Indizes haben

Rechenzeit der Großenordnung log2pnq.

Die Rechenzeitfunktion tpnq hat also Großenordnung

log2pnq ¨ log2pnq.

Beispiele fur Rechenzeitanalysen 4.1.37

Page 749: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse eines schnelleren countTriples(a)

# Zahlt die Tripel mit Summe 0 im Array a.

Funktion countTriplesSchnell(a):

sortiere a

count = 0

for i in range(0,len(a)-2):

for j in range(i+1, len(a)-1):

suche mit binarer Suche nach -(a[i]+a[j]) in a

falls es gefunden wurde:

count += 1

return count

Abstrakte Analyse:

Die Funktion sortiert zuerst ein Array der Lange n. Das

hat Rechenzeit der Großenordnung n ¨ logpnq.

Anschließend durchlauft die Funktion zwei

ineinandergeschachtelte Schleifen.

Beispiele fur Rechenzeitanalysen 4.1.38

Page 750: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse eines schnelleren countTriples(a)

# Zahlt die Tripel mit Summe 0 im Array a.

Funktion countTriplesSchnell(a):

sortiere a

count = 0

for i in range(0,len(a)-2):

for j in range(i+1, len(a)-1):

suche mit binarer Suche nach -(a[i]+a[j]) in a

falls es gefunden wurde:

count += 1

return count

Abstrakte Analyse:

Die Funktion sortiert zuerst ein Array der Lange n. Das

hat Rechenzeit der Großenordnung n ¨ logpnq.

Anschließend durchlauft die Funktion zwei

ineinandergeschachtelte Schleifen.

Die Schleifen werden beide jeweils hochsten n-mal

durchlaufen werden.

Im Inneren der Schleifen findet eine binare Suche in einem

Array der Lange n statt. Sie hat Rechenzeit der

Großenordnung plog2pnqq2.

Also hat der Teil der Funktion mit den Schleifen

Rechenzeit der Großenordnung n ¨ n ¨ plog2pnqq2.

Beispiele fur Rechenzeitanalysen 4.1.38

Page 751: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Rechenzeitanalyse eines schnelleren countTriples(a)

# Zahlt die Tripel mit Summe 0 im Array a.

Funktion countTriplesSchnell(a):

sortiere a

count = 0

for i in range(0,len(a)-2):

for j in range(i+1, len(a)-1):

suche mit binarer Suche nach -(a[i]+a[j]) in a

falls es gefunden wurde:

count += 1

return count

Abstrakte Analyse:

Die Funktion sortiert zuerst ein Array der Lange n. Das

hat Rechenzeit der Großenordnung n ¨ logpnq.

Anschließend durchlauft die Funktion zwei

ineinandergeschachtelte Schleifen.

Dieser Teil der Funktion hat Rechenzeit der

Großenordnung n ¨ n ¨ plog2pnqq2.

Die Rechenzeit der Funktion ist die Summe der

Rechenzeiten der beiden Teile”Sortieren“ und

”Schleifen“.

Da die Rechenzeit von”Sortieren“ kleiner ist als die von

”Schleifen“,

Also hat die Funktion eine Rechenzeit der Großenordnung

pn ¨ log2pnqq2.

Da pn ¨ log2pnqq2ă n3, ist diese Funktion schneller als die

am Anfang der Vorlesung implementierte Funktion

countTriples(a).

Beispiele fur Rechenzeitanalysen 4.1.38

Page 752: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Klassifikationen gemaß der Großenordnung des Wachstums der

Rechenzeit

Großenordnung des Wachstums Faktor fur die

VerdoppelungshypotheseBeschreibung Funktion

konstant 1 1

logarithmisch log n 1

linear n 2

linearithmisch n ¨ log n 2.1

quadratisch n2 4

kubisch n3 8

exponentiell 2n 2n

Beispiele fur Rechenzeitanalysen 4.1.39

Page 753: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

Die Großenordnung der Rechenzeit eines Programms oder eines Algorithmus gibt verlassliche Auskunft uber

die”Schnelligkeit“ des Programms.

Wir haben gesehen, wie man sie experimentell abschatzen und abstrakt mathematisch anchweisen kann.

Dabei brauchen wir unterschiedliche experimentelle Tests fur die Analyse auf polynomielle Rechenzeit bzw.

exponentielle Rechenzeit.

Die folgende Tabelle enthalt typische Rechenzeitfunktionen mit dem Namen ihrer Großenordnung, und den

Zuwachs an Rechenzeit eines Programms, das bei Eingabegroße m wenige Sekunden braucht, bei einer

Eingabe der Große 100 ¨m.

Großenordnung der Verlangerung der

Rechenzeitfunktion Beispiel Rechenzeit (s.o.)

linear tp`q “ ` wenige Minuten

quasi-linear tp`q “ ` ¨ log ` wenige Minuten

quadratisch tp`q “ ` 2 einige Stunden

kubisch tp`q “ ` 3 ein paar Wochen

exponentiell tp`q “ 2` ewig 4.1.40

Page 754: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

4.6 Suche nach Wegen in NetzwerkenDas Small-World-Phanomen

Die Untersuchung von Netzwerken hat sich – verstarkt durch die weltweite Vernetzung – zu einem

lebendigen Forschungsgebiet entwickelt.

Aber bereits in den 1960er Jahren hat man sich mit Fragen beschaftigt, die man erst seit wenigen

Jahren z.B. mit den”Freundschaftsnetzwerk“ der sozialen Netzwerke beantworten kann.

Das Small-World-Experiment (Stanley Milgram, 1967) sollte herausfinden, wie kurz der”Abstand“

zwischen zwei beliebigen Menschen ist. Dieser Abstand ist die Lange der kurzesten Kette von

Freunden, Freunden von Freunden usw., die die beiden Menschen verbindet. Milgram vermutete,

dass diese Ketten zwischen zwei beliebigen Menschen hochstens Lange 6 haben.

Wir werden sehen, wie man das algorithmisch uberprufen konnte, wenn wir das

Freunschaftsnetzwerk hatten.

Da wir es nicht haben, schauen wir uns die Frage abstrakt an und losen sie fur beliebige Netzwerke.

Das Small-World-Phanomen 4.6.1

Page 755: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Vorlesung 12

4. Algorithmen

4.1 Rechenzeit

4.6 Das Small-World-Problem und die Suche nach Wegen in NetzwerkenNetzwerke und ihre Speicherung

Kurzeste Wege in Netzwerken

Kurzeste Wege in gewichteten Netzwerken

Das Small-World-Phanomen 4.6.2

Page 756: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

1 Netzwerke (aus Knoten und Kanten)

Unser Beispielnetzwerk besteht aus Flughafen und Direktflugen zwischen ihnen.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

Knoten

a b Kante zwischen Knoten a und Knoten b (und zwischen b und a)

Knoten

(Flughafen)

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI

Kanten

(Direktfluge in

beide Richtungen)

FRA TXL

FRA AMS

AMS CDG

CDG LCY

LCY AMS

TXL WMI

WMI XYG

CDG MRS

MRS GVA

MRS FCO

GVA XYG

FCO XYG

FRA GVA

FRA XYG

Netzwerke 4.6.3

Page 757: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Noch ein Netzwerk (aus Knoten und Kanten)

aus: Introduction to Programming in Python (Sedgewick, Wayne, Dondero, 2015)

Netzwerke 4.6.4

Page 758: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Anwendungen von Netzwerken

§ Verkehrssysteme

§ Kommunikationssysteme

§ Humanbiologie

§ Soziale Netzwerke

§ Physikalische Systeme

§ Softwaresysteme

§ Finanzsysteme

Netzwerke 4.6.5

Page 759: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Darstellung von Netzwerken als Textdateien

(siehe z.B. flights.txt und movies.txt)

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI

Pro Zeile: ein Knoten und weitere Knoten, zu

denen er eine Kante hat.

Dazwischen jeweils ein Trennzeichen.

Kanten konnen mehrfach vorkommen.

beispielnetzwerk.txt:

FRA TXL

FRA AMS

AMS CDG

...

GVA XYG

FCO XYG

FRA GVA

FRA XYG

bspnetzwerk.txt:

FRA/TXL/AMS/GVA/XYG

AMS/FRA/LCY/CDG

CDG/LCY/MRS

TXL/WMI

XYG/WMI/FCO/GVA

MRS/GVA/FCO

Netzwerke 4.6.6

Page 760: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Speicherung von Netzwerken

Netzwerke werden als Dictionaries aus Knoten mit Arrays ihrer Nachbarn gespeichert.

A C D

E B

Schlussel Wert

(Knoten x) (Array der Nachbarn von x)

A [ C, B, E, D ]

B [ A, D ]

D [ B, C, A ]

C [ A, D, E ]

E [ A, C ]

Dictionary aus Knoten (Schlussel) und Arrays (Werte) aus Nachbarn des Schlussels

Netzwerke 4.6.7

Page 761: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Wir benutzen zwei etwas großere Beispiel-Netzwerke:

movies.txt enthalt Titel/Schauspieler zu 4188 Filmen,

flights.txt ist eine Datei mit Start-/Zielflughafen von 67000 Linienflugen.

$ python showneighbours.py movies.txt /

Manhattan (1979)

Streep, Meryl

Conroy, Frances

Murphy, Michael (I)

Allen, Woody

...

Allen, Woody

Husbands and Wives (1992)

Deconstructing Harry (1997)

Bananas (1971)

Stanley Kubrick: A Life in Pictures (2001)

New York Stories (1989)

...

$ python showneighbours.py flights.txt " "

ERF

PMI

FUE

LPA

AYT

LGW

TFS

LEJ

BCN

DME

ACE

AGA

IST

FUE

FNC

MUC

CGN

...

Netzwerke 4.6.8

Page 762: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Kurzeste Wege in Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein (ungewichtetes) Netzwerk ist die Anzahl seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA (Lange 4).

CDG–AMS–FRA ist ein anderer Weg von CDG nach FRA (Lange 2).

Das ist auch ein kurzester Weg zwischen CDG und FRA. Kurzeste Wege in Netzwerken 4.6.9

Page 763: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Kurzeste Wege in Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein (ungewichtetes) Netzwerk ist die Anzahl seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA (Lange 4).

CDG–AMS–FRA ist ein anderer Weg von CDG nach FRA (Lange 2).

Das ist auch ein kurzester Weg zwischen CDG und FRA. Kurzeste Wege in Netzwerken 4.6.9

Page 764: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Kurzeste Wege in Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein (ungewichtetes) Netzwerk ist die Anzahl seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA (Lange 4).

CDG–AMS–FRA ist ein anderer Weg von CDG nach FRA (Lange 2).

Das ist auch ein kurzester Weg zwischen CDG und FRA. Kurzeste Wege in Netzwerken 4.6.9

Page 765: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

2 Kurzeste Wege in Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein (ungewichtetes) Netzwerk ist die Anzahl seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI

Es kann verschiedene kurzeste Wege zwischen zwei Knoten geben

(z.B. zwischen LCY und GVA).Kurzeste Wege in Netzwerken 4.6.9

Page 766: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

Warteschlange

CDG

Entfernung bekannt

CDG

Vorganger

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 767: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

Warteschlange

CDG

Entfernung bekannt

CDG

Vorganger

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 768: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

Warteschlange

CDG

LCY

Entfernung bekannt

CDG

LCY

Vorganger

LCY CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 769: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

Warteschlange

CDG

LCY

AMS

Entfernung bekannt

CDG

LCY

AMS

Vorganger

LCY CDG

AMS CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 770: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

Warteschlange

CDG

LCY

AMS

MRS

Entfernung bekannt

CDG

LCY

AMS

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 771: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

Warteschlange

LCY

AMS

MRS

Entfernung bekannt

CDG

LCY

AMS

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 772: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCYWarteschlange

LCY

AMS

MRS

Entfernung bekannt

CDG

LCY

AMS

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 773: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCYWarteschlange

AMS

MRS

Entfernung bekannt

CDG

LCY

AMS

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 774: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

Warteschlange

AMS

MRS

Entfernung bekannt

CDG

LCY

AMS

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 775: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

Warteschlange

AMS

MRS

FRA

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 776: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

Warteschlange

MRS

FRA

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 777: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

Warteschlange

MRS

FRA

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 778: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

Warteschlange

MRS

FRA

GVA

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 779: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

Warteschlange

FRA

GVA

FCO

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 780: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

Warteschlange

FRA

GVA

FCO

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 781: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

Warteschlange

FRA

GVA

FCO

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 782: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

Warteschlange

FRA

GVA

FCO

TXL

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die WarteschlangeKurzeste Wege in Netzwerken 4.6.10

Page 783: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

Warteschlange

FRA

GVA

FCO

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 784: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

Warteschlange

GVA

FCO

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 785: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

Warteschlange

GVA

FCO

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 786: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

Warteschlange

FCO

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 787: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

Warteschlange

FCO

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 788: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

Warteschlange

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 789: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXLWarteschlange

TXL

XYG

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 790: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXLWarteschlange

TXL

XYG

WMI

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 791: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXLWarteschlange

XYG

WMI

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 792: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Warteschlange

XYG

WMI

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 793: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

Warteschlange

WMI

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 794: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Warteschlange

WMI

Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 795: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Warteschlange Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Auswahl des aktiven Knotens aus der Warteschlange: erster in der Warteschlange

Der aktive Knoten wird aus der Warteschlange entfernt.

Bearbeitung des aktiven Knotens a: schaue alle Nachbarn b von a an:

falls die Entfernung von b noch nicht bekannt ist:

trage fur b beim Vorganger a ein

trage fur b ein, dass seine Entfernung bekannt ist

setze b in die Warteschlange

Kurzeste Wege in Netzwerken 4.6.10

Page 796: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Warteschlange Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Dieser Algorithmus heißt Breitensuche.

Kurzeste Wege in Netzwerken 4.6.10

Page 797: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in Netzwerken

Wir wollen die kurzesten Wege von CDG zu allen erreichbaren Knoten finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Warteschlange Entfernung bekannt

CDG

LCY

AMS

MRS

FRA

GVA

FCO

TXL

XYG

WMI

Vorganger

LCY CDG

AMS CDG

MRS CDG

FRA AMS

GVA MRS

FCO MRS

TXL FRA

XYG FRA

WMI TXL

Dieser Algorithmus heißt Breitensuche.

Er liefert die Knoten–Vorganger-Kanten – sie bilden den Breitensuchebaum.

(Ein Baum ist ein verbundenes Netzwerk ohne Kreis.)Kurzeste Wege in Netzwerken 4.6.10

Page 798: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Idee fur den Breitensuche-Algorithmus

Eingabe: Netzwerk, Startknoten

Ausgabe: kurzeste Wege vom Startknoten aus durch das Netzwerk

Daten: Netzwerk

Warteschlange (Array)

EntfernungBekannt (Array)

Vorganger (Dictionary)

Ablauf: setze den Startknoten in die Warteschlange

und trage ihn bei EnfernungBekannt ein

solange die Warteschlange nicht leer ist wiederhole:

entferne den ersten Knoten aus der Warteschlange – das ist der aktive Knoten

fur jeden Nachbarn b des aktiven Knotens im Netzwerk wiederhole:

falls b noch nicht bei EntfernungBekannt eingetragen:

trage b bei Vorganger mit Wert”aktiver Knoten“ ein

trage b bei EntfernungBekannt ein

setze b in die Warteschlange

Vorganger kann nun zur Ausgabe der kurzesten Wege vom Startknoten aus benutzt werdenKurzeste Wege in Netzwerken 4.6.11

Page 799: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Strukturierung in Module

Modul netzwerk.py

Funktion Beschreibung

einlesen(dateiname, t=' ') liest Netzwerk aus Datei dateiname ein und gibt es als Dictionary

zuruck; t ist das Trennzeichen zwischen den Knoten in der Datei.

Die Schlussel im Dictionary sind die Knoten des Netzwerks, und die Werte

sind Arrays aus Knoten, die die Nachbarn des jeweiligen Schlussels sind.

Modul warteschlange.py

Funktion Beschreibung

neueWS() erzeugt eine neue leere Warteschlange und gibt sie zuruck

eintragen(ws,x) tragt x in die Warteschlange ws ein (am Ende)

entfernen(ws) entfernt das erste Element aus der Warteschlange ws und gibt es zuruck

istLeer(ws) gibt True zuruck, falls die Warteschlange ws leer ist, sonst FalseKurzeste Wege in Netzwerken 4.6.12

Page 800: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Modul breitensuche.py

Funktion Beschreibung

wegesuche(netzwerk, startknoten) durchsucht das Netzwerk netzwerk beginnend mit

startknoten mittels Breitensuche und gibt das dabei berechnete Dic-

tionary Vorganger zuruck.

Das Dictionary hat als Schlussel alle Knoten, die im Netzwerk von

startknoten aus erreichbar sind. Die Werte sind die Vorganger der

Schlussel auf einem kurzesten Weg von startknoten zum Schlussel.

Klient weg.py

liest den Dateinamen mit dem Netzwerk und den Start- und Zielknoten von der Kommandozeile

und gibt den kurzesten Weg zwischen den Knoten aus.

Kurzeste Wege in Netzwerken 4.6.13

Page 801: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

netzwerk.py – Einlesen von Netzwerken

In Vorlesung 07 (Berechnung des PageRanks) hatten wir bereits Netzwerke eingelesen

Wir schreiben das nun nochmal als Funktion auf und machen ein Modul daraus.#-----------------------------------------------------------------------------------------

# netzwerk.py

#-----------------------------------------------------------------------------------------

def einlesen(dateiname, trennzeichen):

datei = open(dateiname, 'r')

netzwerk = dict()

for zeile in datei:

knoten = str.split(zeile, trennzeichen)

if len(knoten)==0: continue

anfangsknoten = str.strip(knoten[0])

if anfangsknoten not in netzwerk: netzwerk[anfangsknoten] = []

for z in range(1,len(knoten)):

zielknoten = str.strip(knoten[z])

if zielknoten not in netzwerk: netzwerk[zielknoten] = []

if zielknoten not in netzwerk[anfangsknoten]: netzwerk[anfangsknoten] += [ zielknoten ]

if anfangsknoten not in netzwerk[zielknoten]: netzwerk[zielknoten] += [anfangsknoten]

datei.close()

return netzwerkKurzeste Wege in Netzwerken 4.6.14

Page 802: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

warteschlange.py – die Funktionen fur die Warteschlange

#------------------------------------------

# warteschlange.py

#------------------------------------------

def neueWS():

ws = dict()

ws['schlange'] = []

ws['anfang'] = 0

return ws

def istLeer(ws):

return ws['anfang']>=len(ws['schlange'])

def eintragen(ws, x):

ws['schlange'] += [x]

def entfernen(ws):

ws['anfang'] += 1

return ws['schlange'][ws['anfang']-1]

Die Warteschlange wird als Dictionary mit den Schlusseln

'schlange' und 'anfang' implementiert.

Der Wert zu 'schlange' ist ein Array,

und der Wert zu 'anfang' ist der Index im Array, bei

dem die Warteschlange beginnt.

Falls dieser Anfangs-Index großer oder gleich der Lange

des Arrays ist, idt die Warteschlange leer.

In einer neuen (leeren) Warteschlange ist das Array leer

und der Anfangs-Index ist 0.

Ein Element x wird in die Warteschlange eingetragen,

indem es an das Array angehangt wird.

Das erste Element wird aus der Warteschlange entfernt,

indem der Anfangs-Index um 1 erhoht wird.(Die Implementierung ist nicht optimal, da die Elemente nicht aus

dem Array entfernt werden und deshalb Speicherplatz verschwendet

wird. Dafur sparen wir hier Rechenzeit.)Kurzeste Wege in Netzwerken 4.6.15

Page 803: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

breitensuche.py – die Implementierung der Breitensuche

# breitensuche.py

#-------------------------------------------------------

from warteschlange import *

def wegesuche(netzwerk, startknoten):

entfernungBekannt = []

vorgaenger = dict()

warteschlange = neueWS()

eintragen(warteschlange, startknoten)

entfernungBekannt += [startknoten]

while not istLeer(warteschlange):

aktiverKnoten = entfernen(warteschlange)

for k in netzwerk[aktiverKnoten]:

if k not in entfernungBekannt:

vorgaenger[k] = aktiverKnoten

entfernungBekannt += [k]

eintragen(warteschlange, k)

return vorgaenger

Die Implementierung der Funktion

breitensuche() entspricht genau der Idee

(siehe Seite . . . ).

Ruckgabewert ist das Dictionary mit dem

Netzwerk aus Knoten und ihren Vorgangern auf

dem kurzesten Weg vom Startknoten.

Kurzeste Wege in Netzwerken 4.6.16

Page 804: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

weg.py – der Klient fur die Wegsuche

#-------------------------------------------------

# weg.py

#-------------------------------------------------

def rueckweg(vorgaenger, ziel):

rweg = [ ziel ]

while ziel in vorgaenger:

rweg += [ vorgaenger[ziel] ]

ziel = vorgaenger[ziel]

return rweg

def rekonstruiereWeg(vorgaenger, ziel):

weg = rueckweg(vorgaenger, ziel)

weg.reverse()

return weg

def laengsterKuerzesterWeg(vorgaenger, start):

maxWeglaenge = 0

fernstesZiel = start

for ziel in vorgaenger:

rweg = rueckweg(vorgaenger,ziel)

if len(rweg)-1>maxWeglaenge:

maxWeglaenge = len(rweg)-1

fernstesZiel = ziel

return fernstesZiel

rueckweg(vorgaenger, ziel) beginnt im

Dictionary vorgaenger mit dem Schlussel/Knoten

ziel und geht zu dessen Vorganger, Vorvorganger

etc., bis der Knoten mit dem Vorganger None (d.h.

ohne Vorganger) erreicht wird, bei dem die

Breitensuche begann. Der dabei durchlaufene Weg

wird im Array weg gespeichert, das am Ende der

Funktion zuruckgegeben wird.

rekonstruiereWeg(vorgaenger, ziel) dreht den

von rueckweg(vorgaenger, ziel) berechneten

Weg um. Damit hat man einen kurzesten Weg vom

Starknoten der Breitensuche zu ziel.

laengsterKuerzesterWeg(vorgaenger, start)

sucht den langsten kurzesten Weg, der bei der in

start begonnenen Breitensuche gefunden wurde, und

gibt seinen Endknoten zuruck.

Kurzeste Wege in Netzwerken 4.6.17

Page 805: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

weg.py – der Klient fur die Wegsuchedef test():

from breitensuche import wegesuche

import sys

from netzwerk import einlesen

dateiname, trennzeichen = sys.argv[1:3]

netzwerk = einlesen(dateiname, trennzeichen)

startknoten, zielknoten = sys.argv[3:5]

vorgaenger = wegesuche(netzwerk, startknoten)

if not zielknoten in vorgaenger:

print('Es gibt keinen Weg von %s zu %s.' % (startknoten, zielknoten))

else:

print('Ein kurzester Weg von %s nach %s ist ' % (startknoten, zielknoten), end='')

print( str(rekonstruiereWeg(vorgaenger, sys.argv[4])) + '.' )

print('Ein langster kurzester Weg von %s ist ' % (startknoten), end='')

print(str(rekonstruiereWeg(vorgaenger, laengsterKuerzesterWeg(vorgaenger, startknoten))) + '.')

#-------------------------------------------------------------------------------------------

Der Test-Klient liest den Dateinamen mit der Netzwerk-Datei, das darin verwendete Trennzeichen, einen

Start- und einen Zielknoten von der Kommandozeile,

fuhrt die Breitensuche in dem Netzwerk vom Startknoten aus, und gibt einen kurzesten Weg zwischen

Start- und Zielknoten sowie den langsten kurzesten Weg vom Startknoten aus.

Kurzeste Wege in Netzwerken 4.6.18

Page 806: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 weg.py flights.txt ' ' ERF JFK

Ein kurzester Weg von ERF nach JFK ist ['ERF', 'AYT', 'ZRH', 'JFK'].

Ein langster kurzester Weg von ERF ist ['ERF', 'AYT', 'FRA', 'SEA', 'LKE', 'FBS', 'RCE', 'DHB',

'WSX', 'LPS'].

$ python3 weg.py movies.txt / 'Allen, Woody' 'Loren, Sophia'

Ein kurzester Weg von Allen, Woody nach Loren, Sophia ist ['Allen, Woody', 'Annie Hall (1977)',

'Aiello, Danny', 'Pret-a-Porter (1994)', 'Loren, Sophia'].

Ein langster kurzester Weg von Allen, Woody ist ['Allen, Woody', 'Hannah and Her Sisters (1986)',

'von Sydow, Max (I)', 'Pelle erobreren (1987)', 'Granath, Bjorn', 'Ondskan (2003)',

'Hjulstrom, Lennart', 'Mitt liv som hund (1985)', 'Carlsson, Ralph', 'Fucking Amal (1998)',

'Strom, Patrik'].

Kurzeste Wege in Netzwerken 4.6.19

Page 807: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 weg.py flights.txt ' ' ERF JFK

Ein kurzester Weg von ERF nach JFK ist ['ERF', 'AYT', 'ZRH', 'JFK'].

Ein langster kurzester Weg von ERF ist ['ERF', 'AYT', 'FRA', 'SEA', 'LKE', 'FBS', 'RCE', 'DHB',

'WSX', 'LPS'].

$ python3 weg.py movies.txt / 'Allen, Woody' 'Loren, Sophia'

Ein kurzester Weg von Allen, Woody nach Loren, Sophia ist ['Allen, Woody', 'Annie Hall (1977)',

'Aiello, Danny', 'Pret-a-Porter (1994)', 'Loren, Sophia'].

Ein langster kurzester Weg von Allen, Woody ist ['Allen, Woody', 'Hannah and Her Sisters (1986)',

'von Sydow, Max (I)', 'Pelle erobreren (1987)', 'Granath, Bjorn', 'Ondskan (2003)',

'Hjulstrom, Lennart', 'Mitt liv som hund (1985)', 'Carlsson, Ralph', 'Fucking Amal (1998)',

'Strom, Patrik'].

Warum lauft das Programm so langsam?

Kurzeste Wege in Netzwerken 4.6.19

Page 808: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 weg.py flights.txt ' ' ERF JFK

Ein kurzester Weg von ERF nach JFK ist ['ERF', 'AYT', 'ZRH', 'JFK'].

Ein langster kurzester Weg von ERF ist ['ERF', 'AYT', 'FRA', 'SEA', 'LKE', 'FBS', 'RCE', 'DHB',

'WSX', 'LPS'].

$ python3 weg.py movies.txt / 'Allen, Woody' 'Loren, Sophia'

Ein kurzester Weg von Allen, Woody nach Loren, Sophia ist ['Allen, Woody', 'Annie Hall (1977)',

'Aiello, Danny', 'Pret-a-Porter (1994)', 'Loren, Sophia'].

Ein langster kurzester Weg von Allen, Woody ist ['Allen, Woody', 'Hannah and Her Sisters (1986)',

'von Sydow, Max (I)', 'Pelle erobreren (1987)', 'Granath, Bjorn', 'Ondskan (2003)',

'Hjulstrom, Lennart', 'Mitt liv som hund (1985)', 'Carlsson, Ralph', 'Fucking Amal (1998)',

'Strom, Patrik'].

Warum lauft das Programm so langsam?(1) Die Wahl eines Arrays fur entfernungBekannt ist schlecht. Bei der Frage, ob ein Knoten in dem Array ist, wirddas ganze Array

”von links nach rechts“ durchsucht. Besser ist die Wahl eines Dictionaries mit Schlusseln ohne Wert

(d.h. mit Wert None). Bei Dictionaries geht die Suche nach einem Schlussel viel schneller.Kurzeste Wege in Netzwerken 4.6.19

Page 809: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

$ python3 weg.py flights.txt ' ' ERF JFK

Ein kurzester Weg von ERF nach JFK ist ['ERF', 'AYT', 'ZRH', 'JFK'].

Ein langster kurzester Weg von ERF ist ['ERF', 'AYT', 'FRA', 'SEA', 'LKE', 'FBS', 'RCE', 'DHB',

'WSX', 'LPS'].

$ python3 weg.py movies.txt / 'Allen, Woody' 'Loren, Sophia'

Ein kurzester Weg von Allen, Woody nach Loren, Sophia ist ['Allen, Woody', 'Annie Hall (1977)',

'Aiello, Danny', 'Pret-a-Porter (1994)', 'Loren, Sophia'].

Ein langster kurzester Weg von Allen, Woody ist ['Allen, Woody', 'Hannah and Her Sisters (1986)',

'von Sydow, Max (I)', 'Pelle erobreren (1987)', 'Granath, Bjorn', 'Ondskan (2003)',

'Hjulstrom, Lennart', 'Mitt liv som hund (1985)', 'Carlsson, Ralph', 'Fucking Amal (1998)',

'Strom, Patrik'].

Warum lauft das Programm so langsam?

(2) Bei laengsterKuerzesterWeg() wird immer wieder die gleiche Information berechnet. Wenn man z.B. bereits

weiß, dass der Weg von ’X’ zum Startknoten Lange 50 hat und ’Y’ hat ’X’ als Vorganger auf dem kurzesten Weg,

dann weiß man sofort die Lange 51 des Weges von ’X’ zum Startknoten. Dieses Wissen nutzt das Programm nicht

aus.Kurzeste Wege in Netzwerken 4.6.19

Page 810: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Kurzeste Wege in gewichteten Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein gewichtetes Netzwerk ist die Summe der Gewichte seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI2

36

2

3 2

6

13

2

2

2

41

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA mit Lange 7.

CDG–LCY–AMS–FRA ist ein anderer Weg von CDG nach FRA mit Lange 8.

CDG–MRS–FCO–XYG–FRA ist der kurzeste Weg zwischen CDG und FRA (Lange 6).Kurzeste Wege in gewichteten Netzwerken 4.6.20

Page 811: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Kurzeste Wege in gewichteten Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein gewichtetes Netzwerk ist die Summe der Gewichte seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI2

36

2

3 2

6

13

2

2

2

41

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA mit Lange 7.

CDG–LCY–AMS–FRA ist ein anderer Weg von CDG nach FRA mit Lange 8.

CDG–MRS–FCO–XYG–FRA ist der kurzeste Weg zwischen CDG und FRA (Lange 6).Kurzeste Wege in gewichteten Netzwerken 4.6.20

Page 812: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Kurzeste Wege in gewichteten Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein gewichtetes Netzwerk ist die Summe der Gewichte seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI2

36

2

3 2

6

13

2

2

2

41

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA mit Lange 7.

CDG–LCY–AMS–FRA ist ein anderer Weg von CDG nach FRA mit Lange 8.

CDG–MRS–FCO–XYG–FRA ist der kurzeste Weg zwischen CDG und FRA (Lange 6).Kurzeste Wege in gewichteten Netzwerken 4.6.20

Page 813: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

3 Kurzeste Wege in gewichteten Netzwerken

Ein Weg von Knoten a zu Knoten b ist eine Folge von Kanten, die mit a beginnt und mit b endet.

Die Lange eines Weges durch ein gewichtetes Netzwerk ist die Summe der Gewichte seiner Kanten.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVA

XYG

WMI2

36

2

3 2

6

13

2

2

2

41

CDG–MRS–GVA–XYG–FRA ist ein Weg von CDG nach FRA mit Lange 7.

CDG–LCY–AMS–FRA ist ein anderer Weg von CDG nach FRA mit Lange 8.

CDG–MRS–FCO–XYG–FRA ist der kurzeste Weg zwischen CDG und FRA (Lange 6).Kurzeste Wege in gewichteten Netzwerken 4.6.20

Page 814: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1

Prioritats-

Warteschlange

CDG 0

Entfernung

bekannt Vorganger

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 815: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

Prioritats-

Warteschlange

CDG 0

Entfernung

bekannt

CDG

Vorganger

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 816: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

Prioritats-

Warteschlange

CDG 0

LCY 2

Entfernung

bekannt

CDG

Vorganger

LCY CDG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 817: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

Prioritats-

Warteschlange

CDG 0

LCY 2

AMS 6

Entfernung

bekannt

CDG

Vorganger

LCY CDG

AMS CDG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 818: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

Prioritats-

Warteschlange

CDG 0

LCY 2

AMS 6

MRS 1

Entfernung

bekannt

CDG

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 819: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

Prioritats-

Warteschlange

LCY 2

AMS 6

MRS 1

Entfernung

bekannt

CDG

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 820: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

Prioritats-

Warteschlange

LCY 2

AMS 6

MRS 1

Entfernung

bekannt

CDG

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 821: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

Prioritats-

Warteschlange

LCY 2

AMS 6

MRS 1

GVA 4

Entfernung

bekannt

CDG

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

GVA MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 822: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

Prioritats-

Warteschlange

LCY 2

AMS 6

MRS 1

GVA 4

FCO 3

Entfernung

bekannt

CDG

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 823: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

Prioritats-

Warteschlange

LCY 2

AMS 6

GVA 4

FCO 3

Entfernung

bekannt

CDG

MRS

Vorganger

LCY CDG

AMS CDG

MRS CDG

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 824: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

Prioritats-

Warteschlange

LCY 2

AMS 6

GVA 4

FCO 3

Entfernung

bekannt

CDG

MRS

LCY

Vorganger

LCY CDG

AMS CDG

MRS CDG

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 825: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

Prioritats-

Warteschlange

LCY 2

AMS 5

GVA 4

FCO 3

Entfernung

bekannt

CDG

MRS

LCY

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 826: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

Prioritats-

Warteschlange

AMS 5

GVA 4

FCO 3

Entfernung

bekannt

CDG

MRS

LCY

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 827: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

Prioritats-

Warteschlange

AMS 5

GVA 4

FCO 3

Entfernung

bekannt

CDG

MRS

LCY

FCO

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 828: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

Prioritats-

Warteschlange

AMS 5

GVA 4

FCO 3

XYG 5

Entfernung

bekannt

CDG

MRS

LCY

FCO

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 829: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

Prioritats-

Warteschlange

AMS 5

GVA 4

XYG 5

Entfernung

bekannt

CDG

MRS

LCY

FCO

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 830: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

Prioritats-

Warteschlange

AMS 5

GVA 4

XYG 5

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 831: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

Prioritats-

Warteschlange

AMS 5

GVA 4

XYG 5

FRA 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA GVA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 832: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

Prioritats-

Warteschlange

AMS 5

XYG 5

FRA 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA GVA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 833: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

Prioritats-

Warteschlange

AMS 5

XYG 5

FRA 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA GVA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 834: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

Prioritats-

Warteschlange

XYG 5

FRA 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA GVA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 835: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

Prioritats-

Warteschlange

XYG 5

FRA 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA GVA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 836: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

Prioritats-

Warteschlange

XYG 5

FRA 6

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 837: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

Prioritats-

Warteschlange

XYG 5

FRA 6

WMI 11

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI XYG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 838: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

Prioritats-

Warteschlange

FRA 6

WMI 11

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI XYG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 839: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Prioritats-

Warteschlange

FRA 6

WMI 11

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI XYG

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 840: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Prioritats-

Warteschlange

FRA 6

WMI 11

TXL 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI XYG

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 841: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Prioritats-

Warteschlange

WMI 11

TXL 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI XYG

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 842: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Prioritats-

Warteschlange

WMI 11

TXL 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI XYG

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 843: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

Prioritats-

Warteschlange

WMI 10

TXL 8

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI TXL

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 844: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

Prioritats-

Warteschlange

WMI 10

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI TXL

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 845: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Prioritats-

Warteschlange

WMI 10

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI TXL

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 846: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Prioritats-

Warteschlange

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI TXL

TXL FRA

Auswahl des aktiven Knotens aus der Prioritats-Warteschlange: Knoten mit kleinster Entfernung

Bearbeitung des aktiven Knotens a:

trage fur a ein, dass seine Entfernung bekannt ist

schaue alle Nachbarn b von a an, deren Entfernung nicht bekannt ist:

falls b bereits in der Prioritats-Warteschlange ist:

aktualisiere Entfernung (in der Prior.-WS) und seinen Vorganger, falls a”besserer“ Vorganger ist

sonst: trage b und seine Entfernung in die Prioritats-Warteschlange und in die Vorganger-Liste ein

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 847: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Prioritats-

Warteschlange

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI TXL

TXL FRA

Dieser Algorithmus heißt Algorithmus von Dijkstra.

Er liefert die Knoten–Vorganger-Kanten – sie bilden den Kurzesten-Wege-Baum.

(Ein Baum ist ein verbundenes Netzwerk ohne Kreis.)

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 848: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Suche nach kurzesten Wegen in gewichteten Netzwerken

Wir wollen alle kurzesten Wege von CDG aus finden.

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Prioritats-

Warteschlange

Entfernung

bekannt

CDG

MRS

LCY

FCO

GVA

AMS

XYG

FRA

TXL

WMI

Vorganger

LCY CDG

AMS LCY

MRS CDG

GVA MRS

FCO MRS

XYG FCO

FRA XYG

WMI TXL

TXL FRA

Dieser Algorithmus heißt Algorithmus von Dijkstra.

Er liefert die Knoten–Vorganger-Kanten – sie bilden den Kurzesten-Wege-Baum.

(Ein Baum ist ein verbundenes Netzwerk ohne Kreis.)

Kurzeste Wege in gewichteten Netzwerken 4.6.21

Page 849: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Idee fur den Algorithmus von Dijkstra

Eingabe: gewichtetes Netzwerk, Startknoten

Ausgabe: kurzeste Wege vom Startknoten aus durch das gewichtete Netzwerk

Daten: gewichtetes Netzwerk

Prioritats-Warteschlange (Dictionary) (fur Knoten mit Entfernungsmarkierungen)

EntfernungBekannt (Array)

Vorganger (Dictionary)

Ablauf: setze den Startknoten mit Entfernungsmarkierung 0 in die Prioritats-Warteschlange

und trage den Startknoten bei EnfernungBekannt ein

solange die Prioritats-Warteschlange nicht leer ist wiederhole:

entferne den Knoten a mit der kleinsten Entfernungsmarkierung aus der Warteschlange

trage a in EntfernungBekannt ein

fur jeden Nachbarn b von a, der nicht bei EntfernungBekannt eingetragen ist:

e “ Entfernungsmarkierung von a` Gewicht der Kante von a zu b

falls b nicht in der Priorit.-Warteschlange ist: trage b dort mit Entfernungsmark. e ein

sonst: falls e ă Entfernungsmarkierung von b:

andere die Entfernungsmarkierung von b zu e

andere den Vorganger von b zu a

Vorganger kann nun zur Ausgabe der kurzesten Wege vom Startknoten aus benutzt werden

Kurzeste Wege in gewichteten Netzwerken 4.6.22

Page 850: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Darstellung von gewichteten Netzwerken als Textdateien

FRA

TXL

AMS

CDG

FCO

LCY

MRS

GVAXYG

WMI2

36

2

3 2

6

13

2

2

2

4 1

Pro Zeile: ein Knoten und weitere

Knoten/Gewicht-Paare, zu denen er eine Kante

mit dem Gewicht hat.

Dazwischen jeweils ein Trennzeichen.

Kanten konnen mehrfach vorkommen.

gew_beispielnetzwerk:

FRA/TXL/2

FRA/AMS/3

AMS/CDG/6/LCY/3

CDG/LCY/2

TXL/WMI/2

WMI/XYG/6

CDG/MRS/1

MRS/GVA/3

MRS/FCO/2

GVA/XYG/2

FCO/XYG/2

FRA/GVA/4

FRA/XYG/1Kurzeste Wege in gewichteten Netzwerken 4.6.23

Page 851: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Die Speicherung gewichteter Netzwerken

Netzwerke werden als Dictionaries mit Knoten als Schlusseln.

Der Wert zu einem Knoten a ist ein Dictionary

mit Knoten als Schlussel,

so dass der Wert zum Schlussel b das Gewicht der Kante zwischen a und b ist.

A C D

E B

1 2

3 4 5

6Schlussel Wert

(Knoten x) (Dictionary der Nachbarn von x mit Kantengewichten)

A { C:1, E:3, D:6 }

B { D:5 }

D { C:2, A:6, B:5 }

C { A:1, E:4, D:2 }

E { C:4, A:3 }

Kurzeste Wege in gewichteten Netzwerken 4.6.24

Page 852: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Strukturierung in Module

Modul netzwerk.py wird um folgende Funktion erweitert:

Funktion Beschreibung

gew_einlesen(dateiname, t=' ') liest gewichtetes Netzwerk aus Datei dateiname ein und gibt es als

Dictionary zuruck; t ist das Trennzeichen zwischen den Knoten in der Datei.

Die Schlussel im Dictionary sind die Knoten des Netzwerks, und die Werte sind

Dictionaries aus Knoten (Schlussel) und Gewichten (Wert), die die Nachbarn und

das Gewicht der Kanten zwischen den beiden Schlusseln sind.

Modul pwarteschlange.py

Funktion Beschreibung

neueWS() erzeugt eine neue leere Prioritats-Warteschlange und gibt sie zuruck

eintragen(ws,x,k) tragt x mit Wert k in die Prioritats-Warteschlange ws ein

entfernen(ws) entfernt das Element mit dem kleinsten Wert aus der Prioritats-

Warteschlange ws und gibt es zuruck

istLeer(ws) gibt True zuruck, falls die Prioritats-Warteschlange ws leer ist, sonst FalseKurzeste Wege in gewichteten Netzwerken 4.6.25

Page 853: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Modul dijkstra.py

Funktion Beschreibung

wegesuche(netzwerk, startknoten) durchsucht das gewichtete Netzwerk netzwerk beginnend

mit startknoten mittels Breitensuche und gibt das dabei berechnete

Dictionary Vorganger zuruck.

Das Dictionary hat als Schlussel alle Knoten, die im Netzwerk von

startknoten aus erreichbar sind. Die Werte sind die Vorganger der

Schlussel auf einem kurzesten Weg von startknoten zum Schlussel.

Klient gew_weg.py

liest den Dateinamen (und Trennzeichen) mit dem Netzwerk und den Start- und Zielknoten von der

Kommandozeile

und gibt den kurzesten Weg zwischen den Knoten aus.

$ python3 gew_weg.py gew_beispielnetzwerk.txt '/' CDG TXL

Ein kurzester Weg von CDG nach TXL ist ['CDG', 'MRS', 'FCO', 'XYG', 'FRA', 'TXL'].

Der Weg hat Lange 8.Kurzeste Wege in gewichteten Netzwerken 4.6.26

Page 854: Algorithmische Grundlagen Einführung in das Programmieren ... · 4.6 Das Small-World-Problem und die Suche nach Wegen in Netzwerken Die Nummerierung der Kapitel 1, 2 und 4 entspricht

Zusammenfassung

Wir haben Algorithmen zum Finden von kurzesten Wegen in gewichteten und ungewichteten

Graphen implementiert.

Bei der Implementierung haben wir die verschiedenen zu losenden Teilaufgaben auf Module verteilt

und als Funktionen implementiert.

Die Module warteschlange.py und pwarteschlange.py implementieren Datenstrukturen.

Sie dienen der strukturierten Speicherung von Daten und dem Zugriff auf die Speicher-Struktur

uber Funktionen. Dadurch muss der Benutzer nichts uber die konkrete Speicher-Struktur wissem.

(Die Implementierung dieser Speicher-Strukturen ist nicht optimal: sie geht nicht sparsam mit dem Speicher um, und

sie achtet nicht darauf, dass der Zugriff auf die Daten moglichst schnell geht.)

4.6.27