+ All Categories
Home > Documents > AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗...

AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗...

Date post: 14-Jun-2020
Category:
Upload: others
View: 14 times
Download: 1 times
Share this document with a friend
216
Algorithmische Mathematik Thomas Richter * 30. Juni 2019 * Institut für Analysis und Numerik, Universität Magdeburg. Raum 16b, Gebäude 2 ([email protected])
Transcript
Page 1: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Algorithmische Mathematik

Thomas Richter∗

30. Juni 2019

∗Institut für Analysis und Numerik, Universität Magdeburg. Raum 16b, Gebäude 2([email protected])

Page 2: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude
Page 3: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Inhaltsverzeichnis

1. Grundlagen 11.1. Variablen und Schleifen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2. Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.3. Exkurs: Aussagenlogik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

I. Diskrete Aspekte der Algorithmischen Mathematik 17

2. Sortieren 192.1. Ordnung und erstes Sortierverfahren . . . . . . . . . . . . . . . . . . . . . . . . . 192.2. Laufzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252.3. Sortieren bei totaler Ordnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.3.1. Merge Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332.3.2. Quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

2.4. Stabiles Sortieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412.5. Radix-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3. Graphentheorie 473.1. Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473.2. Graphentheoretische Probleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513.3. Darstellung und Umsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

3.3.1. Realisierung in Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583.4. Zusammenhang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

3.4.1. Tiefensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643.4.2. Breitensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

3.5. Suche nach kürzesten Wegen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703.5.1. Dijkstra’s Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

II. Approximation 75

4. Exkurs: Einführung in numpy 77

5. Approximation und Fehler in der Algorithmischen Mathematik 855.1. Zahldarstellung und Fehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

5.1.1. Kondition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875.1.2. Stabilität von Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . . . 88

6. Lineare Gleichungssysteme 976.1. Grundlagen der Linearen Algebra . . . . . . . . . . . . . . . . . . . . . . . . . . 986.2. Störungstheorie und Stabilitätsanalyse von linearen Gleichungssystemen . . . . 107

iii

Page 4: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Inhaltsverzeichnis

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung . . . . . . . . . . . 1106.4. Die Cholesky-Zerlegung für positiv definite Matrizen . . . . . . . . . . . . . . . 1176.5. Dünn besetzte Matrizen und Bandmatrizen . . . . . . . . . . . . . . . . . . . . . 119

6.5.1. Parallele LR-Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1236.6. Iterative Lösungsverfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

6.6.1. Konstruktion von Fixpunktverfahren . . . . . . . . . . . . . . . . . . . . 1286.6.2. Konvergenz von Fixpunktiterationen . . . . . . . . . . . . . . . . . . . . . 130

7. Nullstellen und Extremwerte 1377.1. Methoden zur Nullstellensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

7.1.1. Stabilität und Kondition der Nullstellensuche . . . . . . . . . . . . . . . 1427.1.2. Intervallschachtelung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1447.1.3. Das Newton-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1467.1.4. Varianten des Newton-Verfahrens . . . . . . . . . . . . . . . . . . . . . . 152

7.2. Konvergenzbegriffe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

8. Optimierung 1618.1. Optimalitätsbedingungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1638.2. Abstiegsverfahren und das Gradientenverfahren . . . . . . . . . . . . . . . . . . 169

8.2.1. Das Gradientenverfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . 1708.2.2. Schrittweitenwahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1718.2.3. Konvergenz des Gradientenverfahrens . . . . . . . . . . . . . . . . . . . . 173

8.3. Parameteridentifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1768.3.1. Gaußsche Ausgleichrechnung . . . . . . . . . . . . . . . . . . . . . . . . . 1778.3.2. Allgemeine Parameterschätzungsprobleme . . . . . . . . . . . . . . . . . 1798.3.3. Klassifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1818.3.4. Künstliche neuronale Netze . . . . . . . . . . . . . . . . . . . . . . . . . . 186

Bibliography 203

Verzeichnis der Algorithmen 205

Index 207

iv ©2018 Thomas Richter

Page 5: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Vorwort

Dieses Skript entsteht parallel zur Vorlesung Algorithmische Mathematik im Wintersemester2018/2019 sowie im Sommersemester 2019 an der Universität Magdeburg. Hinweise auf Feh-ler und Verbesserungsvorschläge werden immer gerne entgegengenommen.

v

Page 6: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude
Page 7: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1. Grundlagen

1.1. Variablen und Schleifen

Ziel: Berechnen der Fakultät n! einer natürlichen Zahl n ∈ N.

Definition 1.1 (Fakultät). Es sei n ∈ N mit N = {0, 1, 2, . . . }. Wir definieren

0! := 1 sowie n! :=

n∏i=1

i für n > 1.

mit dem endlichen Produkt von n Zahlen a1, . . . ,an ∈ R, definiert als

n∏i=1

ai := a1 · a2 · · ·an.

Wir wollen diese Aufgabe auf dem Computer in Python umsetzen. Dabei gehen wir davonaus, dass Python keine Funktion zur Berechnung der Fakultät kennt, sondern nur die Grund-rechenarten,+,−, ·, / kennt.Wirmüssen einenAlgorithmus zur Berechnung der Fakultät ent-wickeln.

Definition 1.2 (Algorithmus). EinAlgorithmus ist eine Vorschrift zumLösen (oder zurApproxima-tion, also Berechnung einer näherungsweisen Lösung) einer mathematischen Aufgabe. Ein Algorithmusbesteht aus einzelnen Anweisungen, die

• entweder grundlegende Vorschriften der verwendeten Programmiersprache sind

• oder weitere Algorithmen sind, die bereits auf Basis der Programmiersprache definiert wordensind.

Ein Algorithmus, der eine mathematische Abbildung f : X→ Y umsetzt, benötigt eine Eingabe x ∈ Xund liefert eine Ausgabe y ∈ Y.

In dieser Vorlesung verwenden wir zur Programmierung die Programmiersprache Python.Neben einigen Grundlegenden Informationen in diesem Skript gibt es im Internet eine Viel-zahl von exzellenten (und bestimmt auch eine Vielzahl von sehr schlechten) Skripten, Büchernund Tutorien in Python. Zur Bewältigung dieser Vorlesung gehört auch die eigenständige Re-cherche von Hilfsmaterial zu Python [4, 9].

Die Fakultät von n ist als das Produkt der Zahlen 1 bis n definiert. Ein Algorithmus zur Be-rechnung kann den folgenden Aufbau haben:

• Wir bestimmen die Zahl n ∈ N

1

Page 8: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

• Wir berechnen Stück für Stück das Produkt der Zahlen von 1 bis n, also zunächst 1, dann1 · 2, dann 1 · 2 · 3, usw

Die Zahl n ∈ N und auch die Zwischenwerte 1! = 1, 2! = 1 · 2 speichern wir in Variablen.

Definition 1.3 (Variablen und Datentypen (in Python)). Eine Variable ist eine Bezeichnung füreinen Speicherplatz, der im Programmablauf verschiedene Werte annehmen kann.

Variablen unterscheiden sich in der Art ihres Datentyps. Datentypen können ganze Zahlen, Fließ-kommazahlen zur Approximation von reellen Zahlen, Zeichenketten und vieles mehr sein. Wir be-trachten zunächst nur Zahlen.

Die wichtigste Operation ist die Zuweisung

1 x=4

2 y=1/2

3 z=8∗x−y

Das = ist keine mathematische Gleichheit sondern als Zuweisungsoperator zu lesen: Zunächst wirdder Ausdruck auf der rechten Seite ausgewertet, im Anschluss wird das Ergebnis in die Variable auf derlinken Seite geschrieben.

Variablen können erst verwendet werden, nachdem sie deklariert wurden, also mit einem ers-ten Wert initialisiert wurde. Die Zuweisung

1 x=x+1

funktioniert erst, nachdem x einen Wert erhalten hat. In Python können auch mehrere Wertegleichzeitig zugewiesen werden, z.B.

1 x,y=4,6

2 x,y=y,x

Aber Vorsicht, es werden zunächst alle Ausdrücke der rechten Seite ausgewertet. Erst im An-schluss werden die Variablen auf der linken Seite neu definiert. Welchen Wert haben x,y,znach Ende des folgenden Programms?

1 x,y=4,6

2 x,y,z=y,x,x−y

Zur Berechnung der Fakultät müssen nMultiplikationen durchgeführt werden, dabei soll derAlgorithmus für beliebige Werte von n ∈ N das richtige Ergebnis liefern. Ein zentrales Ele-ment von Programmiersprachen sind Schleifen zur wiederholten Ausführung von einfachenOperationen.

Definition 1.4 (while - Schleife).

1 while BED:

2 Anweisung 1

3 Anweisung 2

4 ...

5 Anweisung n

2 ©2018 Thomas Richter

Page 9: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

Falls die Bedingung BED in Zeile 1wahr ist, so werden die Anweisungen 1 bis n in den kommenden Zei-len alle ausgeführt und im Anschluss springt das Programm wieder in Zeile 1. Falls die Bedingung BEDin Zeile 1 falsch ist, so wird das Programm hinter dem Block mit den Anweisungen 1 bis n fortgeführt.

In Python muss die Bedingung durch ein “:” abgeschlossen werden. Weiter gehören in Python all die-jenigen Anweisungen zur while-Schleife, die durch ein gleichmäßiges Einrücken markiert sind.

Definition 1.5 (Bedingungen). Bedingungen können z.B. einfache mathematische Vergleiche sein

• x<y wahr genau dann, wenn x echt kleiner als y ist

• x>y wahr genau dann, wenn x echt größer als y ist

• x<=y wahr genau dann, wenn x kleiner oder gleich y ist

• x>=y wahr genau dann, wenn x größer oder gleich y ist

• x==y wahr genau dann, wenn x gleich y ist

• x=y! wahr genau dann, wenn x ungleich y ist

• True immer wahr

• False immer falsch

Definition 1.6 (Logische Verknüpfungen). Bedingungen können mit den logischen Schlüsselwor-ten and, or und not verknüpft werden. Dabei sind die Verknüpfungen zu lesen als “und”, “oder” und“nicht”. Einige Beispiele für Bedingungen

• Ein Monat ist größer gleich 1 und kleiner gleich 12(jahr >= 1)and (jahr <= 12).

• Der Eintritt ist frei für Kinder bis 6 Jahr sowie für Rentner ab 67 Jahren sowie für alle, die heuteGeburtstag haben(alter < = 6)or (alter > 66)or (heutegeburtstag)

• Bedingungen können beliebig geschachtelt werden: der Eintritt ist frei für alle zwischen 10 und20 Jahren die heute keinen Geburtstag haben sowie für alle Kinder bis 6 Jahren(alter <= 6)or ( ( (alter>=10)and (alter<=20))and not(heutegeburtstag))

• Der Eintritt ist frei für Kinder bis 6 Jahre sowie für Menschen die größer sind als 180cm(alter <=6 )or (groesse >= 180)

• Der Eintritt ist frei, für Kinder bis 6 oder für Menschen die größer sind als 180cm, nicht aber fürKinder bis 6, die größer als 180cm sind (sogenanntes exklusives oder) ( (alter <=6)and not(↪→ groesse >= 180))or ( not(alter<=6)and (groesse >= 180))

Auch wenn viele der verwendeten Klammern nicht notwendig sind (in Python binden die logi-schen Verknüpfungen schwach) sollten Klammern zur besseren Lesbarkeit und zum Kennzeich-nen logischer Blöcke verwendet werden.

Beispiel 1.7 (while - Schleife). Man überlege sich die Wirkung der folgenden while-Schleifen. Dabeisind die Blöcke jeweils getrennt voneinander zu betrachten.

[email protected] 3

Page 10: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

1 n=1

2 while n<10:

3 n=n+1

4 print(n)

5

6 n=1

7 while n<10:

8 n=n+1

9 n=2∗n10 print(n)

11

12 n=1

13 while n<10:

14 n=n+1

15

16 n=2∗n17 print(n)

18

19 n=1

20 while n<10:

21 n=n+1

22 n=2∗n23 print(n)

Wird eine Variable einfach als Anweisung angegeben (z.B. Zeile 4, 10, usw) so wird der Wertder Variable ausgegeben. Mit diesen Bausteinen können wir einen ersten Programm zur Be-rechnung der Fakultät erstellen

Algorithmus 1.1: Einfache Berechnung der Fakultät1 # Berechnung der Fakultaet

2 n=10 # Eingabe

3

4 i = 1 # Zaehlvariable

5 fak = 1 # Zwischenergebnis i! sowie Endergebnis n!

6

7 while i <= n:

8 fak = fak∗i # Zwischenergebnis i! berechnen als (i−1)! ∗ i9 i = i+1 # i weiterzaehlen

10

11 print(fak) # Ausgabe

Bemerkung 1.8 (Kommentare). Das Symbol # leitet in Python einen Kommentar ein. Ab diesemSymbol wird der Text nicht als Programmbestandteil interpretiert. Zu besseren Lesbarkeit - auch zumErklären der praktischen Programmieraufgaben - solltenmöglichst viele Kommentare verwendet werden,um das Programm zu erklären.

4 ©2018 Thomas Richter

Page 11: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

Was fehlt? Wir können die Eingabe im Programmablauf berechnen und wir können die Aus-gabe schöner gestalten.

WichtigAnweisungen in Programmiersprachen sind Ein- undAusgabeoperationen. In Pythondient die Funktion print der Ausgabe. Einige Beispiele

1 print(’Hallo!’)

2

3 print(’Die Fakultaet von ’,n,’ ist ’,n,’!=’,fak)

Die Eingabe erfolgt in Python mit der Funktion input. Normalerweise entscheidet Pythonselbst, welcher Datentyp gemeint ist. Die Funktion input ist hier eine Ausnahme. Zum einleseneiner ganzen Zahl verwenden wir

1 n = int(input(’Bitte eine ganze Zahl eingeben: ’))

Dabei steht int für integer, hiermit werden ganze Zahlen bezeichnet.

Satz 1.9. Der folgende Algorithmus berechnet für jede Zahl n ∈ N die Fakultät n! und liefert nacheiner endlichen Anzahl von Schritten das Ergebnis:

1 # Berechnung der Fakultaet

2 n = int(input(’Bitte natuerliche Zahl eingeben: ’)) # Eingabe

3

4 fak = 1 # (Zwischen)−Ergebnis und Laufvariable5 i = 1

6 while i <= n: # Abbruch der Schleife?

7 fak = fak∗i # i! berechnen

8 i = i+1 # i weiterzaehlen

9

10 print(’Die Fakultaet von ’,n,’ ist ’,fak) # Ausgabe

Beweis. Der formale Beweis der Korrektheit eines Programms ist nicht einfach und erforderteine vertiefte Einführung in die theoretische Informatik1. Wir geben hier nur eine “Beweis-idee”, die auf dem folgenden Ansatz beruht: Wir definieren klare Vorbedingungen, die zuBeginn des Algorithmus gelten sollen. Im Anschluss teilen wir den Algorithmus in verschie-dene Bereiche, gekennzeichnet durch Zeilennummern, auf. Wir formulieren und BeweisenFolgerungen, die für das Programm jeweils nach einem Abschnitt gelten.

Vorbedingung Wir gehen davon aus dass die in Zeile 3 eingelesene Zahl zulässig ist, alson ∈ Nmit N = {0, 1, 2, . . . }.2

Folgerung 1: in Zeile 5 des Programms gilt

(1.a) i 6 n oder fak = n! sowie i = n+ 1

(1.b) fak = (i− 1)!

1Interessierte finden im Internet (und natürlich der Bibliothek) entsprechende Literatur. Stichwörter sind z.B.formale Programmverifikation, denotationelle Semantik, Hoare Kalkül

2Dies ist die erste Ungenauigkeit. Denn der Benutzer könnte ja durchaus die Eingabe mit −1 oder auch mit 0.5quittieren, also nicht-natürliche Zahlen eingeben.

[email protected] 5

Page 12: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

Es gilt i==1 sowie fak==1. Wegen (1 − 1)! = 0! = 1 ist Bedingung (1.b) somit wahr.

ZumNachweis von Bedingung (1.a)machenwir eine Fallunterscheidung.Wir wissen aus derVorbedingung, dassn ∈ N alson ist eine ganze Zahl, insbesonderen > 0. Angenommen nun,Fall 1, es gilt n = 0. Dann ist 1 = i 6 n = 0 falsch, aber fak = 1 = 0! wahr. Fall 2, es gilt n > 1,dann ist 1 = i 6 n stets wahr. Somit gilt in beiden (also in allen, denn n kann nur> 0 oder= 0sein) Fällen Bedingung (1.a).

Folgerung 2: in Zeile 7. des Programmsgelten stets (d.h. vor sowie nachAusführungderZeilen8 und 9) die beiden folgenden Invarianten:

(2.a) i 6 n oder fak = n! sowie i = n+ 1

(2.b) fak = (i− 1)!

Wir führen den Beweis per Induktion nach der Laufvariable i.

(i) Induktionsanfang.Wegen Folgerung 1 gelten die beide Bedingungen vor dem ersten Durch-lauf der Schleife, denn (1.a) und (2.a) sowie (1.b) und (2.b) sind die gleichen Bedingungen.

(ii) Induktionsschluss. Es gelten die Bedingungen in Zeile 7 vor Ausführung der Zeilen 8 und 9.Wir machen die folgende Fallunterscheidung

1. Es gilt i > n, die Zeilen 8 und 9 werden nicht ausgeführt. D.h., Bedingungen (2.a) und(2.b) gelten weiterhin.

2. Es gilt i 6 n, die Zeilen 8 und 9 werden ausgeführt und es gilt zunächst fak = (i − 1)!sowie i 6 n. Wir gehen beide Zeilen durch. In Zeile 8 wird die rechte Seite ausgewertet,also gilt mit Verwendung von (2.b) (Induktion)

fak · i = (i− 1)! · i = i!

und das Ergebnis wird der Variable fak zugeordnet. Es gilt nach Zeile 8 somit fak = i!.

in Zeile 9 wird in der rechten Seite i um eins erhöht. Somit gilt bei Verwendung (2.a)(Induktion)

i+ 1 6 n+ 1

Das Ergebnis wird der Variable i zugeordnet, somit gilt im Anschluss einerseits

i 6 n+ 1

sowiefak = (i− 1)!

d.h. auf jeden Fall ist (2.b) wahr. Weiter folgt aus i 6 n + 1 mit der Fallunterscheidung:Fall 1, i 6 n dass (2.a)wahr ist und mit Fall 2, i = n+ 1 das ebenso (2.a)wahr ist, dennnun ist fak = (i− 1)! = n!.

6 ©2018 Thomas Richter

Page 13: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

TerminierungWirmüssen noch nachweisen, dass derAlgorithmus eine endliche Laufzeit hat.Zeilen 1-6 sowie 10-11werden nur genau einmal ausgeführt.Wirmüssen nachweisen, dass dieSchleife in Zeilen 7-9 nach einer endlichen Zahl von Schritten abbricht.

Behauptung:Nachm ∈ N Durchläufen der Schleife gilt i = m+ 1. Wir beweisen dies schnellmit Induktion. Zu Beginn, d.h. nach 0 Durchläufen gilt i = 1. Es sei nun für einm die Aussagewahr, d.h. es gelte i = m + 1. Nach einem weiteren Durchlauf wird in Zeile 9, nur diese istrelevant, da Zeile 8 die von uns betrachteten Variablenm und i nicht ändert, die rechte Seitei+ 1 berechnet. Nachm+ 1 Durchläufen gilt also wieder

(i+ 1) = (m+ 1) + 1 ⇒ i = m+ 1.

Hiermit ist die Aussage i = m + 1 bewiesen. Nach m = n Schritten gilt i = n + 1 und dieSchleife bricht in Zeile 7 ab, d.h. das Programm terminiert.

Im Beweis haben wir bereits eine Schwäche des Programms kennengelernt. Wir prüfen nicht,ob die Eingabe n zulässig ist, d.h. ob n eine natürliche Zahl ist. Wir könnten das Programmverbessern, indem wir bei falscher Eingabe mit einer Fehlermeldung reagieren.

if-AnweisungAbfragen, die denweiteren Programmablauf je nach Ergebnis steuern sind zen-tral in jeder Programmiersprache. Einige Beispiele in Python:

1 if BED1:

2 Anweisungen 1

3

4 if BED2:

5 Anweisungen 2

6 else:

7 Anweisungen 3

8

9 if BED4:

10 Anweisungen 4

11 elif BED5:

12 Anweisungen 5

13 else:

14 Anweisungen 6

Die if-Anweisung prüft die Bedingung. Ist die Bedingung wahr, so werden die Anweisungenim folgenden eingerückten Block ausgeführt. Ansonsten wird dieser Block übersprungen unddas Programm geht im Anschluss weiter.

In Python gibt es die optionalen Blöcke else: sowie elif: Der else: Block kann als ansonstengelesen werden. D.h.: ist die Bedingung wahr, so wird der Block gleich nach if: ausgeführt,ist die Bedingung aber nicht wahr, dann wird der Block nach else: ausgeführt. Die weiterenelif: Blöcke (elif für “else if”) können als weitere if-Anweisungen Verstanden werden. D.h. imletzten Beispiel wird zunächst BED4 geprüft, ist diese wahr, so werden die Anweisungen 4 durch-geführt. Ist BED4 aber falsch, so wird geprüft ob BED5wahr ist. In dem Fall werden Anweisungen 5durchgeführt. Ist auch BED5 falsch, so (und nur dann) werden Anweisungen 6 durchgeführt.

Wir könnten unser Programm also erweitern und die Eingabe ergänzen mit

[email protected] 7

Page 14: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.1. Variablen und Schleifen

1 n = int(input(’Bitte natuerliche Zahl eingeben: ’)) # Eingabe

2

3 if n < 0:

4 print(’Fehlerhafte Eingabe. Negative Zahlen sind nicht erlaubt’)

5 print(’Keine Garantie fuer den Programmablauf!’)

Neben der while-Schleife ist die zweite wichtige Struktur die for-Schleife.

for-Schleife Die while-Schleife führt einen Programmblock aus, solange eine bestimmte Be-dingung wahr ist. Die for-Schleife durchläuft einen Programmblock für alle Elemente einerListe. Ein Beispiel

1 for i in [0,1,2,4,8]:

2 print(i)

Die Variable i nimmt nacheinander und in der vorgegebenen Reihenfolge die Werte der Liste[0,1,2,4,8] an und für jeden dieser Werte wird der folgende eingerückte Block durchgeführt.Oft nutzt man die for-Schleife zum Durchlaufen aller Zahlen eines bestimmten Bereichs. Hierstellt Python den praktischen Befehl range zur Verfügung. Man teste die folgenden kurzenSchleifen

1 for i in range(0,10):

2 print(i)

3

4 for i in range(5,9):

5 print(i)

6

7 for i in range(5,1):

8 print(i)

9

10 for i in range(5,1,−1):11 print(i)

12

13 for i in range(0,0.3,1):

14 print(i)

range(a,b,s) liefert Zahl für Zahl Werte a, a+ s, a+ 2s bis die Zahl b nicht erreicht wird. Ist spositiv, so ist die letzte Zahl < b, ist die Zahl s negativ, so ist die letzte Zahl > b.

Listen sind ein weiterer sehr allgemeiner Datentyp in Python. Wir verwenden zunächst nurListen von Zahlen. Diese werden als

1 L = [1,4,20,−5,4]

definiert. Listen können z.B. in for-Schleifen durchlaufen werden. Python stellt viele Befehlebereit um Listen zu modifizieren. Wir gehen davon aus dass durch L eine Liste gegeben ist,unter Umständen die leere Liste L=[].

• len(L) gibt die Anzahl der Element in L zurück.

8 ©2018 Thomas Richter

Page 15: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.2. Funktionen

• L[i], wobei i eine Zahl zwischen 0 und len(L)−1 ist, gibt den i-ten Eintrag der Liste zu-rück. Dabei zählt Python ab der 0.

• L[i,j], wobei i und j Zahlen zwischen 0 und len(L)−1 sind, gibt die Teilliste von Elementi bis Element j− 1 zurück. Bei i > jwird die leere Liste zurückgegeben.

• L.append(x) hängt an die Liste hinten denWert x an. Dies kann auch durch L[len(L):]=[x]erreicht werden.

• L.append(M) hängt an die Liste L hinten die gesamte zweite Liste M an. Dies kann auchdurch L[len(L):]=M erreicht werden.

• L.insert(i,x) fügt das Element x an der Position i ein (das neue Element x steht im An-schluss an der i-ten Stelle).

• L.remove(x) entfernt das erste Auftreten des Element x in L und gibt einen Fehler zurück,falls L das Element x gar nicht enthält.

• L.count(x) gibt zurück, wie oft das Element x in der Liste L enthalten ist.

• L.index(x) gibt den Index zurück an dem das Element x zum ersten mal in der Liste Lauftaucht. Ist das Element nicht enthalten, so wird ein Fehler zurückgegeben.

Wir können die for-Schleife nutzen um die Fakultät zu berechnen.

Algorithmus 1.2: Berechnung der Fakultät mit for-Schleife1 # Berechnung der Fakultaet

2

3 n = int(input(’Bitte natuerliche Zahl eingeben: ’)) # Eingabe

4

5 fak = 1 # (Zwischen)−Ergebnis6

7 for i in range(1,n+1): # Schleife von 1 bis n (einschliesslich)

8 fak = fak∗i # i! berechnen

9

10 print(’Die Fakultaet von ’,n,’ ist ’,fak) # Ausgabe

Da die Funktion range(a,b) die Werte von a bis b− 1 liefert, müssen wir hier die Grenze n+ 1verwenden.

1.2. Funktionen

Ein wichtiges Strukturelement in Programmiersprachen sind Funktionen. Sie erlauben es,Einheiten zusammenzufassen, um sie z.B. mehrfach auszuführen, einmal programmierte Blö-cke in verschiedenen Programmen zu nutzen, oder einfach bessere Struktur zu schaffen. DerSyntax in Python ist wie folgt

Funktionen in Python Funktionen werden in Python folgendermaßen definiert:

[email protected] 9

Page 16: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.2. Funktionen

1 def funktionsname(Param1, Param2, ...):

2 Anweisung 1

3 Anweisung 2

4 ...

5 return rueckgabe

Das Schlüsselwort def startet die Funktionsdefinition, gefolgt von einemNamen der Funktion.Eine Funktion kann (muss aber nicht) Parameter erhalten. Im folgenden eingerückten Blockwerden Anweisungen ausgeführt und schließlich kann (muss aber nicht) eine Rueckgabe mitdem Schlüsselwort return geliefert werden.

Einmal definiert, können Funktionen über ihren Namen aufgerufen werden.

Wir setzen dies am Beispiel der Fakultät um:

Algorithmus 1.3: Funktion zur Berechnung der Fakultät1 def fakultaet(n): # Definition einer Funktion mit einem Parameter n

2 if (n<0): # Abfrage ob n zulaessig

3 print(’Nur positive Zahlen!’)

4 return −15

6 fak = 1 # ab hier Berechnung Fakultaet

7 for i in range(1,n+1):

8 fak = fak ∗ i9 return fak # Rueckgabe des Ergebnis

10

11 ### Jetzt sind ausserhalb der Funktion

12 ### Ausgabe von 0!, 1!, ..., 8!

13 for i in range(0,9):

14 print(’Die Fakultaet von ’,i,’ ist ’,fakultaet(i))

Das Programm hat eine Besonderheit: die if-Anweisung in der Funktion hat die Bedeutungeines entweder - oder, also einer Fallunterscheidung. Aber warum gibt es keinen else-Block?Falls die erste Bedingung korrekt ist, so wird der zweite Teil der Funktion nie erreicht, dadie Funktion mit Hilfe der return-Anweisung beendet wird. Im Sinne der Lesbarkeit wäre esschöner einen else-Block einzufügen.

Funktionen können sich gegenseitig und auch sich selbst aufrufen. Der Selbstaufruf einerFunktion ist ein wichtiges Element der Programmierung, Rekursion genannt.

Definition 1.10 (Rekursion). Unter einer Rekursion versteht man den Selbstaufruf einer Funktion.Ein rekursiv verwendete Funktion bedarf stets einer Verankerung, die zumAbbruch der Rekursion führtund so eine Endlosschleife verhindert.

Rekursion eignet sich z.B. zur Berechnung der Fibonacci-Zahlen, definiert als

f0 := 1, f1 := 1 sowie für n > 2 gilt fn := fn−1 + fn−2,

umgesetzt als

10 ©2018 Thomas Richter

Page 17: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.2. Funktionen

Algorithmus 1.4: Rekursive Berechnung der Fibonacci-Zahlen1 def fibonacci(n):

2 if n <= 1:

3 return 1

4 else:

5 return fibonacci(n−1) + fibonacci(n−2)

Für die Werte n = 0 und n = 1 wird als Ergebnis 1 zurückgegeben. Ansonsten ruft sich dieFunktion gleich zweimal rekursiv selbst auf. Die bisherige Programmierweise wird iterativgenannt, der Programmtext wird Zeile für Zeile hintereinander aufgerufen.

Auch am Beispiel der Fakultät lässt sich die Rekursion gut einsetzen. Denn neben der Defini-tion

n! =

n∏i=1

i

können wir die Fakultät auch rekursiv einführen:

0! = 1 sowie für n > 1 n! = (n− 1)! · n.

Die Fakultät von n ist die Fakultät von n− 1 multipliziert mit n.{algo:fakrek}

Algorithmus 1.5: Rekursive Berechnung der Fakultät1 def fakultaet(n): # rekursive Definition der Fakultaet

2 if n < 0: # Zulaessig?

3 print(’nur positive Zahlen’)

4 return −15 elif n == 0: # Verankerung der rekursiven Definition

6 return 1

7 else: # Rekursion

8 return fakultaet(n−1)∗n

Satz 1.11 (Fakultät mit Rekursion). Die in Algorithmus 1.5 berechnet für jede Eingabe n ∈ N dieFakultät in endlich vielen Schritten.

Beweis. Wir führen den Korrektheitsbeweis per Induktion.

• Für n < 0 ist die Bedingung in Zeile 2 wahr, es werden also Zeilen 3 und 4 ausgeführt.Das Programm liefert korrekterweise eine Fehlermeldung und die Funktion wird mitdem Ergebnis −1 beendet.

• Behauptung: Für n = 0 wir das korrekte Ergebnis, also 0! = 1 berechnet. Beweis: Diesist die eigentliche Verankerung der Induktion. Die Bedingung in Zeile 2 ist falsch, derfolgende Block wird nicht ausgeführt. Die Bedingung in Zeile 5 ist wahr, es wird Zeile 6ausgeführt und die Funktion liefert das korrekte Ergebnis 0! = 1.

• Annahme:Die Funktion berechnet für alle Eingaben 0, 1, . . . ,n−1das korrekte Ergebnis,also die Fakultät von n−1. Behauptung:Unter dieser Annahme berechnet die Funktiondas korrekte Ergebnis für die Eingabe n.

[email protected] 11

Page 18: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.3. Exkurs: Aussagenlogik

Beweis: Es sei nun n > 0 beliebig gegeben. Die Bedingungen in Zeilen 2 und 5 sindfalsch, d.h. die Blöcke in Zeilen 3-4 sowie in Zeile 6 werden nicht ausgeführt. Stattdessenwird der else:-Block, also Zeile 8 ausgeführt. Hier wird der Ausdruck Fakultaet(n−1)∗↪→ n ausgewertet. Laut Induktion gilt Fakultaet(n−1)=(n−1)!. Es wird also das korrekteErgebnis (n− 1)!n = n! zurückgegeben.

Es bleibt, die Terminierung des Programms für beliebige Eingaben nachzuweisen.Wirmachenwieder eine Fallunterscheidung.

• Für n < 0 sowie für n = 0 wird die Funktion mit einer festen Rückgabe beendet.

• Fürn > 0 ruft sich die Funktion rekursivmit demEingabewertn−1 auf.Nachn Schrittenwird Fakultaet(0) aufgerufen und die Berechnung bricht ab.

Bemerkung 1.12 (Rekursion). Rekursion kann sehr elegantes Programmieren ermöglichen. Das zeigtzum Beispiel die sehr kurze Funktion zur Berechnung der Fibonacci-Zahlen. Rekursion hat jedoch ofteinen erheblichenNachteil: sie kann inHinsicht auf Rechenzeit und auch auf Speicherbedarf zu enormenAufwand führen. Man versuche z.B. mit dem Programm oben größere Fibonacci-Zahlen zu berechnen.Wir werden diese Aspekte - Laufzeit und Speicherbedarf - noch eingehend untersuchen.

Bemerkung 1.13 (Bezeichnung von Variablen und Funktionen in Python). Im Gegensatz zueiner normal Sprachemit einemSatz an grammatikalischenRegeln und einemüblicherweise großen aberrecht festem Vokabular leben Programmiersprachen davon, dass ihr Umfang durch selbst geschriebeneFunktionen stets erweitert werden kann. Wir haben schon verschiedene Funktionen zur Berechnung derFakultät oder zur Berechnung der Fibonacci-Zahlen geschrieben.Mit dem Schlüsselwort def könnenwirden Funktionen dabei einen beliebigen Namen geben. Damit die Programme auch im Nachhinein undvon anderen Nutzern verstanden werden können, gibt es Regeln, die (meist) nicht verpflichtend imSinne der Funktionalität, aber im Sinne der Lesbarkeit eingehalten werden sollten:

• Funktionen und auch Variablen dürfen keine Namen benutzen, die bereits reserviert sind, z.B.print, if, else, ...

• Für Funktionsnamen undVariablennamenwerden nurKleinbuchstaben verwendet, etwa ergebnis↪→ = 5, def fakultaet(n):

• Längere Namen werden durch einen _ verknüpft, etwa def fakultaet_rekursiv(n):

Eine ausführliche Darstellung von Regeln guter Programmierung findet sich im Python Style Gui-de [14].

1.3. Exkurs: Aussagenlogik

Wir geben eine stark verkürzte Einführung in die Aussagenlogik. Unter eine Aussage verste-hen wir dabei einen Satz, der üblicherweise wahr oder falsch sein kann. Hier beginnt jedochbereits das erste Problem. Die Aussage Alle Hunde sind weiß ist sicher falsch, der Satz Hundesind Tiere ist wahr. Aber der Satz im Februar schneit es ist nicht entscheidbar. Wir interessierenuns hier aber weniger für die Anwendung der Logik auf Sätze unserer Sprache - dies ist einewichtige Disziplin in der Philosophie - sondern uns geht es um einige Grundlagen der Logikzum besseren Verständnis von Algorithmen.

12 ©2018 Thomas Richter

Page 19: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.3. Exkurs: Aussagenlogik

Wir gehen nun formaler vor und bezeichnen unter einer elementaren Aussage oder einerelementaren Formel einen Ausdruck, der entweder wahr oder falsch sein kann, stellen unsaber nicht die Frage, warum. Wir benennen solche Formeln mit Großbuchstaben.

Definition 1.14 (Junktor). Ein Junktor ist eine logische Verknüpfung zwischen Aussagen. Wir de-finieren die Wirkung eines Junktors durch die vollständige Angabe einer Wahrheitstafel. Die für unswesentlichen Junktoren sind

• die Negation ¬A, gesprochen nicht A,

• die Konjunktion A∧ B, gesprochen A und B,

• die Disjunktion A∨ B, gesprochen A oder B,

• die Implikation A→ B, gesprochenwenn A dann B,

• die Äquivalenz A↔ B oder A = B, gesprochen A genau dann wenn B

mit den Wahrheitstafeln

A B ¬A A∧ B A∨ B A→ B A↔ B

w w f w w w ww f f f w f ff w w f w w ff f w f f w w

Eine Merkregel: und ∧ ist unten offen, oder ∨ ist oben offen.

Imwesentlichen sind die Junktoren definiert, wiewir es im Sprachgebrauch erwartenwürden.Einzig die Implikation erfordert ein wenig Nachdenken, aus einer falschen Aussage kann jedebeliebige Aussage gefolgert werden. Ein einfaches Beispiel: AussageA sei es gilt 0 = 1, AussageB sei es gilt n = n+ 1 für alle Zahlen n ∈ N. Wir folgern mathematisch korrekt A→ B, denn

0 = 1∣∣∣+ n ⇒ 0 + n = n = 1 + n.

Der Schluss A → B ist mathematisch korrekt, das Ergebnis jedoch nicht. Warum? Weil dieAussage A schon falsch war. Dieses Prinzip findet z.B. bei der Beweistechnik der InduktioneineAnwendung.Wir folgern stetsAussagenA(n)→ A(n+1)und gehen stets davon aus, dassdie Aussage A(n) bereits bewiesen ist. Den Induktionsanfang, also den Beweis der WahrheitvonA(1) benötigenwir umdie Schlusskette zu verankern. ZurVerknüpfungAussagenwerdenKlammern verwendet, etwa

(A∧ (B∨ ¬C))→ (C↔ (A∧ ¬D)).

Dabei verwenden wir die Konvention, dass die Negation ¬ stärker bindet als die sonstigenJunktoren, es gilt also stets

(¬A)∧ B↔ ¬A∧ B,

aber im Allgemeinen¬A∧ B 6↔ ¬(A∧ B).

(Es kann natürlich einzelne Belegungen von A und Bmit wahr oder falsch geben, so dass auchdiese Äquivalenz wahr ist).

[email protected] 13

Page 20: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.3. Exkurs: Aussagenlogik

Definition 1.15 (Erfüllbare und unerfüllbare Aussagen, Tautologien). Es sei A eine aus den nelementaren Aussagen A1, . . . ,An verknüpfte Aussage. Wir nennen A

• erfüllbar, falls es mindestens eine Kombination von Wahrheitswerten (A1, . . . ,An) ∈ {w, f}n

gibt, so dass die Aussage A wahr ist.

• unerfüllbar, falls es keine Kombination von Wahrheitswerten (A1, . . . ,An) ∈ {w, f}n gibt, sodass die Aussage A wahr ist.

• eine Tautologie, falls A wahr ist, unabhängig davon ob die elementaren Aussagen A1, . . . ,Anwahr und falsch sind.

Satz 1.16 (De Morgansche Gesetze). Die folgenden Aussagen sind Tautologien

(i) ¬(A∧ B)↔ ¬A∨ ¬B

(ii) ¬(A∨ B)↔ ¬A∧ ¬B

Beweis. Einfache Tautologien können durch Testen aller verschiedenen Belegungen der ele-mentaren Aussagen nachgewiesen werden.

A B A∧ B ¬(A∧ B) ¬A ¬B ¬(A∨ B)

w w w f f f fw f f w f w wf w f w w f wf f f w w w w

Für beliebige Kombinationen der Wahrheitswerte für A und B stimmen die Ergebnisse über-ein, es liegt als eine Tautologie vor. Die zweite Äquivalenz ist auf die gleiche Art zu zeigen.

Man nennt diesen Zugang, das Testen aller mögliche Kombinationen einen brute-force Zugang.Beweise mittels brute-force lassen sich einfach mit Computerunterstützung durchführen. Einentsprechender Algorithmus in Python-Pseudocode (kein lauffähiges Programm) könnte fol-gendermaßen aussehen:

Algorithmus 1.6: Test auf Tautologie1 # Test der Aussage für eine gegebene Belegung

2 def aussage_test(A1, · · ·An):3 if AussageKorrekt für Belegung A1, . . . ,An:4 return wahr

5 else:

6 return falsch

7

8 # Rekursive Funktion zum Test aller Belegungen

9 def test_tautologie(i, A1, . . . ,An):10 # Abbruch negativ, falls Aussage falsch

11 if not(AussageTest(A1, . . . ,Ai−1,w,Ai+1,An)) or not(AussageTest(↪→ A1, . . . ,Ai−1, f,Ai+1,An)):

12 return falsch

14 ©2018 Thomas Richter

Page 21: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.3. Exkurs: Aussagenlogik

13

14 # Abbruch positiv falls alle Kombinationen getestet

15 if i == n:

16 return wahr

17

18 # rekursiver Aufruf

19 return test_tautologie(i+1,A1, . . . ,Ai,w,Ai+2, . . . ,An) and test_tautologie(i↪→ +1,A1, . . . ,Ai, f,Ai+2, . . . ,An)

20

21 # Aufruf der rekursiven Funktion mit der Belegung

22 # A1, . . . ,An = w.23 ist_tautologie = test_tautologie(1,w, · · · ,w)

Dieser Algorithmus setzt wieder auf das Prinzip der Rekursion. Das Verfahren lässt sich leichtabwandeln zumTest auf Erfüllbarkeit oder nicht-Erfüllbarkeit vonAussagen.Wir werden spä-ter auf diesesVerfahren zurückkommenund es hinsichtlichAufwand analysieren:wie oftwirddie Funktion AussageTest aufgerufen, wenn wir eine Aussage aus n elementaren Aussagen un-tersuchen?

Wir fassen nun noch ohne Beweis einige weitere Tautologien zusammen {satz:tautologien}

Satz 1.17 (Tautologien). Die folgenden zusammengesetzten Aussagen sind Tautologien:

(1) A→ A

(2) A∨ ¬A

(3) (A→ B)↔ (¬B→ ¬A)

(4) (A∨ (B∨ C))↔ ((A∨ B)∨ C)

(5) (A∧ (B∧ C))↔ ((A∧ B)∧ C)

(6) ¬(¬A) = A

(7) ((A→ B)∧ (B→ C))→ (A→ C)

(8) (A∨ (B∧ C))↔ ((A∨ B)∧ (A∨ C))

(9) (A∧ (B∨ C))↔ ((A∧ B)∨ (A∧ C))

Von besonderer Bedeutung ist (3), das Prinzip des Widerspruchbeweis: die Folgerung wennA dann B ist genau dann richtig, wenn die Folgerung wenn nicht A dann nicht B wahr ist. DieTautologien (4)-(5) entsprechen dem Assoziativgesetz (wir lassen daher gewisse Klammernweg), (6) ist die doppelte Verneinung, (7) die Transitivität der Implikation, (8)-(9) sind Distri-butivgesetze.

Eine Alternative zum brute-force Verfahren ist das Ausnutzen bereits bekannter Tautologienzur Vereinfachung zusammengesetzter Aussagen. Dieser Zugang lässt sich jedoch nicht im-mer anwenden und ist weitaus schwerer in einemAlgorithmus umzusetzen. Ein Beispiel hier-zu. Wir testen die Aussage(

B∧ ¬(((A→ E)∧ (E→ C))→ (A→ C)

))→ ¬

(C∧

(B∨ ¬(D∧A∧ E)

))(1.1) {LG:A1}{LG:A1}

[email protected] 15

Page 22: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1.3. Exkurs: Aussagenlogik

welche zunächst lang und kompliziert zu sein scheint.Wir identifizieren jedoch (fett unterlegt)die Tautologie (7) aus Satz 1.17. Wir vereinfachen daher (1.1) zu(

B∧ ¬(w))→ ¬

(C∧

(B∨ ¬(D∧A∧ E)

)), (1.2) {LG:A2}{LG:A2}

verwenden ¬w = f sowie B∧ f = f und fahren fort mit

f→ ¬(C∧

(B∨ ¬(D∧A∧ E)

)), (1.3){LG:A3}{LG:A3}

schließlich können wir aus f, also “falsch”, jede Aussage implizieren, also (f→ A)↔ w, somitist gezeigt, dass es sich bei (1.1) um eine Tautologie handelt.

16 ©2018 Thomas Richter

Page 23: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Teil I.

Diskrete Aspekte derAlgorithmischen Mathematik

17

Page 24: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude
Page 25: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2. Sortieren{chap:sortieren}

In diesemKapitel befassenwir unsmit dem Sortierproblem: gegeben sei eine Sequenza1, . . . ,an ∈M von n ∈ N Elementen einerMengeM. Die Aufgabe ist es, diese Elemente in eine bestimmteReihenfolge zu bringen. Hierzu werden wir zunächst den Begriff derOrdnung einführen, wel-ches die Reihenfolgemathematisch definiert. ImAnschluss untersuchenwir verschiedeneMe-thoden zum Sortieren von Sequenzen. Besondere Beachtung wird die Effizienz der Verfahrenfinden. Wie viele Schritte werden benötigt, um eine Sequenz mit n Elementen in die richtigeReihenfolge zu bringen? Und weiter, wie viele Speicher benötigt der Algorithmus, um dieseSortierung durchzuführen?

2.1. Ordnung und erstes Sortierverfahren{sec:ordnung}{def:ordnung}

Definition 2.1 (Ordnung). Es sei S eine Menge und R ⊂ S× S eine Relation mit den Eigenschaften

1. Reflexivität. Es ist (a,a) ∈ R für alle a ∈ S

2. Antisymmetrie. Falls (a,b) ∈ R und (b,a) ∈ R dann gilt zwingend a = b

3. Transitivität. Falls (a,b) ∈ R und (b, c) ∈ R dann gilt (a, c) ∈ R

heißt partielle Ordnung. Alternativ zu (a,b) ∈ R schreiben wir a � b.

Falls zusätzlich gilt (a,b) ∈ R oder (b,a) ∈ R für alle a,b ∈ S, dann heißt R eine totale Ordnung.Wir schreiben dann a 6 b.

Beispiel 2.2 (Ordnungen).

• Es seiR = N,R = Z,R = Q oderR = R. Dannwerden6 sowie durch> jeweils totaleOrdnungengegeben.

• Es sei R = N,R = Z,R = Q oder R = R. Dann werden < sowie durch > keine Ordnungengegeben, denn die Reflexivität ist verletzt.

• Es sei R = N,R = Z,R = Q oder R = R. Dann ist durch = eine partielle Ordnung gegeben.Dies ist etwas verwunderlich (und auch keine praktisch sinnvolle Ordnung), aber die Gesetze sindalle erfüllt. Diese Ordnung ist jedoch keine totale Ordnung, da z.B. weder 3 = 5 noch 5 = 3gilt.

• Es sei R die Menge aus Obstkörben, in denen jeweils entweder jeweils Birnen oder Äpfel liegen.Für zwei Körbe K1,K2 ∈ R definieren wir die partielle Ordnung

K1 � K2 ⇔

K1 und K2 Apfelkörbe und es gilt: Anzahl in K1 6 Anzahl in K2

K1 und K2 Birnenkörbe und es gilt: Anzahl in K1 6 Anzahl in K2

19

Page 26: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.1. Ordnung und erstes Sortierverfahren

Ein Korb K1 ist also kleiner als ein Korb K2, wenn in beiden Körben entweder nur Äpfel odernur Birnen sind und wenn in K1 dann weniger (oder gleich viele) Früchte sind wie in K2. Apfelund Birnen können wir nicht vergleichen, daher ist dies keine totale Ordnung

• Es sei R = C. Wir führen die lexikographische Ordnung ein

a,b ∈ C : a 6 b ⇔ (Re(a) < Re(b)) ∨((Re(a) = Re(b)) ∧ (Im(a) 6 Im(b))

).

Eine komplexe Zahl a ∈ C ist also auf jeden Fall kleiner als b ∈ C, wenn ihr Realteil kleiner ist.Sind Realteile gleich, dann entscheidet der Imaginärteil. Dies ist eine totale Ordnung.

• Der Name lexikographische Ordnung kommt daher, da sich diese Ordnung leicht auf Spracheübertragen lässt. Es sei nun S eine Menge von Wörtern. Es seien u,w ∈ S zwei Wörter mit nuund nw Buchstaben. Es ist durch

u 6 w ⇔(es gibt ein i 6 min(nu,nw) u1 = w1, . . . ,ui−1 = wi−1 ∧ ui < wi

)∨((nu 6 nw)∧ (ui = wi für alle i = 1, . . . ,nu)

), (2.1)

wobei wir mit ui und wi den i-ten Buchstaben meinen und auf der Menge der Buchstaben dieübliche Ordnung vorgegeben sei. Es gilt also z.B.

Baum 6 Haus, Baum 6 Baumhaus, Baum 66 Baustelle, Baumhaus 66 Baum{def:sortallgemein}

Definition 2.3 (Allgemeines Sortierproblem). Gegeben sei eine MengeM mit n ∈ N Elementenund partieller Ordnung �. Gesucht ist eine Bijektion

f : {1, . . . ,n}→M

mit(f(j) 6= f(i))→ (f(j) 6� f(i)) ∀i, j : 1 6 i < j 6 n.

Das allgemeine Sortierproblem ist als Widerspruch formuliert: Falls das Element i vor demElement j steht und falls die Elemente verschieden sind, dann darf das j-te Element nicht vordem i-ten in bzgl. der Ordnung stehen. Bezogen auf die Apfel/Birnen-Ordnung bedeutet dies,dass die Sequenz

(3 Birnen), (22 Äpfel), (8 Birnen), (14 Birnen), (41 Äpfel)

sortiert ist, ebenso wie die Sequenz

(3 Birnen), (8 Birnen), (14 Birnen), (22 Äpfel), (41 Äpfel),

nicht aber die Sequenz

(3 Birnen), (41 Äpfel), (8 Birnen), (14 Birnen), (22 Äpfel).

Denn 2-tes und 5-tes Element stehen bezogen auf die Ordnung falsch zueinander. Über Ele-mente, die nicht in Relation stehen, also Birnen und Äpfel, gibt das Sortierproblem keine An-gaben an die Reihenfolge.

Wir betrachten hierzu den folgenden Algorithmus, Sortieren durch Auswahl, im englischen se-lection sort

20 ©2018 Thomas Richter

Page 27: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.1. Ordnung und erstes Sortierverfahren

{algo:selection}Algorithmus 2.1: Selection SortGegeben Liste L sowie eine (partielle) Ordnung

1 def selection_sort(L):

2 n = len(L)

3 for i in range(n):

4 for j in range(i+1,n):

5 if L[j] � L[i]:

6 L[i],L[j] = L[j],L[i]

{satz:selection}

Satz 2.4 (Sortiereigenschaft von Selection Sort). Algorithmus 2.1 liefert im Ergebnis die eine sor-tierte Liste gemäß Definition 2.3.

Beweis. (i) Wir weisen die Sortiereigenschaft mit vollständiger Induktion nach. Im Zustand(i, j) - damit meinen wir die Einträge von L nach eventuellem Tausch in Zeile 5 für gegebeneWerte der Laufvariablen 0 6 i < n und i 6 j < n - gilt stets

(I) L[k] = L[h] ∨ L[k] 6� L[h] ∀h,k : 0 6 h < i und h < k < n(II) L[k] = L[i] ∨ L[k] 6� L[i] ∀k : i < k 6 j.

Angenommen, wir können beide Eigenschaften für alle 0 6 i 6 j < n nachweisen, so istEigenschaft b) gerade die definierende Eigenschaft aus Definition 2.3.

(ii) Wir prüfen (i, j) = (0, 0). Beide Bedingungen sind leer, denn es gibt keine h,k ∈ N mit0 6 h,k < i = 0. Damit sind (I) und (II) in diesem Fall erfüllt.

(iii) Angenommen, die Bedingung gilt für ein (i, j). Wir zeigen den Schritt (i, j) 7→ (i, j + 1).In diesem Schritt werden eventuell die Einträge L[j+ 1] und L[i] getauscht. Auf jedem Fall giltnach diesem Schritt

L[j+ 1] = L[i] ∨ L[j+ 1] 6� L[i].

Bedingung (I) hängt nicht direkt von j ab. Weiter setzt diese Beziehung Elemente h < i mitallen Elementen k > h in Bezug. Der eventuelle Tausch von L[i] und L[j+1] ändert die Bijektionnicht für h < i. Daher gilt diese Bedingung weiter.

Bedingung (II) hängt unmittelbar von j ab. Wir untersuchen zwei Fälle:

Fall 1:Angenommen, vor Schritt 5war L[j+1] 6� L[i]. D.h., es ist kein Tausch notwendig. Danngilt

L[k] = L[i] ∨ L[k] 6� L[i] ∀i < k 6 j

nach Induktion für (i, j) undL[j+ 1] 6� L[i],

da wir gerade diesen Fall vorausgesetzt haben. D.h., (i, j)→ (i, j+ 1) gilt.

Fall 2:Angenommen, vor Schritt 5war L[j+ 1] � L[i]. Dann tauschen wir L[j+ 1] und L[i]. Wiruntersuchen zwei Teilfälle:

[email protected] 21

Page 28: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.1. Ordnung und erstes Sortierverfahren

Fall 2a: Es sei k = j+ 1. Es gilt nach Schritt 5

L[k] = L[j+ 1] = L[i]alt,

wobei wir mit L[i]alt den Zustand vor Schritt 5 meinen. Also gilt L[i] = L[j + 1]alt � L[i]alt =L[j + 1] = L[k]. Wegen der Antisymmetrie folgt nun entweder L[k] = L[i], oder aber, wennL[k] 6= L[i] dann ist L[k]not � L[i] (es können für verschiedene Elemente nicht gleichzeitigL[k] � L[i] gelten).

Fall 2b: Es sei nun i < k < j+ 1. Aus der Induktionsannahme und mit Antisymmetrie gilt

L[k] = L[i] ∨ L[k] 6� L[i]alt 6� L[j+ 1]alt = L[i].

(Hätten wir eine totale Ordnung, so wäre dies im Fall L[k] 6= L[i] äquivalent zu L[k] > L[i]alt >L[i], also L[k] > L[i], somit L[k] 66 L[i].Wir haben aber nur eine partielleOrdnungundbrauchenein weiteres Argument). Angenommen es wäre

L[k] � L[i] = L[j+ 1]alt � L[i]alt.

Dann folgt mit der Transitivität auch L[k] � L[i]alt im Widerspruch zur Induktionsannahme(II) (da ja k 6 j < j+ 1). Somit L[k] 6� L[i] im Fall L[k] 6= L[i].

(iv)Mit demVorangegangenen haben wir (i, j) für alle 0 6 j < n gefolgert. Es fehlt der Schluss(i,n) 7→ (i + 1, i + 1). Die Reihenfolge ändert sich in diesem Schritt nicht. Bedingung (II) istleer. Der Index i in Bedingung (I) ist um eins größer, d.h. nun ist auch h = i zugelassen undwir müssen für diesen Fall zeigen, dass

L[k] 6= L[i] ∨ L[k] 6� L[h] = L[i] ∀i < k 6= n.

Diese Bedingung ist aber exakt Bedingung (I) zum Index (i,n), d.h. bereits gezeigt.{bem:mutable}

Bemerkung 2.5 (Call byReference, call byValue). Die Funktion SelectionSort ausAlgorithmus 2.1liefert keinen Rückgabewert per return-Anweisung. Dennoch erfüllt die Funktion, z.B. im Sinne von

1 L=[3,1,5]

2 selection_sort(L)

3 print(L)

ihre Aufgabe und ändert die Reihenfolge der Element in L. In der Programmierung unterscheidet manzwischen zwei verschiedenen Varianten bei der Übergabe von Parametern. Wir betrachten das folgendekurze Programm

1 def tuwas(z):

2 z = z+1

3

4 x=5

5 print(x)

6 tuwas(x)

7 print(x)

22 ©2018 Thomas Richter

Page 29: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.1. Ordnung und erstes Sortierverfahren

Was passiert? x erhält den Wert 5, wird ausgegeben an die Funktion tuwas übergeben. Dort erhält x denNamen z, dieses z wird um eins erhört. Im Anschluss hat x immer noch den Wert 5. Wir nennen diesesVerhalten Call by Value, d.h. der Wert der Variable x wird übergeben, innerhalb der Funktion tuwaswird jedoch eine neue Variable z angelegt und der Wert von x wird bei der Übergabe in z kopiert.

Ein zweites ähnliche Beispiel

1 def tunochwas(S):

2 S[0],S[1] = S[1],S[0]

3

4 L=[1,2]

5 print(L)

6 tunochwas(L)

7 print(L)

Jetzt legen wir eine Liste L an, diese wird an die Funktion tunochwas übergeben. Dort heißt die Variablenun S und in S werden erstes und 2tes Element vertauscht. Erstaunlicherweise wird nun zunächst dieursprüngliche Reihenfolge 1, 2 im Anschluss die vertauschte Reihenfolge 2, 1 ausgegeben. Hier scheintdie Variable S in der Funktion tunochwas das gleiche Objekt zu behandeln wie die Variable L. Wir nen-nen dieses Verhalten Call by Reference. Übergeben wird nicht der Wert der Variable, sondern eineReferenz auf diese Variable (wir können uns einfach die Speicherstelle vorstellen). Die Variable erhältnur einen neuen Namen.

Ein drittes Beispiel, leicht abgewandelt:

1 def tunochwas(S):

2 S = [S[1],S[0]]

3

4 L=[1,2]

5 print(L)

6 tunochwas(L)

7 print(L)

Wir haben nur die Art geändert, wie wir die Reihenfolge ändern. Jetzt scheint das Prinzip Call byReference nicht mehr zu gelten. Denn vor und nach dem Funktionsaufruf wir die alte Reihenfolgeausgegeben. Was geht schief? Nichts, es wird wieder per Call by Reference nur eine Referenz auf Lübergeben und nun S genannt. Aber in Zeile 2 des Programm wird nun eine neue Liste - wieder mitdem Namen S - erzeugt. Dieses Objekt hat nichts mehr mit der Liste L zu tun, die unter dem Namen Sübergeben wurde.

In Python liegt es am Typ der Variable, wie die Übergabe erfolgt. Für uns reicht im Moment: Listenwerden als Referenz übergeben, einfache Zahlen per Wert. Falls wir eine Funktion nutzen wollen umeine Variable zu ändern, so sind wir immer auf der sicheren Seite, wenn wir die return-Anweisungverwenden um ein Ergebnis zurückzugeben, also z.B.:

1 def tunochwas(S):

2 S = [S[1],S[0]]

3 return S

4

5 L=[1,2]

[email protected] 23

Page 30: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.1. Ordnung und erstes Sortierverfahren

6 print(L)

7 L = tunochwas(L)

8 print(L)

In diesem Fall wird bei der Zuweisung in Zeile 7 immer eine Kopie der Variable erstellt. Es gibt abergute Gründe, das ModellCall by Reference einzusetzen, z.B. wenn wir mit sehr großen Datenmengenhantieren. Die Liste kann ja viele Millionen Einträge haben, diese zu kopieren, nur weil wir 2 Elementetauschen kann sehr ineffizient sein.

In Python werden Datentypen entweder immutable (unveränderlich) odermutable (veränderlich) ge-nannt. immutable-Typen, wie Zahlen oder Strings, können nie ihre Wert ändern. Die Anweisung x↪→ = x+1 ändert die Variable x nicht sondern erstellt eine neue Variable und nennt diese wieder x.immutable-Typen werden per Call by Value übergeben. mutable-Typen hingegen sind veränderlichund werden per Call by Reference übergeben.Bemerkung 2.6 (Zufallszahlen in Python). Um Testlisten für Sortierverfahren zu erstellen ist espraktisch, Zufallszahlen zu wählen. In Python gibt es hierfür verschiedene Befehle. Diese Befehle sindjedoch nicht Teil der Python-Grundbefehle, sondern müssen zunächst im Programm importiertwerdenmittels

1 import random

Im Anschluss stehen verschiedene Befehle zur Verfügung:1 import random

2

3 x = random.randint(−5,2) # liefert eine zufällige ganze Zahl

4 # zwischen a und b (jeweils inkl.)

5

6 f = random.random() # liefert eine zufällige Fliesskommazahl

7 # zwischen 0 und 1

8

9 L = [1,2,’Haus’,4,−5,6]10 e = random.choice(L) # liefert ein zufaelliges Element aus L

Bemerkung 2.7 (Zeitmessung). Wir wollen oft Zeiten messen, umAlgorithmen auf Effizienz zu prü-fen. Python hält hierfür praktische Funktionen in der Bibliothek time bereit. Einbinden der Funktionenper

1 import time

Wir benötigen zunächst aus dieser Bibliothek nur die Funktion time.clock(), welche die aktuelle Zeit(in Sekunden) als Fließkommazahl zurück gibt. Die in einer Funktion, z.B. selection_sort verbrachteZeit kann mittels zweier Aufrufe von clock ermittelt werden:

1 ...

2 t1 = time.clock()

3 selection_sort(L)

4 t2 = time.clock()

5 print(’Es sind ’,t2−t1,’ Sekunden vergangen’)6 ...

24 ©2018 Thomas Richter

Page 31: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.2. Laufzeit

time.clock() liefert die sogenannte CPU-Zeit. Das ist die Zeit, die der Prozessor mit dem Programmbeschäftigt ist. Diese Zeit kann von der in Realität verstrichenen Zeit abweichen, z.B. wenn der Com-puter gleichzeitig mit anderen Programmen beschäftigt ist. Man unterscheidet zwischen derwall time,welche die Zeit ist, die in Realität vergeht und der cpu time, welche die Zeit angibt, die er Prozessorzur Ausführung der Anweisungen benötigt.

2.2. Laufzeit

Selection Sort ist eines der wenigen Sortierverfahren, welches nur eine partielle Ordnung be-nötigt. Das Problem einer partiellen Ordnung ist, dass es Elemente a,b ∈M geben kann, dieüberhaupt nicht in Ordnung zueinander stehen müssen, d.h. a 6� b und b 6� a. Um zu ent-scheiden, an welcher Stelle ein Element a steht, muss es mit allen anderen Elementen einzelnverglichen werden. {satz:aufwandpartiell}

Satz 2.8 (Aufwand des allgemeinen Sortierproblems). Es seiM eine Menge mit n Elementen und� eine partielle Ordnung. Im ungünstigsten Fall benötigt das allgemeine Sortierproblem mindestens

n2 − n

2

Vergleiche.

Beweis. Jeder Algorithmus zum Sortieren muss sicherstellen, dass die Ordnung gegeben ist,vergleiche Definition 2.3, d.h. ob

f(j) 6� f(i) ∀i, j : 1 6 i < j 6 n.

Wir betrachten eineMengeMmitn Elementen, von denen eventuell keine zwei verschiedenenzueinander in Ordnung stehen, d.h.

∀x,y ∈Mmit x 6= y gilt (x 6� y)∧ (y 6� x).

Hieraus folgern wir, dass keinerlei Transitivität innerhalb der Menge gelten kann, die unterUmständendie Sortierung erleichtern vereinfachenwürde.Umzu entscheiden, ob ein Elementan Stelle i falsch steht, testen wir, ob es eine Element an Stelle j > i gibt mit xj � xi. Das ersteElement erfordert somit n − 1 Vergleiche, das zweite n − 2, usw. Insgesamt ergibt sich derAufwand als (gerechnet in der Anzahl an Vergleichen)

(n− 1) + (n− 2) + · · ·+ 1 =n(n− 1)

2=n2 − n

2.

Der mögliche Ausschluss einer Verwendung der Transitivität ist wichtig. Denn Angenommenes läge eine totale Ordnung6 vor. Dann gilt für alle x,y ∈M entweder x 6 y oder y 6 x (odernatürlich x = y). Ein Test auf Sortiertheit kann hier viel einfacher durchgeführt werden:

[email protected] 25

Page 32: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.2. Laufzeit

Algorithmus 2.2: Test auf Sortiertheit (totale Ordnung)Gegeben Liste Lmit n Elementen und totaler Ordnung 6

1 def test_sortiert(L):

2 n = len(L)

3 for i in range(n−1):4 if not(L[i] <= L[i+1]):

5 return False

6 return True

Dieser Algorithmus benötigt nur n − 1 Vergleiche. Denn durch die totale Ordnung und dieTransitivität folgt aus L[i] <= L[i+1] für alle 0 6 i < n − 1 auch L[i] <= L[j] für alle 0 6 i 6j < n. Und da die Ordnung total ist, ist L[i] 6 L[j] äquivalent zu L[i] = L[j] oder L[j] 66 L[i], d.h.genau die Bedingung an das allgemeine Sortierproblem in Definition 2.3. Dieser Algorithmusbesagt natürlich noch nicht, dass wir das Sortierproblem bei totaler Ordnung in weniger alsn2−nVergleichen durchführen können.Wir werden aber in Abschnitt 2.3 in der Tat Verfahrenkennenlernen, die das Problem sehr viel schneller lösen. Der Grundwird stets die Transitivitätsein sowie dasWissen, dass für zwei beliebige Elementea,b ∈M immera 6 b oder aberb 6 agilt.

Wir untersuchen im folgenden den Aufwand von Algorithmen. Hierzu definieren wir:

Definition 2.9 (Aufwand, Komplexität). Es sei ein Algorithmus gegeben, welcher eine Eingabe derGröße n ∈ N eine Ausgabe zuordnet. Mit dem Aufwand oder der Komplexität

A(n) ∈ N

bezeichnen wir die Anzahl von Operationen, die der Algorithmus zur Ausführung benötigt.

Bemerkung 2.10 (Operationen und Aufwand). Eine klare Definition des Begriffs Aufwand istschwierig und hängt von den genauen Umständen ab. Die Addition zweier Zahlen z = x+ y benötigteine Operation (die Addition) hat also Aufwand 1. Die Addition von n Zahlen

y =

n∑i=1

xi

benötigt n − 1 Additionen und hat damit den Aufwand n − 1. Wie sieht es aber aus mit der Additionvon zwei sehr langen Zahlen mit vielen tausend Stellen? Falls wir einen Computer haben, der zweiZahlen unabhängig von der ihrer Länge in einem Schritt addieren kann, so ist der Aufwand weiterhineins. Allgemein wird dies jedoch nicht so sein und der Aufwand steigt mit der Länge der Zahlen. ImAllgemeinen werden wir hier davon ausgehen, dass die Grundoperationen (z.B. Addition, Multiplikati-on, Vergleich zweier Werte, Tauschen von Zahlen, ...) alle in der gleichen Zeit mit konstantem Aufwanddurchgeführt werden können.

Wir beginnen mit Selection Sort.

Satz 2.11 (Laufzeit von Selection Sort). Algorithmus 2.1 hat stets die Laufzeit

n2 − n

2.

26 ©2018 Thomas Richter

Page 33: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.2. Laufzeit

Beweis. Die Laufzeit kann einfach abgelesen werden.

Selection Sort ist also im Sinne von Satz 2.8 ein optimaler Algorithmus wenn wir nur einepartielle Ordnung zugrunde legen. Zur genaueren Kategorisierung des Aufwands betrachtenwir im folgenden zwei einfache Algorithmen

1 x=0

2 for i in range(n):

3 for j in range(i,n):

4 x = x+j

und

1 x=0

2 for i in range(n):

3 x = x+i

4 for j in range(i,n):

5 x = x+j

Wir bestimmen den jeweiligen Laufzeiten durch Abzählen der Iterationen:

A1(n) = 1 +

n∑i=1

n∑j=i

1 = 1 +

n∑i=1

(n− i+ 1)

= 1 + n2 −

n∑i=1

i+ n = 1 + n2 + n−n(n+ 1)

2=

1

2n2 +

1

2n+ 1

A2(n) = 1 +

n∑i=1

1 +

n∑j=i

1

= n+A1(n) =1

2n2 +

3

2n+ 1

Dabei haben wir Additionen sowie die Initialisierung, jeweils in Zeile 1, als eine Operationgezählt. Der Aufwand von Algorithmus 2 ist höher. Es gilt:

n 10 100 1 000 10 000

A1(n) 56 5 051 500 501 50 005 001A2(n) 66 5 151 501 501 50 015 001

A2(n) −A1(n) 10 100 1 000 10 000(A2(n) −A1(n))/A1(n) 15% 2% 0.2% 0.02%

Wir zeigen den Aufwand, die Differenz zwischen beiden Verfahren und die relative Differenz.Es gilt natürlich A2(n) − A1(n) = n, aber die relative Differenz sinkt mit der Problemgröße.Für großen ∈ N ist der Unterschied zwischen beiden Verfahren zu vernachlässigen.Wir inter-essieren uns daher insbesondere für den wesentlichen asymptotischen Aufwand. Wir definieren:

[email protected] 27

Page 34: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.2. Laufzeit

Definition 2.12 (Landau-Symbole). Es sei g(n) eine Funktion mit g → ∞ für n → ∞. Dann istf ∈ O(g) genau dann, wenn

lim supn→∞

∣∣∣∣ f(n)g(n)

∣∣∣∣ <∞Weiter ist f ∈ o(g) genau dann, wenn

limn→∞

∣∣∣∣ f(n)g(n)

∣∣∣∣ = 0.

Sei nun g(h) eine Funktion mit g(h)→ 0 für h→ 0. Dann ist f ∈ O(g) genau dann, wenn

lim suph→0

∣∣∣∣ f(h)g(h)

∣∣∣∣ <∞und f ∈ o(g) genau dann, wenn

limh→0

∣∣∣∣ f(h)g(h)

∣∣∣∣ = 0.

Die Landau-Symbole dienen dem Vergleich von Konvergenzgeschwindigkeiten. Für die bei-den Algorithmen oben gilt

A1(n) ∈ O(n2), A2(n) ∈ O(n2).

Oft schreiben wir einfach

A1(n) = O(n2), A2(n) = O(n2).

Beide haben die gleiche asymptotische Komplexität, auch wenn die Laufzeit nicht identischist. Daher ist die Notation mit “=” nicht optimal, wir erwarten Transitivität, dies gilt jedochnicht!

Ein paar weitere Beispiele zum nachrechnen (jeweils n→∞ und h→ 0)

log(n) = o(n)sin(h) = O(h)

sin(n) = O(1)

h2 + h = O(h)

n2 + n = O(n2)√n = o(n)

Oftmöchtemandie führendeKonstante bei der Bestimmungder Laufzeit angeben.Das Landau-Symbol wird dann für den zweiten Term verwendet, d.h. für alle Terme, die wir vernachlässi-gen wollen. Für die beiden obigen Algorithmen gilt dann jeweils

A1(n) =n2

2+ O(n), A2(n) =

n2

2+ O(n).

Auch Selection Sort hat den Aufwand O(n2).

28 ©2018 Thomas Richter

Page 35: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.2. Laufzeit

Laufzeiten, best-case, worst-case, average-case Viele Algorithmen haben einezufällige Komponente. Wir betrachten das folgende Beispiel

Algorithmus 2.3: Sequentielle SucheGegeben sei eine Liste L=[s1,...,sn] mit n ∈ N Einträgen. Gesucht ist die Position eines ihrerEinträge l.

1 for i in range(n):

2 if L[i] == l:

3 return i

4 return −1

Es gilt:

Satz 2.13 (Aufwand der sequentiellen Suche). Wir gehen davon aus, dass die Einträge li der Listepaarweise verschieden sind und dass das gesuchte Element l Teil der Liste ist. Die best-case Komple-xität des Verfahrens ist

Abest(n) = 1

die worst-case Komplexität des Verfahrens ist

Aworst(n) = n

die average-case Komplexität des Verfahrens im Falle eine Gleichverteilung ist

Aavg(n) =n+ 1

2.

Beweis. Die ersten beiden Fälle ergeben sich bei l1 = l, bzw. bei ln = l. Wir gehen nun davonaus, dass sich das Element l an beliebiger Stelle befindet und zwar mit gleicher Wahrschein-lichkeit an jeder der n Stellen, jeweils 1/n. Falls sich l an Stelle i befindet, so ist die LaufzeitAi(n) = i. Hierdurch ergibt sich:

Aavg(n) =1

n

n∑i=1

i =n(n+ 1)

2n=n+ 1

2.

Wir betrachten nun Sortieren durch Einfügen{algo:insertion}

Algorithmus 2.4: Insertion SortGegeben eine Liste Lmit n Elementen und eine (partielle) Ordnung �.

1 def insertion_sort(L):

2 for i in range(n):

3 j=i

4 while (j>0) and not(L[j−1] � L[j]):

5 L[j−1],L[j] = L[j],L[j−1]6 j = j−1

[email protected] 29

Page 36: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

Im Gegensatz zu Selection Sort hängt bei Insertion Sort die Laufzeit von der Eingabe ab. Fallsdie Ordnung alle Elemente erfasst und die Daten bereits sortiert sind, d.h. L[j−1]�L[j], sobricht die while-Schleife immer sofort bei j = i ab. Zeilen 5 und 6 werden nie ausgeführt undinsgesamt sind nur n − 1 Vergleiche notwendig. Dies ist kein Widerspruch zur Aussage vonSatz 2.8, denn dieser sagt etwas über den ungünstigsten Fall aus.

Die best-case Laufzeit istO(n). Imworst-case sind dieDaten gegenläufig sortiert. Es kann gezeigtwerden, dass dies auch im Laufe des Verfahrens so bestehen bleibt. Damit ergibt sich eineworst-case Laufzeit von O(n2). Es kann in aufwändiger Analyse auch gezeigt werden, dass dieaverage-case Laufzeit O(n2) ist.

2.3. Sortieren bei totaler Ordnung{sec:sorttotal}

Wir gehen im Folgenden davon aus, dass eine totale Ordnung6 auf derMengeM gegeben ist.Für je zwei Elemente gilt also entweder a 6 b oder b 6 a. Gelten beide Bedingungen, so ista = b. Bei Analyse einer partiellen Ordnungmussten wir oft mit der Negation, also f(i) 6� f(j)arbeiten. Dies bedeutet nicht gleichzeitig f(j) � f(i). Im Fall einer totalen Ordnung ist dieseinfacher. Aus f(i) 66 f(j) folgt f(j) 6 f(i). Wir definieren die Negation

f(i) 66 f(j) ⇔: f(i) > f(j).

Wir betrachten noch einmal Selection Sort aus Algorithmus 2.1. In Zeilen 4-5 werden die Ele-mentemit Indizes i und j getauscht, falls L[j] <= L[i] gilt. Hiermit wird - im Sinne vom Beweiszu Satz 2.4 - erreicht, dass nach dieser Schleife gilt:

L[k] 6= L[h] ∨ L[k] 6� L[h] ∀0 6 h < i und h < k < n.

Bei einer totalen Ordnung liest sich diese Bedingung einfacher schreiben

L[h] 6 L[k] ∀0 6 h < i und h < k < n.

Wollen wir diese Bedingung induktiv von i auf i+1 übertragen, so müssen wir nur den neuenIndex h = i überprüfen, also ob

L[i ] 6 L[k] ∀i < k < n

gilt, denn alle Indizes 0, . . . , i−1 bleiben in L unverändert.Wir können den Selection-Sort leichtmodifizieren:{algo:selectiontotal}Algorithmus 2.5: Min-Sort; Selection Sort bei totaler OrdnungGegeben Liste L und totale Ordnung

1 def selection_sort_total(L):

2 n = len(L)

3 for i in range(n):

4 m = i

5 for j in range(i+1,n):

6 if L[j] <= L[m]:

7 m = j

8 L[i],L[m] = L[m], L[i]

30 ©2018 Thomas Richter

Page 37: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

In Zeilen 4-7 des Verfahrens wird derjenige Indexmmit i 6 m < n gesucht, dessen Elementminimal ist. Anschließend wird dieses minimale Element mit Index i vertauscht. Dieser Algo-rithmus ist effizienter, da anstelle von O(n2) Tauschvorgängen nur O(n) Elemente getauschtwerden müssen. Nach wie vor sind jedoch O(n2) Vergleiche notwendig.

Diese Vereinfachung ist bei einer partiellen Ordnung nicht möglich. Hier existiert nicht unbe-dingt ein kleinstes Element, da überhaupt nicht alle Elemente miteinander in Relation stehen.Auch der Beweis lässt sich bei einer totalen Ordnung leichter durchführen.

Satz 2.14 (Selection Sort bei totaler Ordnung). Algorithmus 2.5 löst das Sortierproblem bei totalerOrdnung.

Beweis. Wir zeigen induktiv, dass nach Schritt i gilt:

L[h] 6 min{L[h+1], L[h+2], . . . , L[n−1]} ∀0 6 h 6 i. (2.2) {selectiontotal:1}{selectiontotal:1}

Nach Schritt i = n− 1 ist dann das Sortierproblem gelöst, denn dies impliziert insbesondere

L[h] 6 L[h+1] ∀0 6 h < n− 1.

(i) Aus der Transitivität folgt, dass die Zeilen 4-7 einen Indexm ∈ {i, . . . ,n} bestimmen mit

L[m] = min{L[i ], . . . , L[n−1]},

also L[m]6L[j] für alle j = i, . . . ,n − 1. Denn durch jeden möglichen Tausch m 7→ m ′ 7→ m ′′

bleibt stets L[m ′′]6 L[m ′]6 L[m] erhalten.

(ii) Wir zeigen nun mit Induktion die Bedingung (2.2). Zunächst sei i = 0. Die Bedingung istleer, also korrekt.

(iii) i 7→ i + 1. In diesem Schritt ändert sich höchstens das Element L[i+1] und wird gegebe-nenfalls mit einem L[m] für i+ 1 6 m < n getauscht. D.h., nach Induktionsvoraussetzung giltBedingung (2.2) für alle Indizes 0 6 h 6 i. Es bleibt zu zeigen, dass nach diesem Schritt auch

L[i+1] 6 min{L[i+2], . . . , L[n−1]}

gilt. Der neue Index i + 1, also der alte Indexm wurde jedoch gerade also das Minimum derMenge

L[m] = min{L[i+1], . . . , L[n−1]}

bestimmt. Somit ist die Bedingung gezeigt.

Wir kommen nun mit Bucket-Sort kurz zu einem Sortierverfahren welches einem komplettanderen Prinzip folgt und unter Umständen weit schneller ist als die lineare Laufzeit O(n).

Definition 2.15 (Induzierte Ordnung). Es seienM,N eine Mengen. Die MengeN sei mit der (tota-len) Ordnung6 versehen. Weiter sei k :M→ N eine Bijektion. Dann nennen wir aufM die Ordnung6 ′ gegeben durch

a 6 ′ b ⇔ k(a) 6 k(b)

eine von N induzierte Ordnung.

[email protected] 31

Page 38: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

{Bucket-Sort}

Satz 2.16 (Bucket Sort). Es sei L eine Liste mit n Einträgen einer Menge M, N eine Menge mite Elementen und 6 auf L die von N mittels k : M → N induzierte Ordnung. Dann das folgendeVerfahren, Bucket-Sort genannt, lineare Laufzeit O(n+ e):

1. Stelle e “Eimer” E1, . . . ,Ee auf

2. Laufe über alle n Elemente der Liste L und füge jedes Elemente x ∈ M in den entsprechendenEimer Ek(x) ein

3. Laufe über alle e Eimer in korrekter Sortierung und hänge die Ergebnisse aneinander.

Jeder Eintrag x1, . . . , xn der Liste Lwird in den “Eimer” mit Index k(xi) gelegt. Dies geschiehtin O(n) Operationen. Im Anschluss werden in O(e) Operationen die Elemente der Eimer zueiner sortierten Liste zusammengefügt. Im Fall e = O(n) ist dieses Verfahren linear und somitoptimal. Denn ein Sortieralgorithmus kann nicht schneller als linear sein, da ja jedes Elementmindestens einmal angesehen werden muss, um die Sortierung sicher zu stellen. Im Gegen-satz zu den oben angesprochenen einfachen Verfahren hat Bucket Sort den Nachteil, dass esnicht ohne erheblichen Speicheraufwand auskommt. Es müssen e Listen - also die “Eimer” -vorgehalten werden und in jedem dieser Eimer können maximal n Elemente stehen (falls alleEinträge der Liste L gleich sind). Das Verfahren hat die Laufzeit O(n+ e) und auch den Spei-cheraufwandO(n+e). Fallsn� e, so istBucket Sort in dieserArt nicht sinnvoll durchzuführen.Angenommen n Zahlen einer Menge vom Typ unsigned int, (ein übliches Zahlenformat mit 32Bits, d.h. 32 Stellen

M = {0, 1, . . . , 232 − 1} = {0, 1, . . . , 4 294 967 295}

Dann müssen stets e = 4 294 967 295 “Eimer” vorgehalten werden und die Laufzeit beträgt

Abucket(n) = 4 294 967 295 + n.

Für n = 1 000 ist der quadratische Aufwand von selection sort klar vorzuziehen (es werdennur 0.01% der Operationen von Bucket Sort benötigt). Hinzu kommt hier natürlich viel zu ho-he Speicheraufwand. In abgewandelter Form hat Bucket Sort jedoch einen hohen praktischenNutzen. Es werden nicht e “Eimer” verwendet, sondern eine kleine Zahl e ′ � n. Die Auf-teilung in die “Eimer” sorgt für eine Vorsortierung. Die Elemente werden möglichst gut aufe ′ Teillisten verteilt und diese können dann - als kleinere Probleme - effizient sortiert werden.Die Schwierigkeit besteht in einer gutenAufteilung der Daten auf die “Eimer”.Wenn amEndefast die ganze Liste in der gleichen Teilliste landet, kann das Verfahren nicht effizient sein.

Das Prinzip, die Eingabe aufzuteilen und getrennt voneinander zu bearbeiten wirdDivide andConquer (teile und herrsche) genannt. Auf diesem Prinzip basieren zwei weitere wichtige Sor-tierverfahren, Merge Sort und Quicksort.

32 ©2018 Thomas Richter

Page 39: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

2.3.1. Merge Sort{sec:mergesort}

Merge Sortwurde von John von Neumann1 eingeführt. Die grundlegende Idee vonMerge Sortist es, dass jeweils zwei sortierte Listen L und Rmit nl und nr Elementen, d.h. mit

1 6 i < nl : L[i−1] <= L[i]

1 6 i < nr : R[i−1] <= R[i]

effizient zu einer sortierten Liste der Länge n = nl + nr zusammengesetzt werden können.{algo:zusammen}

Algorithmus 2.6: Zusammenfügen sortierter ListenGegeben, zwei sortierte Listen L,R

1 def merge(L,R):

2 S = [] # Ergebnisliste

3 il = 0 # Laufvariablen in Listen L und R

4 ir = 0

5 # Beide Listen gleichzeitig durchlaufen bis ein Ende erreicht

6 while (il < len(L)) and (ir < len(R)):

7 if L[il] <= R[ir]:

8 S.append(L[il])

9 il = il + 1

10 else:

11 S.append(R[ir])

12 ir = ir + 1

13

14 # Jetzt ist eine Laufvariablen am Ende, es koennen beide angehaengt werden

15 for i in range(il,len(L)):

16 S.append(L[i])

17 for i in range(ir,len(R)):

18 S.append(R[i])

19 return S # Ergebnis zurueckgeben

Eswerden insgesamtnl+nr Schritte durchgeführt. Der gesamteMerge SortAlgorithmus ergibtsich nun aus einer Aufteilung der Liste S in kleine Teillisten und anschließendes Zusammen-fügen. Dabei nutzt man den einfachen Umstand, dass jede Liste der Länge 1 immer sortiertist. Das Verfahren kann rekursiv formuliert werden: {algo:merge}Algorithmus 2.7: Merge SortGegeben, Liste Lmit n ∈ N Elementen und totaler Ordnung 6

1 def merge_sort(L):

2 n = len(L)

3 if n <= 1: # leere Liste, 1er Liste immer sortiert

4 return L

5 m = int(n/2)

6 S1 = merge_sort(L[0:m]) # Rekursiver Aufruf linke Haelfte

7 S2 = merge_sort(L[m:n]) # Rekursiver Aufruf rechte Haelfte

1Ungarisch/US-Amerikanischer Mathematiker und Informatiker (wenn es damals schon Informatiker gab). Vonihm stammen etliche wichtige Beiträge in verschiedenen Bereichen der Mathematik.

[email protected] 33

Page 40: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

8 L = merge(S1,S2)

9 return L

Merge Sort hat zusätzlichen Speicheraufwand beim Kombinieren der beiden Listen.

Satz 2.17 (Aufwand vonMerge Sort). Merge Sort hat in jedem Fall den Aufwand O(n logn).

Beweis. Es sei T(n) der Aufwand für Algorithmus 2.7 bei einer Eingabe der Länge n. Hierfürgilt

T(n) = T(bn2c) + T(dn

2e) + n, (2.3){ms:1}{ms:1}

wobei b·c das Abrunden auf die nächstkleinere ganze Zahl bezeichnet und d·e das entspre-chende Aufrunden. Weiter bezeichnet der Summand n den Aufwand beim Zusammenfügen,die beiden anderen Terme den Aufwand im rekursiven Aufruf. Die Größe der Teilliste kannsich um eins unterscheiden. Falls n = 1 so ist der Aufwand T(1) = 1. Wir zeigen induktiv fürk ∈ N

T(2k) 6 (k+ 1)2k.

Für k = 0 also n = 1 ist T(1) = 1 6 1 · 20 = 1.

Die Behauptung sei für 2k−1 wahr. Dann gilt mit (2.3)

T(2k) 6 2 · T(2k−1) + 2kInd.6 2 · k · 2k−1 + 2k = (k+ 1)2k.

Nun gibt es ein minimales k0 ∈ Nmit 2k0−1 6 n 6 2k0 . Dann folgt

T(n) 6 T(2k0) = (k0 + 1)2k0 6 2(k0 + 1)n 6 2(2 + log2(n)

)n,

alsoT(n) = 2n log2(n) + 4n = O(n log(n)).

2.3.2. Quicksort{sec:quicksort}{Quicksort}

Mit Merge Sort haben wir eine Sortierverfahren analysiert, welches immer - also unabhängigvon dem Wert von n Elementen in einer Liste - den Aufwand 2n log2(n) also O(n log(n)) be-sitzt. Der Schlüssel für Merge Sort ist das hierarchische Aufteilen der Liste {s1, . . . , sn} in zweikleinere Listen und das anschließende Zusammenfügen von zwei kleineren sortierten Listenzu einer größeren. Aus diesem Aufbau resultiert die logarithmische Komponente in der Lauf-zeit. Ein Feld der Länge n lässt sich log2(n)mal in jeweils zwei (etwa) gleichgroße Teile zerle-gen.

Einweiteres Sortierverfahren, welches auf demPrinzipDivide and Conquer beruht istQuicksort.Ein Feld s1, . . . , snwird sukzessive in kleinere Felder aufgeteilt. Dabeiwird in jedemSchritt einPivot-Element p gewählt, z.B. p = s1. Das Feld wird dann so umgestellt, dass links vom Pivot-Element nur Elemente si 6 p stehen und rechts vom Pivot-Element nur Elemente sj > p.Das Pivot-Element stehe nach diesem Partitionierungsschritt an der Stelle ip ∈ {1, . . . ,n}. ImAnschlusswird das Feld in zwei Teile {1, . . . , ip}und {ip+1, . . . ,n}unterteilt unddasVerfahren

34 ©2018 Thomas Richter

Page 41: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

wird rekursiv auf beide Teile angewandt. Bei der Partitionierung kommt es prinzipiell nichtdarauf an, ob Elemente si = p links oder rechts eingeordnet werden. Bei der Wahl des Pivot-Elements sind wir frei. Einfache Verfahren verwenden entweder das erste oder letzte Elementder Liste.

Der Algorithmus besteht also aus zwei Teilen:{algo:quicksort}

Algorithmus 2.8: Quicksort Eingabe von Liste Lmit n ∈ N Elementen sowie zwei Indizes0 6 l, r < n

1 def quick_sort(L,l,r):

2 if not(l<r):

3 return # Beendet Funktion (ohne Rueckgabe)

4 j = partitioniere(L,l,r) # Partitionieren der Liste

5 quick_sort(L,l,j) # Sortiere links

6 quick_sort(L,j+1,r) # Sortiere rechts

{algo:partitioniere}Algorithmus 2.9: Partitioniere Eingabe einer Liste Lmit n ∈ N Elementen sowie von zweiIndizes 0 6 l < r < n

1 def partitioniere(L,l,r):

2 p = L[r] # Pivot−Element3 jl = l # linker Index

4 jr = r−1 # rechter Index neben Pivot

5

6 while True: # ’Endlos’−Schleife7 while (jl<r−1) and (L[jl]<p): # suche >= Pivot

8 jl = jl + 1

9

10 while (l<jr) and (L[jr]>=p): # suche < Pivot

11 jr = jr − 1

12 if (jl<jr): # Tausche, falls f

13 L[jl],L[jr] = L[jr],L[jl]

14

15 if not(jl<jr): # Ende der while−Schleife16 break

17

18 if (L[jl]>=p): # Falls linker index = Pivot, tauschen

19 L[jl],L[r] = L[r],L[jl]

20 return jl

21 else:

22 return jr

Die Funktionen arbeiten Beide auf dem Prinzip desCall by Reference und ändern stets die Liste,legen aber keine neue Liste an.

Diese Art der Partitionierung wird Hoare Schema genannt. Wir arbeiten mit zwei Indizes, diegegenläufig das Feld bearbeiten.

[email protected] 35

Page 42: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

Wir machen ein Beispiel. Es ist n = 7, d.h. die Liste hat die Elemente s0, . . . , s6. Das Pivot-Element ist jeweils markiert. Wir wählen wie in Algorithmus 2.9 jeweils das rechte Element.

s0 s1 s2 s3 s4 s5 s6

7 3 0 4 8 9 5

7 3 O 4 8 g J← Pirot

- Pos je nach socleI3 0 I 8 9 J

spogjenaohsudeI3 O I89 J

c - s Element getauodt

"4 3 I I89 5 = Indites meal sale

far je LEie3=7zp=5 ⇒ Tank

-4 3 O 5 8 g zD= je =3

Jett : 2 Listen

3 0 J 8 9 F Taels Assad soak

- - ohneteood .

- - Dealt ; Tausch je end

4 3 O 5 7 9 8 Pinot

I3 0

"'

£ 8 i¥I Sade olneteosdg

O 3 4 .

1

I89 jewels : Tausch

I je and Pirot

i ¥!, I

iIIE. Sade ohne

' I Teased .

O 3 4 5 7 89 → Fertig

36 ©2018 Thomas Richter

Page 43: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

Satz 2.18 (Laufzeit von Quicksort). Die worst-case Laufzeit von Quicksort zur Sortierung von nElementen beträgt

Tworst(n) =n2

2+ O(n)

Operationen. Die best-case Laufzeit von Quicksort zur Sortierung von n Elementen beträgt

Tbest(n) = 2n log2(n) + O(n)

Operationen.

Beweis. Zur Partitionierung von k = r− l+ 1 Elementen sind k− 1 Vergleiche notwendig. DieAnzahl der Tauschprozesse hängt von der Verteilung der Elemente ab. Wir notieren also

Tpart(k) = k− 1.

Der Aufwand von Quicksort zum Sortieren von k Elementen lässt sich rekursiv schreiben als

Tquick(k) = Tpart(k) + Tquick(k′) + Tquick(k− k

′),

wobei k ′ < k von dem Pivot-Element und der Verteilung der Elemente abhängt. Im ungüns-tigsten Fall gilt k ′ = 1 und es gilt:

Tquick(k) = Tpart(k) + Tquick(1) + Tquick(k− 1).

Wir setzen Tquick(1) = 1 und erhalten

Tquick(n) =

n∑k=1

Tpart(k) + n · Tquick(1) =n∑k=1

(k− 1) + n =n(n− 1)

2+ n =

n2

2+ O(n).

Im worst-case gilt für Quicksort quadratische Laufzeit.

Im optimalen Fall halbiert sich die Intervallgröße stets so dass

Tquick(k) = Tpart(k) + Tquick

(⌈k

2

⌉)+ Tquick

(⌊k

2

⌋)6 Tpart(k) + 2Tquick

(⌈k

2

⌉).

Wir wählen ein k0 ∈ Nmit2k0−1 6 n 6 2k0 .

Dann giltTquick(n) 6 Tquick(2

k0) 6 2k0 + 2Tquick(2k0−1). (2.4) {quick:1}{quick:1}

Wir zeigen induktivTquick(2

k0) 6 (k0 + 1)2k0

Für k0 = 0 ist die Aussage bei Tquick(20) = Tquick(1) = 1 klar. Nun gelte die Aussage also fürk0 − 1. Dann ist mit (2.4)

Tquick(2k0) 6 2k0 + 2Tquick(2

k0−1)ind6 2k0 + 2k02

k0−1 = (k0 + 1)2k0 .

Hieraus folgtTquick(n) 6 2(log2(n) + 2)n = 2n log2(n) +O(n).

[email protected] 37

Page 44: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

Wir zeigen für n = 10 000 und n = 20 000 die Laufzeiten für jeweils 5 000 verschiedene Zah-lenlisten.

0.0006

0.0008

0.001

0.0012

0.0014

0.0016

0 1000 2000 3000 4000 5000

Zei

t

Experiment

0.0015

0.002

0.0025

0.003

0.0035

0 1000 2000 3000 4000 5000

Zei

t

Experiment

Die Laufzeiten sind weit gestreut. Bei n = 10 000 ist die Häufung bei T ≈ 0.00077, bei n =20 000 liegt die Häufung bei T ≈ 0.0016. Es gilt:

0.00077

2 log2(10 000)10 000≈ 2.9 · 10−9,

0.00165

2 log2(20 000)20 000≈ 2.9 · 10−9.

Mit der Konstantec ≈ 2.9 · 10−9

zeigt sich für die “meisten” Experimente also die erwartete logarithmische Laufzeit.

Satz 2.19 (Durchschnittliche Laufzeit von Quicksort). Es seien s1, . . . , sn paarweise unterschied-liche Elemente. Angenommen, alle n! Permutationen der s1, . . . , sn sind gleich wahrscheinlich. Dannist die durchschnittliche Laufzeit

Tavg(n) ≈ 1.386n log2(n) + O(n).

38 ©2018 Thomas Richter

Page 45: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

Beweis. Wenn die alle Permutationen mit gleicher Wahrscheinlichkeit vorkommen, so ist dasPivot-Element k ′ ∈ {1, . . . ,k} zufällig und jede neue Partitionierung in {1, . . . ,k ′} und {k ′ +1, . . . ,k} tritt mit gleicher Wahrscheinlichkeit auf. Für Pivot-Element 1 6 k ′ 6 k gilt dann

Tquick(k) = Tpart(k) + Tquick(k′) + Tquick(k− k

′ − 1).

Da alle k ′mit gleicherWahrscheinlichkeit vorkommenberechnet sich die durchschnittliche Lauf-zeit eines Schritts als

Tquick(k) = k− 1 +1

k

k∑k ′=1

(Tquick(k

′) + Tquick(k− k′ − 1)

)Die beiden Teile der Summe können zusammengefasst werden

T(k) = k− 1 +2

k

k−1∑k ′=0

T(k ′) +1

kT(k),

wobei wir T(0) := 0 setzen. Zum Lösen dieser Gleichung multiplizieren wir beide Seiten mitk

kT(k) = k(k− 1) + 2

k−1∑k ′=0

T(k ′) + T(k).

Eine entsprechende Gleichung gilt für k− 1

kT(k) = k(k− 1) + 2

k−1∑k ′=0

T(k ′) + T(k)

(k− 1)T(k− 1) = (k− 1)(k− 2) + 2

k−2∑k ′=0

T(k ′) + T(k− 1)

Wir ziehen die Gleichungen voneinander ab und erhalten

kT(k) − (k− 1)T(k− 1) = 2(k− 1) + T(k− 1) + T(k)

also(k− 1)T(k) = kT(k− 1) + 2(k− 1) ⇒ T(k)

k=T(k− 1)

k− 1+

2

k.

Wir setzen Tk := T(k)/k und erhalten

Tk = Tk−1 +2

k= Tk−2 +

2

k+

2

k− 1= T1 + 2

k∑i=1

1

i

Bei der Summe handelt es sich um die Partialsumme der harmonischen Reihe. Für diese gilt∫k1

1

xdx 6

k∑i=1

1

i6 1 +

∫k1

1

xdx.

Das Integral lässt sich über den Logarithmus berechnen als

k∑i=1

1

i6 1 + ln(k).

[email protected] 39

Page 46: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.3. Sortieren bei totaler Ordnung

Hiermit erhalten wir die Abschätzung (bei T1 = 1)

Tk 6 1 + 2 ln(k).

Mit T(k) = kTk folgtT(k) 6 k(1 + 2 ln(k)).

Schließlich gilt ln(k) = log2(k) ln(2) ≈ 0.693 log2(k), also

T(k) 6 1.386k log2(k) + O(k).

Schließlich geben wir noch ein allgemeines Resultat bezüglich der Laufzeit von vergleichsba-sierten Sortierverfahren, d.h. von Verfahren, welche die Sortierung auf Basis direkter VergleicheL[i]<=L[j] herstellen. Mit Bucket-Sort haben wir bereits ein mögliches alternatives Verfahrenkennengelernt. Hier kommt statt Vergleich ein direktes Einsortieren in den richtigen Bucketzum Einsatz. Wir haben jedoch noch nicht gezeigt, wie sich so ein Einsortieren - ohne Ver-gleich - effizient implementieren lässt.

Satz 2.20 (Vergleichsbasierte Sortierverfahren). Es sei S = {s1, . . . , sn} eine Menge (paarweiseverschieden) von n Elementen mit totaler Ordnung 6. Jedes vergleichsbasierte Sortierverfahrenbenötigt im schlechtesten Fall

O(n log(n)

)Vergleiche.

Mit diesem Satz ist gemeint, dass ein optimales vergleichsbasiertes Verfahren im ungünstigs-ten Fall, d.h. bei schlechter Vorsortierung der Elemente si, immer O(n log(n)) Vergleiche be-nötigt. Für jedes Verfahren gibt es also mindestens eine Liste von Elementen {s1, . . . , sn} sodass diese Zahl von Vergleichen notwendig ist.

Beweis. (i) n verschiedene Elemente si können in n! Permutationen, also verschiedenen Rei-henfolgen auftreten. Denn, für die erste Stelle gibt es n Möglichkeiten, für die zweite Stellebleiben n− 1 Möglichkeiten, usw. Wir nennen P die Menge dieser Permutationen. Genau einedieser Permutationen liefert die sortierte Liste.

(ii) Ein Vergleich sa < sb teilt dieMenge der P Permutationen in zwei Teilmengen P = Pa∪Pb,diejenigen mit sa < sb und diejenigen mit sa > sb. Im ungünstigen Fall, bleibt die größereder beiden Mengen übrig. Selbst ein optimaler Algorithmus wird also mit jedem Vergleichhöchstens zu einer Halbierung der Menge der Permutationen führen.

(iii) Es istN0 := #P = n! die Anzahl der Permutationen zu Beginn. Im ungünstigstem Fall giltalso pro Schritt Ni = Ni−1/2, also

Ni = 2−in!

Eine eindeutige Reihenfolge steht somit nach

log2(n!)

40 ©2018 Thomas Richter

Page 47: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.4. Stabiles Sortieren

Schritten fest. Denn dann gilt

2− log2(n!)n! =1

2log2(n!)n! =

n!

n!= 1,

sodass die verbleibende Teilmenge nur noch ein (somit sortiertes) Element hat.

(iv) Es giltlog2(n!) 6 n log2 n.

Mit Induktion. n = 1 klar.

log2((n+ 1)!) = log2(n!) + log(n+ 1) 6 n log2(n) + log(n+ 1) 6 (n+ 1) log2(n+ 1).

2.4. Stabiles Sortieren

Wir führen zunächst einen neuen Begriff ein.

Definition 2.21 (Stabiles Sortieren). Ein Sortierverfahren heißt stabil, wenn gleichWerte nachDurch-lauf des Verfahrens in der gleichen Reihenfolge sind wie vorher.

Beispiel 2.22. Wir betrachten die Liste L=[3,5,2,5] und schreiben diese aber als L=[3,5,2,5] um diebeiden Einträge mit dem Wert 5, d.h. Einträge 1 und 3 zu unterscheiden.

Sortieren dieser Liste liefert entweder das Ergebnis [2,3,5,5] oder aber die Liste [2,3,5,5]. Im erstenFall ist die Sortierung stabil, denn die Einträge 5 und 5 tauschen die Reihenfolge nicht. Im zweiten Fallliegt keine stabile Sortierung vor.

Ex gilt nun, die bekannten Sortierverfahren Selection Sort, Algorithmus 2.1, Insertion Sort, Al-gorithmus 2.4, Min-Sort, Algorithmus 2.5, Merge Sort, Algorithmus 2.7 und Quicksort, Algo-rithmus 2.8 auf Stabilität zu analysieren.

Wir betrachten hier nur das zuletzt untersuchteQuicksort. Unsere Implementierung der Funk-tion def partitioniere(L,l,r) ist nicht stabil. Denn in Zeile 19 tauschen wir die Indizes jl und r,also das aktuelle Element und das Pivot-Element auch dann, wenn L[jl] == p gilt. Wir ändernalso die Reihenfolge von zunächst gleichen Elementen.

2.5. Radix-Sort

Wir betrachten zumAbschluss noch ein Sortierverfahren,welches auf dermehrfachenAnwen-dung von stabilen Verfahren aufbaut und welches die Komplexität On besitzt. Bei Radix-Sortwird das Prinzip einer lexikographischen Ordnung angewandt. Wir betrachten hier als Grund-menge die natürlichen Zahlen N, die Methode lässt sich jedoch einfach erweitern. Eine Zahla ∈ N stellen wir in 10er Basis dar als

a = adad−1 · · ·a1a0 =d∑i=0

10iai,

[email protected] 41

Page 48: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.5. Radix-Sort

d.h. a0 ist die 1-er Stelle, a1 die 10-er Stelle, usw. Gegebenenfalls gilt az = az+1 = . . . ,ad = 0ab einem Index z > 0.

Die übliche Ordnung 6 aufN kann auch als lexikographische Ordnung formuliert werden:

a = b ⇔ ai = bi ∀i = 0, . . . ,d

a < b ⇔ ∃k ∈ {0, . . . ,d}mit ak < bk und ai = bi für i = k+ 1, . . . ,n.

Es gilt also z.B. 1029 < 1043, also

9︸︷︷︸a0

·100 + 2︸︷︷︸a1

·101 + 0︸︷︷︸a2

·102 + 1︸︷︷︸a3

·103 < 3︸︷︷︸b0

·100 + 4︸︷︷︸b1

·101 + 0︸︷︷︸b2

·102 + 1︸︷︷︸b3

·103,

da a1 = 2 < 4 = ba und 0 = a2 = b2 = 0 sowie 1 = a3 = b3 = 1. Anders gesprochen: es wirdzunächst die Ordnung an d-ter Stelle (hier 3-ter Stelle) überprüft, dann an d−1-ter Stelle, usw.bis hin zur 0-ten Stelle.

Dieses Prinzip lässt sich auf viele andere Zahlensystem oder auch komplett anders gestalteteMengen übertragen. Im Folgenden betrachten jedoch nur einfache Zahlen-Ziffern.

Idee von Radix-Sort: Gegeben MengeM mit Elementen s ∈ S, welche eine lexikographischeOrdnung bzgl. Ihrer Stellen maximal d Stellen s0, . . . , sd besitzt.

Eine Liste L=[s1,s2,...,sn] dieser Menge werden nach folgendem Prinzip sortiert:1 for i in range (d+1) :2 Sor t i e re L bezügl ich S te l l e i s t ab i l

Beispiel 2.23. Wir betrachten die folgenden Zahlen und sortieren rückwärts nach den Ziffern.

Schritt: vorher 1 2 3

138 471 413 138471 413 713 167368 713 927 274413 453 628 368628 274 138 368798 646 646 413713 167 453 453646 927 167 471274 138 368 628368 368 368 646167 628 471 713927 798 274 798453 368 798 927

Man beachte, dass stets stabil sortiert wurde, d.h. Einträge mit jeweils gleicher Ziffer werden nie ge-tauscht.

42 ©2018 Thomas Richter

Page 49: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.5. Radix-Sort

Wir müssen also zunächst untersuchen, ob die bekannten Sortierverfahren stabil sind. Weiterkann Radix-Sort nur dann Sinn machen, wenn wir für die Sortierung nach einzelnen Ziffernein besonders schnelles Verfahren gefundenwird. Denn bei Radix-Sort müssenwir dieMengeder Elemente insgesamt dmal sortieren.

Satz 2.24. Merge-Sort und Insertion-Sort sind stabile Sortierverfahren.Quicksort ist im allgemeinennicht stabil. Es existieren jedoch stabile Varianten von Quicksort.

Beweis: Gegeben sei eine Menge Smit totaler Ordnung sowie eine Liste L=[s1,...,sn]mit Ele-menten dieser Menge. Insertion-Sort ist in Algorithmus 2.4 angegeben.

Wir betrachten jeweils einen Durchlauf der inneren Schleife, also Zeilen 4-6 der Algorithmus.Angenommen, für zwei Elemente L[k] und L[l]mit k < l gelte L[k]==L[l].

Angenommen, mindestens eines der Elemente hat einen Index größer i, also k > i oder l > i.Dann wird mindestens eines der Elemente sicher nicht getauscht, denn potentiell getauschtwerden nur Indizes j 6 i. Die Reihenfolge bleibt somit nach Durchlauf der Schleife bestehen.

Nun gelte 0 6 k < l 6 i. Falls die Schleife in Zeile 3 wegen L[j−1]<=L[j] bei j > l abbricht,so werden die Elemente mit Index k und l sicher nicht getauscht, denn aus k < l < j folgtk < j− 1.

Angenommen, der Index j = l wird erreicht. Nun folgen gegebenenfalls Tauschvorgänge,bei denen L[l] schrittweise mit Elementen L[l]=L[j]−>L[j−1]−>L[j−2]−>...−>L[s] getauschtwird.

Falls Abbruch bei s > k + 1, so wird die Reihenfolge der beiden Elemente nicht getauscht.Falls s = k+ 1 erreicht wird so kommt es wegen L[s]=L[l]=L[k]=L[s−1] zu einem Abbruch derSchleife.

Elemente mit gleichemWert werden also nie getauscht.

[email protected] 43

Page 50: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.5. Radix-Sort

Schnelles Sortieren kleiner Mengen

Für eine effiziente Umsetzung von Radix-Sort benötigen wir Verfahren zur Sortierung der Lis-ten nach einzelnen Ziffern. Speziell an dieser Aufgabe ist, dass nur eine sehr geringe Anzahlan verschiedenenWerten in jeder Ziffermöglich sind. Die Listen können beliebig lang sein, dieZiffern haben aber z.B. nur dieWerte {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, oder im Binärsystem lediglich dieWerte {0, 1}.

Bucket-Sort ist prinzipiell ein sehr schnelles Sortierverfahren. Zum Sortieren einer Liste von nElementen werdenO(n+m) Operationen benötigt, wobeim die Anzahl von möglicherweiseverschiedenen Elementen ist. Fallsm groß ist, so ist dieses Verfahren nicht effizient.

Sortieren wir jedoch nur nach einer Ziffer, so gibt es nur 10 unterschiedlicheWerte {0, 1, . . . , 9}.Es sind also nur 10 Eimer notwendig. Wir könnten somit auf die folgende Art nach der l-tenZiffer sortieren.

Algorithmus 2.10: Sortieren mit Bucket-Sort nach Ziffer l1 def bucketsort(L,l): # Liste L, Stelle l

2

3 B=[] # B ist eine Liste von Listen

4 for d in range(10): # Wir fuegen 10 leere Listen an

5 B.append([])

6

7 for i in range(n):

8 z = ziffer(L[i],l) # l−te Stelle von L[i]9 B[z].append(L[i]) # Fuege L[i] in richtigen Bucket ein

10

11 S=[] # Leere Ergebnis−Liste12 for i in range(10): # Durchlaufe die Buckets in korrekter Reihenfolge

13 for l in B[i]: # Durchlaufe die Elemente im Bucket

14 S.append(l) # Fuege Element an

15

16 return S

Die Funktion ziffer(..,..) soll dabei die entsprechende Ziffer zurück geben und muss nochgeschrieben werden, z.B. durch (einfache Funktion ohne jede Sicherheits-Abfrage)

1 def ziffer(x,l): # Rueckgabe der l−ten Ziffer von x2 return ( int(x/(10∗∗l)) % 10 )

Der Nachteil von Bucket-Sort ist der zusätzliche Speicheraufwand zum Speichern der Buckets,sowie das zweimalige Kopieren aller Elemente, zunächst in den Bucket, dann in die Ergebnis-liste.

Ein Vorteil von diesemAlgorithmus ist die Stabilität. Die Elemente werden in gleicher Reihen-folge in die Buckets gelegt, in der sie nachher auch entnommen werden.

Eine gute Alternative zum Sortieren nach Ziffern istCounting-Sort. In einem ersten Durchgangwird gezählt, wie oft jede Stelle vorkommt. Im zweitenDurchgang können die Elemente gleichan der richtigen Stelle eingefügt werden.

44 ©2018 Thomas Richter

Page 51: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.5. Radix-Sort

Algorithmus 2.11: Sortieren mit Counting-Sort nach Ziffer l1 def countingsort(L,l):

2 C = [0]∗10 # Vorkommen jeder Ziffer

3

4 for i in range(n): # Zaehle vorkommen der Ziffern

5 z = ziffer(L[i],l)

6 C[z]=C[z]+1

7

8 I = [0]∗10 # Start−Index fuer jede Ziffer9 for i in range(1,10):

10 I[i] = I[i−1] + C[i−1]11

12 S = [0]∗n # Ergebnisliste der Laenge n

13 for i in range(n):

14 z = ziffer(L[i],l)

15 S[I[z]] = L[i] # L[i] an richtige Stelle

16 I[z] = I[z]+1 # Index erhoehen

17

18 return S

Wirwählen hier wiederholt die Notation L=[0]∗n. Dies erstellt eine Liste mit dem Eintrag 0 undder Länge n. Man teste in Python den Effekt von Anwendungen der Art print([1,2,3]∗5).

ZumAbschluss vergleichen wir die verschiedenen Sortierverfahren für große Listen von Zah-len zwischen 0 und 108 und geben die gemessenen Laufzeiten an. Wir müssen bei Radix-Sortsomit stets 8 Durchgänge von Counting-Sort ausführen.

N Radix Quick Merge

20 0.0000046 0.0000036 0.00001740 0.0000089 0.0000081 0.00003180 0.0000110 0.0000146 0.000069

160 0.0000172 0.0000342 0.000126320 0.0000293 0.0000692 0.000241640 0.0000540 0.0001485 0.000529

1 280 0.0001024 0.0003106 0.0010212 560 0.0001962 0.0005980 0.0006425 120 0.0001327 0.0004300 0.00130010 240 0.0002474 0.0008956 0.00347820 480 0.0004856 0.0018293 0.00522640 960 0.0010229 0.0037729 0.01019781 920 0.0016786 0.0061296 0.016180

163 840 0.0028981 0.0113089 0.030600327 680 0.0055382 0.0235784 0.062167655 360 0.0111745 0.0500609 0.128783

1 310 720 0.0227151 0.1042850 0.2682302 621 440 0.0455057 0.2149980 0.5505685 242 880 0.0919180 0.4507670 1.160730

[email protected] 45

Page 52: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

2.5. Radix-Sort

x

x log(x)Merge-SortQuick-SortRadix-Sort

1× 1071× 10610000010000100010010

10.0000000

1.0000000

0.1000000

0.0100000

0.0010000

0.0001000

0.0000100

0.0000010

0.0000001

Der Unterschied zwischen der Laufzeit O(n) und O(n log(n)) scheint nicht sonderlich großund wird nur für sehr große Listen deutlich.

46 ©2018 Thomas Richter

Page 53: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3. Graphentheorie

Unter einemGraphwerdenwir eine Paar bestehend ausKnoten undKanten verstehen. Knotenkönnen z.B. Länder sein, Kanten gemeinsame Grenzen. Oder Knoten sind Straßenbahnhalte-stellen, Kanten sind die Schienenverbindungen dazwischen. An diesen beiden Beispielsgra-phen lassen sich einige wichtige Probleme der Graphentheorie beschreiben:

• Wie komme ich am schnellsten von der Haltestelle A zur Haltestelle B, wenn ich nurentlang der Schienen fahre? Dies ist das übliche Problem der Routenplanung.

• Wie kann ich die Länder auf einer Landkarte mit möglichst wenig verschiedenen Farbenso einfärben, dass je zwei Länder mit gemeinsamer Grenze eine unterschiedliche Farbehaben? Dies ist das Färbeproblem.

• Wie plane ich eine möglichst schnelle Route über alle Haltestellen im Straßenbahnnetz?Dies ist das Problem des Handlungsreisenden (Traveling Salesman).

• Ist es möglich durch Grenzübertritte von jedem Land der Karte zu jedem anderen Landzu kommen? Dieses Problem nennt man den Zusammenhang im Graphen.

In den folgenden Abschnitten werden wir diese - und weitere - Probleme der Graphentheorieanalysieren und Algorithmen zu deren Umsetzung untersuchen und implementieren. Einegroße Herausforderung vieler Probleme der Graphentheorie ist die Komplexität. Die von unsbeschriebenen Suchverfahren besaßen alle eine Komplexität von n (Radix-Sort), n log(n) (z.B.Merge-Sort oder Quicksort im durchschnittlichen Fall, aber auch jedes optimale vergleichsba-sierte Verfahren) odern2 (einfache Verfahrenwie Bubble Sort). In der Graphentheorie tauchenProbleme auf, für die bisher überhaupt kein Algorithmus bekannt ist, der das Problem in po-lynomialer Laufzeit, d.h. mit der Komplexität np für ein festes p ∈ N löst.1 Das Problem desHandlungsreisenden kann z.B. exakt mit dem Aufwand n! gelöst werden, für die praktischeUmsetzung ist dieser Aufwand jedoch schon bei kleinem n viel zu groß.

Im Rahmen dieser Vorlesung wird nur ein kurzer Einblick in die Graphentheorie mit einigengrundlegenden Problemen, Anwendungen und Algorithmen gegeben. Zum Weiterlesen gibtes viele empfehlenswerte Bücher, z.B. Diestel [2], Korte und Vygen [8] oder Schrijver [12].

3.1. Grundlagen

Definition 3.1 (Graph). Ein Graph (V,E) ist ein Paar, wobei V 6= ∅ und E ⊂ V × V Mengen sind.Die Elemente aus V heißen die Knoten, die Elemente aus E die Kanten.

Ein Graph heißt ungerichteter Graph, falls für x,y ∈ V und (x,y) ∈ E auch (y, x) ∈ E folgt.Ansonsten heißt er gerichteter Graph.1Mit n werden wir in der Graphentheorie meist die Anzahl an Knoten oder die Anzahl an Kanten im Graphenbezeichnen, oder aber auch Sie summe beider Werte.

47

Page 54: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.1. Grundlagen

Abbildung 3.1.: Karte von Europa.Diese Karte entstammt den Artikel https://de.wikipedia.org/wiki/Europa, lizenziert unter der Creati-ve Commons Attribution-Share Alike 3.0 Unported Lizenz(https://creativecommons.org/licenses/by-sa/3.0/legalcode). DieAutoren sind auf der Wikipedia-Seite genannt.{fig:europa}

Ein Graph heißt vollständiger Graph, falls er für alle x,y ∈ V mit x 6= y eine Kante (x,y) ∈ Ebesitzt.

Bemerkung 3.2 (Gerichtete und ungerichtete Graphen). Wir werden uns im wesentlichen mitungerichtetenGraphen beschäftigen. Zu jeder Kante (x,y) ∈ E existiert also auch eine Kante (y, x) ∈ E.Alternativ können wir in einem ungerichteten Graphen eine Kante als eine zweielementige Teilmenge{x,y} anstelle eines geordneten Paares auffassen. Denn für Mengen gilt {x,y} = {y, x}. Wir werdenjedoch meist die Schreibweise (x,y) verwenden und jeweils im Zusammenhang klarstellen, ob wir einengerichteten oder einen ungerichteten Graphen betrachten.

{bsp:graphen}

Beispiel 3.3. Wir betrachten einige Beispiel.

1. Gegeben sei die Karte in Abbildung 3.1. Wir bilden einen Graphen nach folgendem Prinzip:

V = {x | x ist ein Land Europas}, E = {(x,y) ∈ V×V | x und y haben eine gemeinsame Landgrenze}.

Zunächst handelt es sich natürlich nach einem Graphen entsprechend der obigen Definition. Die-ser Graph ist

• ungerichtet, da - falls eine Grenze zwischen Land x und Land y gibt - es auch eine Grenzezwischen Land y und Land x gibt.

48 ©2018 Thomas Richter

Page 55: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.1. Grundlagen

• nicht vollständig, da es nicht zwischen allen Ländern eine Grenze gibt, z.B. nicht zwischenPortugal und Albanien.

2. Wir bilden den Graphen nun nach folgendem Prinzip:

V = {x | x ist Land Europa}, E = {(x,y) ∈ V×V | es fließt ein Fluss von Land x nach Land y}.

Auch hierbei handelt es sich um einen Graphen bestehend aus Knoten - den Ländern - und denKanten, einer Teilmenge der Produktmenge V × V . Die genauen Eigenschaften lassen sich nurmit hinreichend geographischen Kenntnissen klären, aber vermutlich

• ist dieser Graph nicht vollständig, da es z.B. keinen Fluss gibt, der von den Niederlandennach Polen fließt.

• Ebenso ist der Graph vermutlich ein ungerichteter Graph, da es z.B. keinen größeren Flussgibt, der von Portugal nach Spanien fließt, viele jedoch in anderer Richtung.

3. Schließlich betrachten wir einen Graphen nach dem Prinzip:

V = {x | x ist Hauptstadt in Europa}, E = {(x,y) ∈ V × V | man kann von x nach y reisen}.

Eine Kante zwischen zwei Städten besteht laut dieser Definition nicht nur dann, wenn es einedirekte Reiseverbindung gibt, sondern wenn eine Reise überhaupt möglich ist. Wieder handelt essich um einen Graphen, dieser ist (derzeit) ungerichtet und vollständig.

Bemerkung 3.4. Diese von uns verwendete Definition ist eine Vereinfachung. Zwischen zwei Knotenx,y ∈ V kann es in “unseren Graphen” nur eine einzige Kante e = (x,y) ∈ E geben. Der Begriff desGraphen kann so erweitert werden, dass auch parallele Kanten zwischen zwei Knoten möglich sind(man spricht dann von einem Multigraphen).

Wir werden uns hier im wesentlichen mit ungerichteten Graphen befassen. Falls es eine Kante(x,y) ∈ E gibt, so ist die Kante (y, x) auch Element von E. Oder anders ausgedrückt, wir kön-nen eine Kante als ungeordnetes Paar {x,y} = {y, x} auffassen. Wir werden jedoch weiterhin(x,y) schreiben.

Es seien nun x,y ∈ V zwei Knoten, e = (x,y) ∈ E eine Kante. Wir sagen: “x und y sind dieEndknoten von e”, “Die Knoten x und y sind mit der Kante e inzident” und “die Knoten x undy sind benachbart oder auch adjazent”.

Definition 3.5 (Nachbarschaft). Sei (V,E) ein ungerichteter Graph. Für einen Knoten x ∈ V istdurch

N(x) = {y ∈ V \ {x} | (x,y) ∈ E} ⊂ V

undδ(x) = {(x,y) ∈ E} ⊂ E

die Nachbarschaft definiert.

Zwei Knoten x,y ∈ V heißen benachbart, wenn es eine Kante e = (x,y) ∈ E gibt.

Zwei Kanten e1, e2 ∈ E heißen benachbart, wenn es einen Knoten x ∈ V gibt, der Teil beider Kantenist.

Definition 3.6 (Grad). Der Grad eines Knotens x ist die Anzahl der mit x inzidenten Kanten |δ(x)|.

[email protected] 49

Page 56: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.1. Grundlagen

In Bezug auf Beispiel 3.3 (1.) gilt z.B.

N(Niederlande) = {Belgien, Deutschland}

sowie

δ(Niederlande) = {(Niederlande, Belgien), (Niederlande, Deutschland)},

d.h. der Grad der Niederlande ist 2.

Die Nachbarschaft von x besteht also aus allen Knoten y ∈ V , die durch eine Kante (x,y) mitx verbunden sind. Der Begriff kann erweitert werden zur Nachbarschaft einer Teilmenge vonKnoten X ⊂ V :

δ(X) = {e = (x,y) ∈ E | x ∈ X, y ∈ V \ X},

N(X) =⋃x∈X

N(x) \ X.

Definition 3.7 (Kantenzüge). Sei (V,E) ein Graph. Ein Kantenzug von x ∈ V nach y ∈ V ist eineFolge von Knoten xi ∈ V für i = 0, . . . ,k und Kanten ei = (xi−1, xi) ∈ E für i = 1, . . . ,k mit

x = x0e1−→ x1

e2−→ x2e3−→ · · · xk−1

ek−→ xk = y.

Im Fall x = y handelt es sich um einen geschlossenen Kantenzug

x = x0e1−→ x1

e2−→ x2e3−→ · · · xk−1

ek−→ xk = x.

Wir betrachten wieder den Graphen aus Beispiel 3.3 (1.) dann ist durch

Belgien→ Frankreich→ Spanien (3.1){bsp:kantenzug1}{bsp:kantenzug1}

ein Kantenzug gegeben, nicht aber durch

Belgien→ Deutschland→ Spanien,

da es keine Kante Deutschland→ Spanien gibt. Auch durch

Belgien→ Niederlande→ Belgien→ Deutschland, (3.2){bsp:kantenzug2}{bsp:kantenzug2}

ist ein Kantenzug gegeben. Dass der Knoten Belgien doppelt vorkommt ist kein Problem.{def:weg}{def:kreis}

Definition 3.8 (Wege und Kreise). Es sei

x0e1−→ x1

e2−→ x2e3−→ · · · xk−1

ek−→ xk

ein Kantenzug mit paarweise verschiedenen Knoten {x0, . . . , xk}. Der Teilgraph

P := (V ′,E ′) = ({x0, . . . , xk}, {e1, . . . , ek}) ⊂ (V,E)

wird Weg genannt. Wird ein Weg P mit mindestens 3 Knoten (d.h. k > 2) um eine Kante ek+1 =(xk, x0) erweitert, so dass

x0e1−→ x1

e2−→ x2e3−→ · · · xk−1

ek−→ xkek+1−−−→ x0

ein geschlossener Kantenzug ist, so heißt er Kreis

C := (V,E) = ({x0, . . . , xk}, {e1, . . . , ek, ek+1}).

Die Länge eines Weges oder Kreises ist die Anzahl seiner Kanten.

50 ©2018 Thomas Richter

Page 57: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.2. Graphentheoretische Probleme

Bemerkung 3.9 (Kantenzüge und Wege). Der Unterschied zwischen Kantenzügen und Wegenscheint zunächst sehr klein. Mit einem Kantenzug meinen wir eine Abfolge von Knoten und Kanten,unter einem Weg verstehen wir einen Graphen, der durch die Knoten und Kanten eines Kantenzugsgebildet wird - wenn kein Knoten doppelt vorkommt.

Betrachten wir den Kantenzug (3.1) so ist der zugehörige (gerichtete) Graph gegeben durch

V = {Belgien,Frankreich,Spanien}, E = {(Belgien,Frankreich), (Frankreich,Spanien)},

ein Teilgraph des ursprünglichen Graphen aus Beispiel 3.3.

Man sagt “der Weg P verbindet die Knoten x0 und xk”. Die Suche von verbindenden Wegen mitspeziellen Eigenschaften (z.B. möglichst kurz) ist eine der großen Aufgaben der Graphentheo-rie. In allgemeinen Graphen muss es zwischen zwei Knoten x,y ∈ V nicht unbedingt einenWeg P geben.

Definition 3.10 (Zusammenhängend). Ein Knoten y ∈ V heißt von x ∈ V aus erreichbar, falls eseinen Weg gibt der x und y verbindet.

Ein Graph (V,E) heißt zusammenhängend, falls es zu je zwei Knoten x,y ∈ V einen Weg gibt, der xund y verbindet. Ansonsten heißt der Graph unzusammenhängend.

Graph 1 aus Beispiel 3.3 ist z.B. nicht zusammenhängend. Der Knoten Malte ist von Polen durchkeinen Weg erreichbar. Graph 3 hingegen ist zusammenhängend, da es eine Möglichkeit gibt,von jeder Hauptstadt in jede andere Hauptstadt zu reisen.

Satz 3.11. Ein ungerichteter Graph G = (V,E) ist genau dann zusammenhängend, falls für alle nichtleeren, echten Knotenteilmengen

X ⊂ V mit X 6= ∅ und X 6= V

δ(X) 6= ∅ gilt.

3.2. Graphentheoretische Probleme

Im Folgenden werden einige wichtige Probleme der Graphentheorie vorgestellt.

A. Das Färbeproblem Wie viele verschiedene Farben sind notwendig um eine Landkarte sozu färben, dass zwei Länder mit gemeinsamer Grenze (von positiver Länge, also keine Punkt-Grenzen) stets eine unterschiedliche Farbe haben?

[email protected] 51

Page 58: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.2. Graphentheoretische Probleme

Karte der deutschen Bundesländer inkl. Färbung der Länder mit insgesamt vier Farben, sodass zwei benachbarte Länder nie die gleiche Farbe haben. [Bild: public domain, veröffentlichtauf https://programmingwiki.de/Färbungsprobleme]

Die Lösung dieses Problems heißt der Vier-Farben-Satz. Es genügen also stets vier Farben.

Satz 3.12 (Vier-Farben-Satz). Es genügen stets vier Farben, um die Länder einer Landkarte in dereuklidischen Ebene so zu färben, dass keine zwei benachbarten Länder die gleiche Farbe besitzen.

Dieser Satz wurde bereits gegen 1850 formuliert, konnte aber erst über hundert Jahre späterbewiesen werden. Die Beweise zum Vier-Farben-Satzwerden mit Hilfe von Computern durch-geführt: zunächst wird die Anzahl möglicher typischer Konfigurationen reduziert (nach wievor auf über 1000 verschiedene). Auf diesen Konfigurationenwird das Färbeproblemmit Hilfedes Computers gelöst.

Die Kartenfärbung kann mit Hilfe eines Graphen beschrieben werden.

52 ©2018 Thomas Richter

Page 59: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.2. Graphentheoretische Probleme

Die Knoten des Graphen sind die Bun-desländer V = {x1, . . . , x16}, eine Kantee = {xa, xb} ∈ E ⊂ V × V existiert zwi-schen Bundesländern xa, xb mit gemein-samer Grenze (positiver Länge).Gesucht ist eine Färbung der Knoten f :V → {1, . . . ,M} mit M ∈ N möglichstklein, so dass f(xa) 6= f(xb) für alle e ={xa, xb} ∈ E.[Bild: public domain, modifiziert. Veröf-fentlicht auf https://programmingwiki.de/Färbungsprobleme]

Definition 3.13 (Kantengewichte). Es sei G = (V,E) ein Graph. Eine Abbildung

f : E→ R

wird Gewichtsfunktion genannt. Für e ∈ E wird durch ce = f(e) das Kantengewicht bezeichnet.

Wir betrachten meist nur positive Kantengewichte, also

f : E→ R>0.

Für einige Algorithmen wird diese Annahme ganz wesentlich sein.

B. Routenplanung Gesucht ist die kürzeste (oder schnellste oder schönste) Route zwischenzwei Städten.

[email protected] 53

Page 60: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.2. Graphentheoretische Probleme

Gegeben ist ein gewichteter Graph G =(V,E, f) sowie zwei Knoten x,y ∈ V . Ge-sucht ist einWeg

P = ({x = x0, . . . , xk = y}, {e1, . . . , ek})

der x und y verbindet und das kleinstesummierte Kantengewicht hat

k∑i=1

cek → min.

[Bild: von Fremantleboy unterCreative-Commons-Lizenz 2.52, veröffentlicht auf https://www.wikipedia.de.]

C. Traveling Salesman - Problem des Handlungsreisenden Gesucht ist die kürzeste (oderschnellste oder schönste) Route, auf welcher eine gegebene Menge von Städten jeweils genaueinmal besucht wird.

[Bild: von Fremantleboy unter CC BT 2.5 Lizenzauf www.wikipedia.de.]

Gegeben ist ein vollständiger gewichteterGraph (V,E, f). Gesucht ist der Kreis

C = ({x1, . . . , xk}, {e1, . . . , ek}),

welcher alle Knoten des Graphen verbin-det und dessen summiertes Gewicht

k∑i=1

cek → min

minimal ist.

2https://creativecommons.org/licenses/by/2.5/deed.de

54 ©2018 Thomas Richter

Page 61: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.2. Graphentheoretische Probleme

Wir werden sehen, dass dieses Problem sehr schwer ist. Bisher ist kein effizienter Algorithmusbekannt, der dieses Problem in einer polynomiellen Laufzeit, d.h. mit der Komplexität (np)für ein festes p ∈ N löst. Es ist überhaupt nicht bekannt, ob sich dieses Problem effizient lösenkann. Hier verbirgt sich ein wichtiges Problem der Komplexitätstheorie auf welches wir nochzurückkommen. Das Problem hat vielfältige Anwendungen, z.B. bei der Routenplannung fürdie Auslieferung von Paketen oder Briefen.

Definition 3.14 (Euler-Tour). Es sei G = (V,E) ein Graph. Ein Kantenzug

x0e1−→ x1 · · ·

ek−→ xk,

der jede Kante e ∈ E genau einmal verwendet heißtEuler-Tour. Ist Fall eines geschlossenenKantenzugsx0 = xk nennen wir die Tour einen Euler-Kreis.

Ein Euler-Kreis ist nicht unbedingt ein Kreis, da jede Kante zwar nur genau einmal vorkom-men darf, die Knoten jedoch mehrfach auftauchen dürfen.

D. Königsberger Brückenproblem Ist es möglich, über jede der sieben Brücken genau einmalzu gehen und dann wieder am Ausgangspunkt anzukommen?

[Bilder: unter der Creative Commons Attribution-Share Alike 3.0 Lizenz auf www.wikipedia.deveröffentlicht. ]

Es gilt:

Satz 3.15. Es seiG = (V,E) ein zusammenhängender Graph. Es existiert genau dann ein Euler-Kreisin G, wenn alle Knoten x ∈ G einen geraden Grad haben.

E. GraphpartitionierungGegeben ist ein GraphG = (V,E)mit n ∈ NKnoten. Gesuch ist eineAufteilung (=Partitionierung) des Graphens in p ∈ N Teilgraphen Gi = (Vi,Ei) mit Vi ⊂ Vund Ei ⊂ E und den folgenden Eigenschaften

• Die Teilgraphen haben gleich viele Knoten

|Vi| =|V |

p

• Bei der Erstellung des Teilgraphen werden möglichst wenige Kanten geschnitten, d.h.die Menge

E ′ := {e = (x,y) ∈ E | x ∈ Vi und y ∈ Vj i 6= j}

ist möglichst klein.

[email protected] 55

Page 62: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.2. Graphentheoretische Probleme

Die beiden Ziele sind üblicherweise nicht exakt zu erreichen. Ein Graph mit 100 Knoten kannnatürlich nicht in 3Graphenmit exakt gleicher Knotenzahl geteilt werden. Aber selbstwenn ei-ne theoretisch optimale Partitionierung existiert, so sind im allgemeinen Fall keine effizientenAlgorithmen bekannt, diese auch zu berechnen. Die Graphpartitionierung ist ein sogenann-tes NP-vollständiges Problem. Es ist nicht nur kein Algorithmus bekannt, der das Problem ineiner (in der Anzahl n der Knoten) polynomiellen Zeit optimal löst, selbst zur Überprüfungeiner möglichen “Lösung” auf Optimalität ist kein Algorithmus mit polynomieller Laufzeitbekannt.

Das Problem hat viele Anwendungen im parallelen Rechnen, also dem Ausnutzen von Paral-lelrechnern zur Beschleunigung von Algorithmen:

• Wie teile ich eine Aufgabe (der Größe n) gleichmäßig auf p Recheneinheiten auf, die ihrejede Teilaufgabe parallel (also gleichzeitig) bearbeiten.

• Dabei soll die Kommunikation zwischen denRecheneinheitenmöglichst gering gehaltenwerden, da diese zusätzlichen Aufwand bedeutet.

Da zur exakten Lösung der Graph-Partitionierung keine Algorithmen existieren, müssen heu-ristische Verfahren zur Approximation eingesetzt werden. Für die praktische Anwendung istdies im allgemeinen auf ausreichend. Wenn eine Aufgabe der Größe n = 1 000, 000 auf 1 000Recheneinheiten partitioniert werden kann, so kann die Rechenzeit theoretisch um den Fak-tor 1 000 reduziert werden. Ist die Graph-Partitionierung aber nicht exakt, angenommen dieTeilgraphen haben zwischen 900 und 1 100 Knoten, so ist die Zeitersparnis nach immer noch1 100 000 : 1100 ≈ 910.

F. Bandbreiten-Problem Wir definieren:

Definition 3.16 (Bandweite eines Graphen). Es sei G = (V,E) ein Graph mit n Knoten und einereineindeutigen Nummerierung f : V → {1, . . . ,n} (d.h. jedem Knoten ist eine eineindeutige Nummerzugeordnet). Unter der Bandbreite des Graphen bezeichnen wir die maximale Differenz der Knoten-nummern in einer Kante, d.h. die Kenngröße

maxe=(x,y)∈E

|f(x) − f(y)|.

Unter dem Bandbreiten-Problem verstehen wir nun die folgende Aufgabe: Gesucht ist eineeineindeutige Nummerierung f : V → {1, . . . ,n} der Knoten, so dass die Bandbreite des Gra-phen möglichst minimal ist.

Auch das Bandbreiten-Problem ist ein Problem, für welches keine effizienten Algorithmen zurexakten Lösung bekannt sind, es gehört zur Klasse der NP-schweren Probleme.

Das Bandbreiten-Problem taucht als Teilaufgabe der numerischenMathematik auf. Hier müs-sen oft lineare Gleichungssysteme mit einer speziellen Struktur gelöst werden:

Definition 3.17 (Dünn besetzte Matrix, Bandmatrix). Es seiA ∈ Rn×n eine Matrix. Wir nennendie Matrix A = (aij)ij eine Bandmatrix mit Bandbreitem ∈ N, falls

aij = 0 ∀|i− j| > m,

56 ©2018 Thomas Richter

Page 63: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.3. Darstellung und Umsetzung

d.h. wenn alle Einträge einer Matrix außerhalb des Bandes mit Breite 2m (m nach rechts undm nachlinks von der Diagonale aus) verschwinden. Generell nennen wir eine Matrix dünn besetzt, wenn dieAnzahl der nicht-Null Elemente klein ist, d.h.

|{(i, j) ∈ {1, . . . ,n}2 | aij 6= 0}|� n2.

Die Definition von dünn besetzt ist nicht eindeutig. Eine strenge Definition bedeutet, dass injederMatrix-Zeile nur eine feste (unabhängig vonn) Anzahl an Elementen ungleichNull sind.

Zu jeder Matrix A ∈ Rn×n kann nach folgendem Prinzip ein Graph erstellt werden

V = {1, 2, . . . ,n}, E = {(i, j) ∈ V × V | aij 6= 0}.

Die Lösung des Bandbreiten-Problems bedeutet für die Matrix, dass sie bei entsprechenderUmsortierung in eine Bandbreite mit möglichst geringer Bandbreite m transformiert wird.Eine effiziente Durchführung der Gauß-Elimination bei einer Bandmatrix benötigt O(nm2)Operationen anstelle von O(n3) Operationen bei einer allgemeinen Matrix. Ist n groß und mverhältnismäßig klein, so ist der Unterschied wesentlich.

3.3. Darstellung und Umsetzung

Zum Beschreiben eines Graphen (V,E) mit nV ∈ N Knoten V = {x1, . . . , xnV } und nE ∈ NKanten E = {e1, . . . , enE} eignet sich z.B. die Adjazenzmatrix A ∈ RnV×nV mit der Eigenschaft

A = (aij)nVi,j=1, aij =

{1 (xi, xj) ∈ E0 sonst

.

6

5

4

3

21

Es ist ein ungerichteter Graph mit 6 Knoten und 8Kanten.

A =

0 1 1 1 0 11 0 0 1 1 11 0 0 1 0 01 1 1 0 0 00 1 0 0 0 01 1 0 0 0 0

Zur Speicherung des Graphen in einer Adjazenz-matrix sind 36 Matrixeinträge notwendig.

In praktischen Anwendungen und gerade bei der Implementierung von Verfahren auf demComputer ist die Adjazenzmatrix nicht effizient. Betrachtet man z.B. das Straßensystem zwi-schen den etwa 2 000 Städten in Deutschland (den Knoten eines Graph) so stellt man fest, dass

[email protected] 57

Page 64: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.3. Darstellung und Umsetzung

jede Stadt nur mir einigen wenigen Städten direkt (also mit einer Kante) verbunden ist. DieSpeicherung der Adjazenzmatrix würde 2 0002 = 4 000 000 Einträge benötigen.

Eine alternative Speicherung eines Graphen ist die Inzidenzmatrix A ∈ RnV×NE mit der Ei-genschaft

A = (aij)nV ,nEi,j=1 , aij =

{1 (xi, x

′i) = ej ∈ E

0 sonst.

Ein Matrixeintrag aij ist somit 1, falls es eine Kante ej gibt, welche den Knoten xi als End-punkt hat. Diese Art der Darstellung hat meist einen noch größeren Speicherbedarf, da in denmeisten Graphen jeder Knoten mindestens zu einer Kante gehört.

Wir geben die Inzidenzmatrix (Knoten-Kanten-Matrix) an. Hierzu benennenwir zunächst die8 Kanten. Dabei setzenwir im ungerichtetenGraphen eine Kante (x1, x2)mit der Kante (x2, x1)gleich.

e1 = (3, 4) e2 = (1, 3) e3 = (1, 4) e4 = (2, 4),

e5 = (2, 5) e6 = (1, 2) e7 = (1, 6) e8 = (2, 6)

Die Inzidenzmatrix ergibt sich als

A =

0 1 1 0 0 1 1 00 0 0 1 1 1 0 11 1 0 0 0 0 0 01 0 1 1 0 0 0 00 0 0 0 1 0 0 00 0 0 0 0 0 1 1

Die Inzidenzmatrix benötigt mit nV ×nE Einträgen im Allgemeinen noch weit mehr Speicherals die Adjazenzmatrix. Eine effiziente Speicherung eines Graphen erfolgt mit der Adjazenz-liste. Hier wird für jeden Knoten die Menge der Knoten (oder alternativ Kanten) gespeichert,die mit diesem Knoten verbunden sind. Die Adjazenzliste ist eine dünne Struktur (im engl.sparse) zur Speicherung des Graphen.

Wir geben schließlich die Adjazenzliste des Graphen an

1 7→ 2, 3, 4, 6

2 7→ 1, 4, 5, 6

3 7→ 1, 4

4 7→ 1, 2, 3

5 7→ 2

6 7→ 1, 2

(3.3){adjliste:1}{adjliste:1}

Gespeichert werden müssen schließlich 6 Listen mit insgesamt 16 Einträgen.

3.3.1. Realisierung in Python

Es gibt Erweiterungsbibliotheken für Python zur effizienten Handhabung von Graphen. Hiersind wichtige Algorithmen bereits implementiert, so dass die vorgestellten Probleme schnell

58 ©2018 Thomas Richter

Page 65: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.3. Darstellung und Umsetzung

und effizient behandelt werden können. ImRahmen dieser Vorlesungwerdenwir diese Biblio-theken zunächst nicht verwenden, sondern die Darstellung von Graphen selbst implementie-ren. Hierzu wählen wir Adjazenzlisten als sparsame und effiziente Form. Für uns besteht einGraph aus

• n Knoten

• für jeden der n Knoten wählen wir eine Liste um die möglichen Kanten zu den weiterenn− 1 Knoten zu speichern

In Python können Listen als Elemente wieder Listen enthalten. Wir setzen als Beispiel denGraphen aus (3.3) um. Die Adjazenzliste dieses Graphen, bestehend aus 6 Knoten, kann durchdie folgende doppelte Liste dargestellt werden:

1 n = 6 # Anzahl der Knoten

2 G = [[1,2,3,5],[0,3,4,5],[0,3],[0,1,2],[1],[0,1]]

3

4 print(G) # Ausgabe

Man beachte, dass die Indizes im Vergleich zu (3.3) um eins verschoben sind. Dies ist not-wendig, da Python bei Null zu zählen beginnt. In der Liste G[0] stehen die Kanten vom erstenKnoten gespeichert. In Python hat dieser den Index 0, im Beispiel (3.3) den Index 1. Im Fol-genden werden wir stets bei 0 anfangen. Das kurze Python-Beispiel zeigt, dass die Anzahl derKnoten nicht unbedingt gespeichert werden muss. Denn es sollte stets n == len(G) gelten.

Wir werden stets darauf achten, dass die Einträge in jeder Liste G[i] für i = 0, . . . ,n−1 sortiertsind. Dies können wir einfach mit den verschiedenen Sortierverfahren erreichen, die wir inKapitel 2 diskutiert haben. Darüber hinauswerdenwir in der Adjazenzliste nie eine Kante voneinem Knoten i zu sich selbst speichern. Schließlich betrachten wir nur ungerichtete Graphen.Wir geben beispielsweise einige grundlegende Algorithmen an:

1. Die Funktion test_ungerichtet prüft, ob der gegebene Graph ungerichtet ist

2. Die Funktion graph_aufraemen sortiert die Adjazenzliste, entfernt doppelte Kanten undentfernt selbstverweise, d.h. Kanten der Art (i, i)

1 # Testet, ob der Graph G ungerichtet ist

2 # Rueckgabe: True falls ungerichtet , False falls gerichtet

3 def test_ungerichtet(G):

4 for k in range(len(G)): # alle Knoten durchlaufen

5 for j in G[k]: # Nachbarn von k, d.h. Kanten(k,j) durchlaufen

6 if not(k in G[j]): # Es gibt keine Kante (j,k)

7 return False # ... Graph ist nicht ungerichtet

8 return True # Graph ist gerichtet

9

10 # Transformiert Graph in Standard−Form11 # − Nachbarn sortiert

12 # − keine doppelten Kanten

13 # − keine Kante zu eigenem Knoten

14 def graph_aufraeumen(G):

15 for k in range(len(G)): # Alle Knoten durchlaufen

[email protected] 59

Page 66: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

16 SORT(G[k]) # Sortieren der Nachbarn

17 # SORT ist ein beliebiges Sortierverfahren

18

19 S = [] # neue, bereinigte Liste für Nachbarn

20 j = −1 #

21 for i in G[k]: # Alle Nachbarn durchlaufen

22 if i != j: # Neuer Nachbar?

23 j = i # dann merken

24 if i!=k: # Nicht der aktuelle Knoten?

25 S.append(i) # dann einfuegen

26

27 G[k] = S # neue Liste speichern

3.4. Zusammenhang

Ein Graph G = (V,E) ist zusammenhängend, wenn es zu je zwei Knoten x,y ∈ V einen Wegin G gibt, der x und y verbindet. Im Folgenden betrachten wir Algorithmen zur Suche vonWegen, sowie zur Bestimmung aller Knoten y ∈ V , die von einem x ∈ V aus erreichbar sind.

Definition 3.18 (Zusammenhangskomponente). Es sei G = (V,E) ein ungerichteter Graph. Diemaximalen zusammenhängenden Teilgraphen von G sind die Zusammenhangskomponenten vonG.{bsp:zusammenhang}

Beispiel 3.19. Der folgende Graph mit 5 Knoten und 3 Kanten

1

2

3

4

5

hat zwei Zusammenhangskomponenten G1 und G2:

G1 = (V1 = {1, 2, 3}, E1 = {(1, 2), (2, 3)}), G2 = (V2 = {4, 5}, E2 = {(4, 5)}).

Im Folgenden werden wir Algorithmen untersuchen, um die Zusammenhangskomponenteneines Graphen zu bestimmen. Der Grundalgorithmus ist die Durchmusterung von Graphen.Ausgehend von einem Knoten x ∈ V suchen wir alle Knoten y ∈ V , die von x aus erreichbarsind.

Wir benötigen einige weitere Begriffe.

Definition 3.20 (BaumundWald). Ein ungerichteter Graph heißtWald, falls er keinen Kreis enthält.Ein Baum ist ein zusammenhängender Wald. Knoten vom Grad 1 in einem Baum heißen Blatt.

60 ©2018 Thomas Richter

Page 67: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

Die Zusammenhangskomponenten eines Waldes sind Bäume.

Bäume eignen sich, um die Zusammenhangskomponenten eines Graphen darzustellen. DerGraph aus Beispiel 3.19 ist ein Wald. Jede der beiden Zusammenhangskomponenten ist einBaum. Die Knoten 1, 3, 4, 5 sind Blätter.

Das grundlegende Verfahren zur Bestimmung von Zusammenhangskomponenten in einemGraphen G = (V,E) ist die Graphdurchmusterung.

Wir geben zunächst einen Algorithmus an, der auch umgangsprachlich formulierten Pseudo-Code enthält. Zeilen, die nicht in Python formuliert sind, sind rot unterlegt.

{algo:durchmusterung}Algorithmus 3.1: GraphdurchmusterungGegeben ungerichteter Graph G als Adjazenzliste (doppelte Liste) mit n=len(G) Knoten sowieausgezeichneter Knoten x ∈ {0, . . . ,n−1}. Ausgabe: Liste K aller Knoten, die von x aus erreich-bar sind sowie die Adjazenzliste Z eines aufspannenden Baumes.

1 def graph_durchmusterung(G,x):

2 n = len(G) # Anzahl der Knoten im Graph

3 Z=[] # Adjazenzliste der Zusammenhangskomponente

4 for i in range(n): # leere Listen fuer Nachbarn einfuegen

5 Z.append([])

6 K=[x] # Knoten in der Zusammenhangskomponente

7 Q=[x] # Hilfsliste

8 while len(Q)>0:

9 wähle y aus Q # Ein Element y auswaehlen. Details spaeter!

10 falls ein Nachbar z von y existiert , der noch nicht in K ist:

11 K.append(z) # Knoten z hinzufuegen

12 Z[y].append(z) # Kante (y,z) hinzufuegen

13 Z[z].append(y) # Kante (z,y) hinzufuegen

14 Q.append(z) # von z aus weitersuchen

15 else:

16 Q.remove(y) # y hat keine neuen Nachbarn mehr

Die grundlegende Idee von diesem Algorithmus ist es, die Zusammenhangskomponente ZStück für Stück aufzubauen. Hierzu wird eine temporäre Liste Q geführt. Zunächst wird derKnoten x in Q eingefügt. Dann wird in Zeile 9 jeweils ein Knoten y aus der Liste Q entnommen.Wir wissen, dass dieser Knoten y von x aus erreichbar ist. Ein Nachbar z von y ist also auchvon x aus erreichbar und wird daher den Listen Q sowie Z hinzugefügt. Hat ein Knoten y keineneuen Nachbarn mehr, also solche die schon in Z enthalten sind, so wird der Knoten aus dertemporären Liste Q entfernt.

Der Algorithmus ist in den beiden Zeilen 9 und 10 in Pseudo-Code formuliert, da er hier nocheine gewisse Freiheit enthält:

• in Zeile 9 wählen wir einen Knoten der Hilfsliste Q, spezifizieren aber nicht, welchen.

• ebenso wählen wir in Zeile 10 eine Kante e = (y, z) unter der Bedingung dass e ∈ Esowie z 6∈ Z, spezifizieren aber nicht die konkrete Realisierung dieser Wahl.

[email protected] 61

Page 68: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

Wir werden später zwei verschiedene Realisierungen der Graphdurchmusterung diskutieren,die Tiefensuche sowie die Breitensuche. Die konkreten Verfahren unterscheiden sich in der ex-akten Wahl der von Knoten und Kante in Zeilen 9 und 10.{satz:durchmusterung}

Satz 3.21 (Graphdurchmusterung). Der Algorithmus zur Graphdurchmusterung eines GraphenG = (V,E) zum Knoten x ∈ V liefert eine maximale Zusammenhangskomponente Z mit x ∈ Z.Bei optimaler Implementierung benötigt der Algorithmus lineare Laufzeit (bezogen auf die Anzahl derKnoten und Kanten)

O(|V |+ |E1|),

wobei E1 die Menge der Kanten in der Zusammenhangskomponente Z von x ist.

Beweis. (i)Wir zeigen zunächst, dass der durch die Knoten K und die Adjazenzliste Z gegebeneGraph zu jedem Zeitpunkt im Verfahren ein Baum ist. Zu Beginn des Verfahrens gilt:

1 K=[x]

2 Z=[[] ... []]

d.h. K enthält nur den Knoten x und Z enthält keine Kanten. Dieser Graph - bestehend auseinem Knoten - ist somit zusammenhängend und kreisfrei, also ein Baum.

Im Verfahren wird der Graph bestehend aus der Liste K und der Adjazenzliste Z nur in denZeilen 11-13 erweitert. Der Knotenliste Kwird ein Knoten z nur dann hinzugefügt, wenn diesermit einem Knoten y ∈ K durch eine Kante e = (y, z) ∈ E verbunden ist, aber noch nicht in Kenthalten ist. Diese Kante, sowie die gegenläufige Kante e ′ = (z,y) ∈ E (dieser Schritt ist nichtnotwendig) werden der Adjazenzliste Z hinzugefügt. Der resultierende Teilgraph K,Z ist somitnach wie vor zusammenhängend und - da z nicht in K lag - immer noch kreisfrei. Somit liegtein Baum vor.

(ii) Angenommen, nach Abschluss des Verfahrens gebe es einen Knoten r ∈ V \ K, der abervon einem Knoten x ∈ K erreichbar wäre. Dies bedeutet: es gibt einen Weg P in G = (V,E),der x und r verbindet. Es sei (a,b) ∈ E eine Kante auf diesem Weg mit a ∈ K und b ∈ V \ K.Da a ∈ Kmuss es einen Durchlauf des Algorithmus gegeben haben mit a ∈ Q (es werden nurKnoten in K eingetragen, die zuvor in Q lagen). Dieser Knoten a wird jedoch nur dann aus Qentfernt, wenn es keine solche Kante (a,b) gibt. Dies ist ein Widerspruch, also kann es keineerreichbaren Knoten r ∈ V \ K geben.

(iii) Es bleibt die Bestimmung der Komplexität.

In den Zeilen 1-7 des Algorithmus entsteht Aufwand der Ordnung (n) zur Initialisierung derErgebnis-Adjazenzliste Z. Der wesentliche Aufwand besteht in den Zeilen 7-15, d.h. in derwhile-Schleife: für jeden Knoten y ∈ Q (der auch immer y ∈ K in der Knotenliste der Zu-sammenhangskomponente ist) durchlaufen wir potentiell alle Kanten (y, z). Dabei betrachtenwir jede Kante höchstens einmal, denn sobald (y, z) berücksichtigt wurde, muss der Knoten znichtweiter betrachtet werden (siehe Zeile 10).Wurden einmal alle von y ausgehendenKantenbetrachtet, so wird in Zeile 16 der Knoten y aus Q entfernt. Da y bereits in der Zusammen-hangskomponente y ∈ K ist, wird ein Knoten y nie zweimal der ListeQ hinzugefügt. Hierausfolgt, dass wir jede Kante imGraphen höchsten einmal betrachten. Die Anzahl der Durchläufe

62 ©2018 Thomas Richter

Page 69: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

von Zeilen 8-16 ist somit maximal O(|E1|). Falls die Zeilen 9 und 10 im Algorithmus in linearerLaufzeit O(1) implementiert werden, so ergibt sich die postulierte Komplexität

O(|V |+ |E1|)

Satz 3.22 (Zusammenhangskomponenten). Alle Zusammenhangskomponenten eines ungerichte-ten Graphen können in linearer Laufzeit

O(|V |+ |E|)

bestimmt werden.

Beweis. Man startet das Verfahren mit einem beliebigen Knoten x ∈ V . Als Ergebnis erhältman in der Laufzeit

O(|V |+ |E1|)

eine Zusammenhangskomponente Z1 = (K1,E1). Wir führen das Verfahren weiter mit einemKnoten x ∈ V \ V1 (falls vorhanden). Die entsprechende Zusammenhangskomponente Z2 =(V2,E2) können wir in Laufzeit

O(|E2|)

bestimmen, da die anfängliche Initialisierung der Liste der besuchten Kanten nur einmal er-folgen muss. Nachm Schritten erhalten wir die Laufzeit

O(|V |+ |E1|+ |E2|+ · · ·+ |Em|) = O(|V |+ |E|),

da|E1|+ · · ·+ |Em| 6 |E|.

Definition 3.23 (Breitensuche und Tiefensuche). Wählt man bei der Graphdurchmusterung jeweilsden Knoten y ∈ Q, der zuletzt zu Q hinzugefügt wurde, so nennt man das Verfahren Tiefensuche.Wählt man den Knoten y ∈ Q, der als erstes zu Q hinzugefügt wurde, so nennt man das VerfahrenBreitensuche.

Die Grundideen der beiden Varianten beschreiben zwei verschiedene Datenstrukturen, last infirst out sowie first in first out. Die Erste Datenstruktur wird mit einem Stack realisiert. Wie aufeinen Bücherstapel werden Elemente oben abgelegt und auch wieder von oben entfernt. Diezweite Variante, first in first out beschreibt eineWarteschlange, auf englischQueue. Das Elementwelches zuerst in dieWarteschlange zugefügt wurde, wir auch als erstes wieder entfernt. Stel-len wir uns beide Datenstrukturen als Listen vor, so erfolgt bei einem Stack das Hinzufügenund Entfernen auf der gleichen Seite, bei einer Warteschlange erfolgen Hinzufügen und Ent-fernen auf unterschiedlichen Seiten. Bei der Realisierung von Stacks und Queues müssen wirdarauf achten, dass das Hinzufügen von Elementen sowie das entnehmen von Elementen inkonstanter LaufzeitO(1) erfolgt. Ansonsten gilt die Aussage zur Komplexität in Satz 3.21 nichtmehr.

[email protected] 63

Page 70: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

3.4.1. Tiefensuche

Bemerkung 3.24 (Stacks in Python). Stacks lassen sich in Python einfach durch Listen realisieren.Es sei L eine Liste. Das anhängen eines neuen Elements x, d.h. das Ablegen von x oben auf demStapel wird mit der Funktion L.append(x) in optimaler Laufzeit erledigt. Das Entnehmen des letztenElements, d.h. das Entfernen des obersten Elements des Stapels erledigt die Funktion z=L.pop().Diese Funktion liefert das oberste Element zurück und entfernt es aus der Liste.

1 # ein Beispiel zum Abtippen

2 L = [1,5]

3 L.append(4)

4 L.pop()

5 L.pop()

6 print(L)

Mit diesen Strukturen können wir nun die Tiefensuche in Python implementieren. In Zeile 9des Algorithmus wählen wir nun also jeweils das letzte Element der Liste Q, d.h. y=Q[len(Q)−1]↪→ . Alternativ können wir das Element mit dem Befehl y=Q.pop() entnehmen. Dieser Befehllöscht jedoch sofort das letzte Element aus der Liste. In Zeile 16 von Algorithmus 3.1 wirddas Element y jedoch erst dann aus Q gelöscht, wenn y keine weiteren Nachbarn mehr hat, dienoch nicht in Z liegen. Auch wenn die Verwendung von y=Q.pop() eventuell effizienter ist, wäh-len wir hier die Variante y=Q[len(Q)−1]. In Zeile 10 von Algorithmus 3.1 muss ein Nachbar vony gefunden werden, der noch nicht in Z, bzw. in K liegt. Um hier nicht stets die ganze AdjazenzG[y] durchsuchen zu müssen, führen wir eine Indexliste I ein, in der wir uns für jeden Knoteny in Gmerken, welche Indizes der Adjazenz bereits untersucht wurden. Schließlich ändern wirdie Bedeutung der Liste K. Wir speichern nun nicht mehr, welche Knoten wir bereits hinzu-gefügt haben, sondern wir speichern eine Liste der Länge n=len(G), welche am Anhang stetsdenWert False hat und ändern denWert K[y]=True sobald wir einen Knoten Y hinzufügen. Diesgeschieht, da wir in Zeile 10 von Algorithmus 3.1 für jeden Knoten testen müssen, ob dieserbereits in K enthalten ist. Eine Suche würde im besten Fall O(log(n)) Operationen benötigen,im schlechtesten Fall (lineare Suche) O(n). Die direkte Abfrage K[y]==True oder K[y]==False istpotentiell effizienter.

64 ©2018 Thomas Richter

Page 71: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

{algo:tiefensuche}Algorithmus 3.2: Tiefensuche

1 def tiefensuche(G,x):

2 n = len(G) # Anzahl der Knoten

3 Z = [] # Adj.liste der Zusammenhangskomponente

4 for i in range(n):

5 Z.append([])

6 K = [False]∗n # Knoten in Zusammenhangskomponente

7 K[x] = True # Ausgangsknoten x merken

8

9 Q = [x] # Startknoten auf den Stack

10 I = [0]∗n # Positionen in Adjazenzliste speichern

11

12 while len(Q)>0:

13 y = Q[len(Q)−1] # letztes Element aus Q entnehmen

14

15 while I[y]<len(G[y]): # Suche Nachbarn z von y

16 z = G[y][I[y]]

17 if not(K[z]): # z noch nicht in Z?

18 break # Abbruch der Schleife

19 I[y]=I[y]+1 # Index hochzaehlen

20

21 if I[y]<len(G[y]): # Nachbar z gefunden

22 Z[y].append(z) # Nachbarn in Adjazenzliste Z eintragen

23 Z[z].append(y) # (gerichteter Graph)

24 K[z] = True # Knoten z merken

25 Q.append(z) # Knoten auf Stack legen

26 else: # kein weiterer Nachbar

27 Q.pop() # y von Stack entfernen

28

29 return Z,K # Rückgabe Adjazenzliste und Knotenliste

3.4.2. Breitensuche

Zur Realisierung der Breitensuche sind nur wenige Modifikationen notwendig. In Zeile 9 vonAlgorithmus 3.1 ist nun das Element zu entnehmen, welches wir zuerst in die Liste Q eingefügthaben. Dies ist natürlich ganz einfach mit dem Befehl y=Q[0] zu erledigen. Ein Problem ergibtsich in Zeile 16 der Graphdurchmusterung. Hier müsste das erste Elemente der Liste entferntwerden. Listen in Python sehen dies nicht effizient vor: um das erste Element zu entfernenmüssen wir alle weiteren Elemente kopieren, d.h. Q[0]=Q[1], Q[1]=Q[2], usw, im Anschluss dieListe verkürzen. Das Kopieren bringt einen hohen Aufwand O(n) mit sich. Stattdessen ver-wenden wir die Datenstruktur queue.

Bemerkung 3.25 (Queues in Python). Queues können in Python durch eine Bibliothek bereit gestelltwerden. In Python 3 werden die entsprechenden Funktionen mittels

1 import queue

[email protected] 65

Page 72: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

geladen, in Python 2 mit

1 import Queue

Ab hier ist die Verwendung gleich. Die wesentlichen Methoden dienen dem

• Erstellen einer Variable vom Typ queue mittels Q = queue.Queue()

• dem Hinzufügen eines Elementes x am Ende der Queue mittels Q.put(x)

• dem Entnehmen eines Elements y am Anfang der Queue mittels y=Q.get().

• der Abfrage der Länge der Queue mittels Q.qsize(), d.h. das Ermitteln der Anzahl der in derQueue gespeicherten Elemente. Man teste das folgende Programm

1 import queue # Achtung, in Python 2 import Queue

2

3 Q = queue.Queue() # Queue erstellen

4 Q.put(10)

5 Q.put(5)

6 Q.qsize()

7 Q.get()

8 Q.get()

9

10 S = [] # Stack (=Liste) erstellen

11 S.append(10)

12 S.append(5)

13 len(S)

14 S.pop()

15 S.pop()

Wir können nun die Breitensuche auf der Basis der Queue realisieren. In Zeile 7 von Algorith-mus 3.1 müssen wir das Startelement mittels Q.put(x) in die Queue einfügen. In Zeile 8 mussdie Schleife while len(Q)>0: durch while Q.qsize()>0: ersetzt werden. In Zeile 9 von wählen wirdas Element y als y=Q.get(). Diese Anwendung entfernt das Element aus der Queue Q. (Manlese hierzu auch den entsprechenden Abschnitt bei der Tiefensuche). Bei der Breitensuche istdieses Verhalten jedoch nicht schlimm. Denn: wir arbeiten mit einer Warteschlange, d.h. wirfügen in Zeile 14 einen Knoten z in dieWarteschlange Q ein und entnehmen diesen dann sofortim nächsten Durchlauf in Zeile 9 wieder. Dies können wir effizienter gestalten, in dem wir zueinem Knoten y in einer Schleife alle Nachbarn in die Warteschlange einfügen.

{algo:breitensuche}Algorithmus 3.3: Breitensuche

1 def breitensuche(G,x):

2 n = len(G) # Anzahl der Knoten

3 Z = [] # Adj.liste der Zusammenhangskomponente

4 for i in range(n):

5 Z.append([])

6 K = [False]∗n # Knoten in Zusammenhangskomponente

7 K[x] = True # Ausgangsknoten x merken

8

66 ©2018 Thomas Richter

Page 73: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

9 Q = queue.Queue() # Erstellen einer Queue

10 Q.put(x) # Startknoten

11

12 while Q.qsize()>0:

13 y = Q.get() # Erstes Element entnehmen

14

15 for z in G[y]: # Alle Nachbarn von y durchlaufen

16 if not(K[z]): # Falls Nachbar z noch nicht in Z

17 Z[y].append(z) # Nachbarn in Adjazenzliste Z eintragen

18 Z[z].append(y) # (gerichteter Graph)

19 K[z] = True # Knoten z merken

20 Q.put(z) # Knoten an Queue anhaengen

21

22 return Z,K # Rückgabe Adjazenzliste und Knotenliste

Visualisierung der Breitensuche

Wir zeigen von oben links nach unten rechts die sechs Schritte der Breitensuche vom Knotenx aus:

• Das aktuelle Suchelement y ist jeweils blau eingekreist

• Knoten, die bereits in Z sind werden gelb markiert

• Kanten in Z sind grün markiert

• Die Zahlen markieren die Reihenfolge der Element in der Queue. Der Knoten mit derjeweils kleinsten Zahl wird im nächsten Schritt als aktives Element y, d.h. als blau mar-kiertes gewählt

[email protected] 67

Page 74: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

• Dabei überspringe wir Schritte in denen es keine neue Nachbarn mehr gibt. Dies trifftauf den Knoten 2 im 3-ten Schritt sowie auf den Knoten 5 im 5ten Schritt zu.

Die Breitensuche hat eine zur Suche kürzester Wege wichtige Eigenschaft. Hierzu überlegeman sich anhand der vorherigen Abbildung, in welcher Reihenfolge neue Knoten dem BaumZ hinzugefügt werden: im ersten Schritt werden alle Knoten der Liste Q hinzugefügt, die un-mittelbar von x aus erreichbar sind. Danach werden alle diese Knoten aus y ∈ Q bearbeitetund es werden jeweils die neuen Knoten hinzugefügt, die wieder in genau einem Schritt vony aus erreichbar sind. Wir machen die folgenden Modifikationen im Algorithmus um uns ineiner Indexliste L die Abstand von x zu merken:

• Nach Zeile 2 wird eine Liste erzeugt mittels L = [−1]∗n. Der Index−1 bedeutet, dass derentsprechende Knoten nicht erreichbar ist von x

• Dann wird der Startknoten mittels L[x]=0 eingetragen. Denn der Startknoten ist unmit-telbar, ohne Weg, bzw. mit einemWeg der Länge 0 erreichbar.

• Innerhalb der if-Anweisung in Zeilen 17-20, d.h. z.B. gleich zu Beginn in Zeile 17 wirddie Liste aktualisiert mittels L[z]=L[y]+1. Denn falls die Länge von x nach y L[y] ist, so istdie Länge bis z - welche noch nicht erreicht wurde eine zusätzliche Kante.

Visualisierung der Breitensuche mit kürzesten Wegen

Zusätzlich zur vorherigen Visualisierung haben wir den Index L[] angegebenen. Anstelle desEintrags −1 lassen wir den Index frei, falls der entsprechenden Knoten (noch) nicht erreichtwurde.

Satz 3.26 (Breitensuche). Der durch Breitensuche ausgehend von x ∈ V erzeugte Baum Z = (V ′,E ′)enthält einen kürzesten Weg von Knoten x ∈ V ′ zu allen anderen, von x aus erreichbaren Knoteny ∈ V ′. Die Länge des Weges dist(x,y) kann in linearer Laufzeit bestimmt werden.

68 ©2018 Thomas Richter

Page 75: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.4. Zusammenhang

Beweis. DieAbbildung zeigt die Schwierigkeit des Beweises.Wir betrachten z.B. denWeg P imGraphen G vom Knoten x bis zum Knoten, der in der mittleren Abbildung der unteren Reihemit der Nummer 8 gekennzeichnet ist. Zu diesem Knoten gibt es im GraphenG zwei kürzesteWege, jeweils bestehend aus 3 Kanten; einer geht über den mit 6 gekennzeichneten Knoten,einer über den Knoten 7. Der Beweis kann also nicht auf dem Prinzip “Der kürzeste Weg zwi-schen Knoten x und y in G verläuft auch in Z”. Nur einer der möglicherweise uneindeutigenkürzesten Wege geht durch Z.

Der Beweis wird als Widerspruchsbeweis geführt. Angenommen, es gäbe zwei Knoten x,y ∈Z ⊂ V mit

distG(x,y) < distZ(x,y). (3.4) {kw:1}{kw:1}

Der Weg in Z hab die Knoten P = (x0, x1, . . . , xn).

Da Z = (V ′,E ′) mit V ′ ⊂ V und E ′ ⊂ E ein Teilgraph von G ist, so liegt der Weg P natürlichauch in G. Somit gilt stets

distG(x,y) 6 distZ(x,y),

da es gegebenenfalls noch kürzere Wege in G gibt.

Angenommen xk sei der erste Knoten im Weg P mit der Eigenschaft

distG(x, xk) = distZ(x, xk) aber distG(x, xk+1) < distZ(x, xk+1). (3.5) {kw:ws}{kw:ws}

So ein Knoten muss existieren, wenn Bedingung (3.4) gelten soll. Wir können ohne Einschrän-kung annehmen, dass y = xk+1.

Für xk gilt somitdistG(x, xk) = distZ(x, xk).

Weiter gilt distZ(x, xk+1) = distZ(x, xk) + distZ(xk, xk+1) = distZ(x, xk) + 1, da der Weg Pein kürzester Weg in Z ist. Annahme (3.5) bedeutet dann

distG(x, xk+1) < distZ(x, xk+1) = distZ(x, xk) + 1 = distG(x, xk) + 1, (3.6) {kw:ws1}{kw:ws1}

also müsste distG(x, xk+1) 6 distG(x, xk) sein.

Im modifizierten Algorithmus gibt es einen Zustand, in dem der Knoten xk der Queue Q hin-zugefügt wird und einen Index L[xk]= distG(x, xk) = distZ(x, xk) erhält.

Da Knoten xk nun in der Queue Q liegt, wird dieser einmal in Zeile 13 entnommen y=Q.get()=↪→ xk. ImAnschluss werden in den Zielen 15-20 alle Nachbarn z von y=xk betrachtet, d.h. auchder gesuchte Knoten z=xk+1.

Angenommen dieser Knoten z=xk+1 sei bisher noch nie besucht, also K[xk+1]==False in Zeile16. So wird dieser Hinzugefügt und die Länge als L[xk+1]=L[xk]+1 im Widerspruch zu (3.6)bestimmt.

Nun angenommen, es gelte K[xk+1]==True. Dieses bedeutet, dass der Knoten xk+1 bereits be-sucht wurde. Somit hat dieser ist diesem Knoten auch schon eine Länge zugeordnet. Da diesvorher geschehen ist, also nicht vomKnoten xk ausmuss dann L[xk+1]<=L[xk]+1 gelten,wiederim Widerspruch zu (3.6).

[email protected] 69

Page 76: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.5. Suche nach kürzesten Wegen

3.5. Suche nach kürzesten Wegen

Die Breitensuche durchmustert einen GraphenG = (V,E) und findet so die Zusammenhangs-komponenten. Ausgehend von einemKnoten x ∈ V wird ein Baum aufgespannt, der von x ausdie Wege mit der kleinsten Kantenanzahl zu allen erreichbaren Knoten y ∈ V erhält. DiesesErgebnis scheint schon nahe an demProblemder Routenplanung zu sein: suche den kürzesten(oder schnellsten, oder schönsten) Weg von Köln an den Tegernsee. Alle Kanten haben jedochdie gleicheWertigkeit. Übertragen auf die Routenplanung bedeutet dies, dass alle Abschnitte,z.B. zwischenAutobahnausfahrten die gleicheWertigkeit besitzen, unabhängig von der Längeder Strecke, oder der zugelassenen Höchstgeschwindigkeit.

Wir führen hierzu gewichtete Graphen ein, um den Knoten und Kanten Gewichtsfunktionenzuzuordnen.

Definition 3.27 (GewichteterGraph). EinQuadrupelG = (V,E, fV , fE) bestehend aus KnotenV ⊂N, Kanten E ⊂ V × V sowie zwei Gewichtsfunktion fV : V → R und FE : E→ R heißt gewichteterGraph. Oft betrachtet man auch TripelG = (V,E, fE) oderG = (V,E, fV)mit ausschließlich Kanten-oder Knotengewichten.

DieUnterscheidung zwischen gerichteten undungerichtetenGraphen, vollständigenGraphen,Bäumen und Wäldern wird durch das zusätzliche Gewicht nicht geändert.

Zur Speicherung von gewichteten Graphen werden zusätzlich zur Adjazenzliste die Gewichts-listen gespeichert. Ein Beispiel:

Algorithmus 3.4: Darstellung eines gewichteten Graphen1 # Adjazenzliste mit 9 Knoten

2 Z=[[1,2,3],[0,5,6],[0,9],[0,5],[5,7],[1,3,4,8],[1,8,9],[4,8],[5,6,7],[2,6]]

3 # Liste von Kantengewichten − in der Ordnung der Adjazenz

4 fE=[[3,3,2],[3,9,8],[3,2],[2,5],[5,2],[9,5,5,5],[8,1,8],[2,6],[5,1,6],[2,1]]

5 # Liste der Knotengewichte (nicht in der Abbildung)

6 fV=[1.2,2.0,−0.5,1.2,1.6,−0.8,0.5,3,1,0.5]7

8 print(’Knoten 1 hat Kante zu Knoten’,Z[1][0],’mit Kantengewicht’,fE[1][0])

9 print(’Knoten 1 hat Gewicht’,fV[1])

10 print(’Knoten’,Z[1][0],’hat Gewicht’,fV[Z[1][0]])

70 ©2018 Thomas Richter

Page 77: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.5. Suche nach kürzesten Wegen

{def:kweg}Definition 3.28 (Kürzester Weg). Gegebensei ein gewichteter Graph G = (V,E, fE) (mitKantengewichten) sowie zwei Knoten x,y ∈V . Gesucht ist der Weg P = (V ′,E ′, fW) ⊂ G

P := (V ′,E ′) =

({x = x0, . . . , xk = y}, {e1, . . . , ek})

mit kleinstem summierten Kantengewicht∑e∈P

fW(e)→ min!

Wir suchen z.B. den kürzesten Weg vonKnoten 0 nach Knoten 8. 3

3

5

6

1

2

9

5

5

8

2

2

03

1

5

4

6

7

8

9

2

1

Bemerkung 3.29 (Kreise mit negativemGewicht). Kantengewichte fW(e) können im Allgemeinennegativ oder positiv sein. Wir beschränken uns hier auf den einfachen Fall von ausschließlich positivenKantengewichten fW : E → R>0. Angenommen, ein Graph (mit auch negativen Kantengewichten)hätte einen Kreis mit negativer Kantengewichtsumme. Durch mehrfaches durchlaufen dieses Kreiseskönnen wir Wege mit beliebig kleiner Gewichtssumme erzeugen. Dieses Beispiel ist extrem, es zeigtjedoch bereits, dass dieser allgemeine Fall schwerer ist.

3.5.1. Dijkstra’s Algorithmus

Bei der Suche nach kürzesten Wegen haben wir Landkarten vor Augen. Diese beinhalten zu-sätzlich zu den Knoten und Kanten - also Städten und Bahnlinien - auch geometrische In-formationen, die uns beim Problem stark helfen: Wollen wir von Hamburg nach Kiel fahren,so werden wir nicht in einen Zug nach Berlin oder Hannover steigen. Wir suchen hier nacheinfachen Algorithmen, die ohne solche Zusatzinformationen auskommen.

Starten wir in einem Punkt x ∈ V , so könnenwir also nicht zielgerichtet in Richtung y ∈ V los-legen sondern werden den Graphen - ähnlich der Durchmusterung - allgemein durchlaufen.Hierbei werden wir für alle Knoten xk ∈ V jeweils kürzesteWege von x berechnen. Treffenwirbei dieser Suche auf den Knoten y, so sind wir fertig.

Der Algorithmus zur Breitensuche bildet eine gute Grundlage. Er würde das kürzeste-Wege-Problem lösen, wenn alle Kanten die Gewichte fE ≡ 1 hätten. Von einem Knoten x ∈ G =(V,E) aus wird ein Baum Z = (V ′,E ′) erzeugt, der die kürzesten Wege - gerechnet in derAnzahl der Kanten - zu allen erreichbaren Knoten y erhält. Dabei geht die Breitensuche fol-gendermaßen vor:

• Wir beginnen mit dem Startknoten x und fügen diesen in den Ergebnisbaum ein Z.

[email protected] 71

Page 78: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.5. Suche nach kürzesten Wegen

• Dieser Baum Zwird Schritt für Schritt um alle Knoten aus V erweitert, die noch nicht inZ sind, aber von einem Knoten aus Z erreicht werden können.

• So kann sichergestellt werden, dass im i-ten Schritt genau die Knoten hinzugefügt wer-den, die in mindestens i Schritten von x aus erreichbar sind.

• Wird ein Knoten z angetroffen der bereits in Z enthalten. ist, so muss er kein zweites malberücksichtigt werden. Denn der erste Weg zu z ist entweder kürzer oder aber genausolang. Ist er genauso lang, so ist es nicht wichtig, welcher Weg gespeichert wird.

Der letzte Punkt wird durch die Wahl der queue zur Realisierung von Q in der Breitensuchesichergestellt. Es ist auch der entscheidende Punkt, der die Breitensuche von der Suche nachkürzestenWegen in gewichtetenGraphen unterscheidet. Es kann durchaus sein, dass von zweiWegen von x nach y derjenigemit der kleineren Kantenanzahl dermit dem größeremGesamt-gewicht ist. In der Abbildung zu Definition 3.28 betrachte man z.B. die Wege 0

3−→ 19−→ 5

5−→ 8

mit Gesamtgewicht 3+9+5 = 17 sowie 03−→ 2

2−→ 91−→ 6

1−→ 8mit 4 Kanten aber dem geringerenGesamtgewicht 3 + 2 + 1 + 1 = 7.

Die notwendigen Änderungen sind nicht sehr umfangreich: Wir fügen einen Knoten v erstdann zum Ergebnisgraphen Z hinzu, wenn wir uns sicher sind, dass wir v nicht - auf einemanderenWeg - schneller erreichen können.Umdies zu erreichen arbeitenwirmit 2 temporärenListen: Q ist nach wie vor die Suchliste aller Knoten, die wir bereits erreicht haben und vondenen wir noch weitere Knoten suchen werden. Sobald ein Knoten w der Liste Q hinzugefügtwird, so speichern wir in L[w] die Länge des bisher schnellsten Weges. Wird w ein zweitesmal gefunden, z.b. mittels einer Kante (v,w), so speichern wir nur den schnelleren Weg undmerken uns die Kante (v,w), indem wir den Wert P[w]=v merken, d.h. wir speichern, von woaus wir nach w gelangt sind.

Ein Knoten wird erst dann endgültig dem Ergebnisgraphen R hinzugefügt, wenn der Knotenselbst der Liste Q entnommen wird.

Ein Algorithmus zum Lösen des Problems (bei positiven Kantengewichten) heißt Dijkstra’sAlgorithmus.

72 ©2018 Thomas Richter

Page 79: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.5. Suche nach kürzesten Wegen

Algorithmus 3.5: Dijkstra’s AlgorithmusGegeben ein gewichteter Graph G = (V,E, fW) sowie ein Knoten x ∈ V

1 # Eingabe: Adjazenzliste G sowie Kantengewichte fE.

2 # Startknoten x sowie Ziel y

3 def dijkstra(G,fE,x,y):

4 n=len(G) # Anzahl der Knoten

5 Z = [] # Erzeuge leere Liste fuer Ergebnis

6 for i in range(n):

7 Z.append([])

8

9 Q=[x] # Temporaere Liste

10 R=[False]∗n # weitere temp. Liste

11

12 L=[−1]∗n # Laenge zu allen Knoten

13 L[x]=0

14

15 P=[−1]∗n # Speichert den Weg rueckwaerts

16

17 while len(Q)>0:

18 wahle v aus Q mit L[v] minimal

19 Q.remove(v)

20 R[v]=True

21

22 for j in range(len(G[v])): # Nachbarn von v durchlaufen

23 if not(R[G[v][j]]): # j−ter Nachbar noch nicht bearbeitet24 w=G[v][j]

25 lw=L[v]+fW[v][j] # Weglaenge zu w

26 if (L[w]<0) or (lw<L[w]): # neuer Weg kuerzer?

27 L[w]=lw # neue Weglaenge merken

28 Q.append(w) # von w aus weitersuchen

29 P[w]=v # Merke den Rueckweg von w nach v

Der Algorithmus erzeugt einen gerichteten Graphen (R, T), der zu jedem Knoten v ∈ R denkürzesten Weg beinhaltet. Der Graph ist eine sogenannte Arboreszenz. Eine Arboreszenz ist einzusammenhängendes Branching. Dabei ist ein Branching ein gerichteter Graph, dessen zugehö-riger ungerichteter Graph ein Wald ist (Kreisfrei) und für den jeder Knoten nur eine einzelneeingehende Kante besitzt. Was ist wichtig für uns? Zu jedem Knoten v ∈ R \ {x} gibt es nureine Kante e ∈ T mit e = (v ′, x). Wollen wir nun den kürzesten Weg von x nach y bestimmen,so durchlaufen wir die entsprechenden Kanten von y aus einfach rückwärts. Suchen wir nurden Weg von x nach y so kann der Algorithmus abgebrochen werden, falls in Zeile 18 v = y

gilt.

Zeile 18 ist noch nicht ausformuliert. Hier unterscheidet sich Dijkstra von den beiden anderenVarianten der Durchmusterung, also Tiefensuche oder Breitensuche. Nicht die Reihenfolgeentscheidet, wo es weitergeht, sondern die bisherigen Gewichte. Knoten v in Q die schnell er-reicht sind, also geringe Werte von L[v] besitzen, sind gute Kandidaten für die weitere Suche.Für eine praktische Umsetzung von Dijkstra’s Algorithmus muss diese Zeile effizient imple-mentiert werden. Es bietet sich an, dass die Liste Q gleich sortiert gespeichert wird, so dass

[email protected] 73

Page 80: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

3.5. Suche nach kürzesten Wegen

immer v=Q[0] gewählt werden kann. Wir können z.B. Zeile 18 im Algorithmus durch v=Q[0]und Zeile 28 im Algorithmus durch den Aufruf knoten_einfuegen(Q,L,w) ersetzt werden, mitder Funktion:

1 def knoten_einfuegen(Q,L,w):

2 index = 0

3 while (index<len(Q)) and (L[Q[index]]<L[w]):

4 index = index+1

5 Q.insert(index,w)

Wir bemerken, dass diese Realisierung nicht optimal ist. Das Einfügen hat im Durchschnittdie Laufzeit O(n). Die Methode kann aber einfach verbessert werden indem z.B. das Prin-zip der logarithmischen Suche verwendet wird um den Index index zu bestimmen, an demdas gesuchte Element einzufügen ist. So sinkt der Aufwand zum Einfügen in die Liste Q aufO(log2(n)).

Satz 3.30 (Dijkstr’as Algorithmus). Der Dijkstra Algorithmus löst das kürzeste-Wege-Problem.Der Algorithmus kann in

O(|V |2 + |E|)

Operationen durchgeführt werden.

Beweis. Der Beweis der Korrektheit, dass also kürzesteWege von x ∈ V zu jedem erreichbarenKnoten y ∈ V gefunden werden findet sich z.B. in Hougardy & Vygen [5].

Wir gehen kurz auf den Aufwand ein. Wir speichern Q und R in Listen. R[v] hat den Wert Trueoder False, die Überprüfung ist somit in einem Schritt möglich.

Die while-Schleife wird höchstens |V | mal durchgeführt, da nur |V | Knoten der Menge Q hin-zugefügt werden können. Wird einmal v in Q betrachtet, so wird der Knoten v der Liste auchentnommen und niewieder hinzugefügt. Jeder Knoten kann also nur einmal durchlaufenwer-den.

In jedem Durchgang werden die folgenden Schritte durchgeführt:

• Suche des Elements v in Q mit L[v] minimal. Bei Speicherung von Q als Liste kann diesin O(|Q|) = O(|V |) Operationen erfolgen (dies ist nicht effizient und geht schneller).

• Löschen von v ∈ Q erfordert bei einer Liste das Suchen (bereits erfolgt), ein Kopierendes letzten Elements an die Stelle von v und ein Verkürzen, somit O(1) Operationen.

• Hinzufügen von v in R erfolgt in O(1) Operationen.

• Ebenso benötigt die Abfrage w 6∈ R in Zeile 23 nur O(1) Operationen

• In Zeile 22werden alle Kanten von v aus durchlaufen. Da dieser Schritt maximal für alleKnoten des Graphen durchlaufen wird wird die innere Schleife 24-29 somit maximalO(|E|)mal durchlaufen. Die Schritte 24-29 können jeweils in O(1)Operationen durchge-führt werden.

Insgesamt ergibt sich somit der Aufwand O(|V |2 + |E|).

74 ©2018 Thomas Richter

Page 81: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Teil II.

Approximation

75

Page 82: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude
Page 83: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

4. Exkurs: Einführung in numpy

Eine der Stärken von Python ist der unkomplizierte Umgang mit Variablen und Datentypen.Vieles geschieht jedoch im Verborgenen. Man teste das folgende Programm, möglichst in Py-thon 2 und in Python 3.

1 def fak(i):

2 f = i;

3 while (i>2):

4 f=f∗(i−1)5 i=i−16 print(type(i),f,type(f))

7

8 fak(5)

9 fak(20)

10 fak(200)

Pyhon ist jeweils in der Lage die Fakultät zu berechnen, auch die große Zahl

200=7886578673647905035523632139321850622951359776871732632947425332443594499634

0334292030428401198462390417721213891963883025764279024263710506192662495282

9931113462857270763317237396988943922445621451664240254033291864131227428294

8532775242424075739032403212574055795686602260319041703240623517008587961789

22222789623703897374720000000000000000000000000000000000000000000000000

Aber Versionen 2 und 3 von Python zeigen einen Unterschied im Variablentypen. In Python 2hat die Variable i stets den Typ int, die Ausgabe f jedoch in Abhängigkeit von der Größe denTyp int oder long. Der Datentyp int ist ein üblicher Datentyp in vielen Programmiersprachenund stellt eine ganze Zahl mit 32 Bits da. Es können Werte im Bereich

<int> = {−2−31,−2−31 + 1, . . . ,−1, 0, 1, . . . , 231 − 1}

dargestellt werden. Sobald dieser Bereich überschritten wird schaltet Python auf den Daten-typ long um. Dieser kann prinzipiell beliebig lange Zahlen darstellen. Die maximale Größewird nur durch den zur Verfügung stehenden Speicher begrenzt. Auch wenn dieses Verhaltensehr praktisch sein kann, wie z.B. bei der Berechnung der Fakultät nimmt, es ein wenig dieKontrolle über den Programmablauf. Denn auch wenn der Übergang fließend ist, so ändertsich die interne Arithmethik. Das folgende kleine Programm führt nacheinander Rechnungendurch und misst jeweils für 1 000 000 Additionen ganzer Zahlen die notwendige Zeit. Dabeisteigt die Größe der Zahlen von Durchgang zu Durchgang an.

77

Page 84: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

0.23

0.24

0.25

0.26

0.27

0.28

0.29

0.3

0.31

0.32

0.33

100 200 300 400 500 600

Zei

t pro

100

0000

Add

ition

en

Anzahl der Stellen

Abbildung 4.1.: Aufwand zurAddition von 1 000 000 großer Zahlen in Python inAbhängigkeitder Anzahl der Stellen.{numpy:aufwandint}

1 import time

2 import math

3

4 f = 1

5 s = 1

6

7 for j in range(100):

8 t1 = time.clock()

9 for i in range(1000000):

10 f = f + s

11 t2 = time.clock()

12

13 # Ausgabe von Zeitaufwand vs. Anzahl der Stellen

14 # Die Anzahl der Stellen einer Zahl f ergibt sich

15 # als 10er−Logarithmus der Zahl f16

17 print(math.log(f)/math.log(10),t2−t1)18 s = s∗1000000

Mit der Länge der Zahlen wächst auch der Aufwand. Wir tragen in Abbildung 4.1 den Zeit-aufwand für jeweils 1 000 000 Additionen gegenüber der Anzahl der Stellen im Ergebnis auf.Es zeigt sich etwa lineares Wachstum.

Man wiederhole nun die Berechnung der Fakultät, jedoch mit den Eingaben

1 fak(5.)

2 fak(20.)

3 fak(200.)

78 ©2018 Thomas Richter

Page 85: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

also jeweilsmit einemPunkt, kurz für 5.0. Hiermit gebenwir Python an, dasswirmit Fließkom-mazahlen rechnen wollen und nicht mehr mit ganzen Zahlen. Wie ändert sich das Ergebnis?Die Fakultät von 5 wird auch jetzt korrekt berechnet. Auch die Fakultät von 20 stimmt in denStellen die Python anzeigt in beiden Fällen überein. Bei der Fakultät von 200.0 liefert Pythonjedoch das Ergebnis inf, infinity für∞. Das Ergebnis ist größer als der zulässige Zahlenbereichfür Fließkommazahlen vom Typ float. Bei Rechnenmit Fließkommazahlen verwendet Pythoneinen festen Typen und wechselt nicht intern die Darstellung.

Mischen wir in Rechnungen jedoch Zahlen vom Typ int (oder long) mit Zahlen vom Typ floatist Vorsicht geboten. Die folgende Funktion soll die Partialsummen der harmonischen Reiheberechnen.

1 def hr(i):

2 s = 0

3 for j in range(1,i+1):

4 s = s + 1/j

5 return s

Der Aufruf von print(hr(10)) liefert - je nach Python-Version - unterschiedliche Ergebnisse.Python 2 gibt die Zahl 1 zurück, Python 3 den korrekten, aber natürlich gerundeten Wert2.9289682539682538. Python 2 geht davon aus, dass die wesentliche Rechnung in Zeile 4 mitganzen Zahlen durchgeführt wird. Dann ist 1/1 = 1 aber 1/j = 0 für alle Zahlen j > 1. Einstets korrektes Ergebnis wird erreicht, wenn wir diese Anwendung durch s = s + 1.0/j erset-zen und Python hiermit darauf hinweisen, dass die Division mit Fließkommazahlen durchzu-führen ist. Die ganzzahlige Division sollte in Python immer mittels a//b durchgeführt werden.

In vielen Programmen haben wir Listen als Datentyp eingesetzt. Mit doppelten Listenstruk-turen können wir auch Matrizen darstellen, z.B.:

1 N = 10

2

3 # erzeuge Nullmatrix der Groesse NxN

4 A = [[]]∗N5 for j in range(N):

6 A[j]=[0]∗N7

8 # Initialisiere Hilbert−Matrix9 for i in range(N):

10 for j in range(N):

11 A[i][j] = 1.0/(1.0+i+j)

Dies ist praktisch, kann aber von Python nicht effizient umgesetzt werden. Dafür ist der TypListe zu allgemein. Jede Liste kann eine unterschiedliche Anzahl von Elementen besitzen undjeder Eintrag kann einem anderen Typen angehören.

[email protected] 79

Page 86: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Wir werden im Folgenden oft die Bibliothek numpy einsetzen. Die wichtigste Struktur in numpydas array zum Speichern von Vektoren und Matrizen.

1 # Der Zusatz äs np" bedeutet, dass wir numpy Befehle,

2 # z.B. array über das Kürzel np.array() aufrufen können

3 import numpy as np

4

5 X = np.array([[3 , 2, 1],

6 [−1, 3, −3],7 [2 , −1, 1]])

8

9 v = np.array([1, 2, 3])

10

11 print(X)

12 print(v)

Es ist üblich, die Bibliothek numpymittels import numpy as np zu importieren. Auf die einzelnenFunktionen kann dann mit dem Kürzel np zugegriffen werden. Zwischen Listen und numpy−↪→ array’s gibt es einige wesentliche Unterschiede:

1. Die Größe eines arrays ist fest. Das stimmt nicht exakt, wir gehen aber zunächst davon aus,dass eine einmal gewählte Größe erhalten bleibt und nicht geändert werden kann.

2. Ein array hat einen festen Datentyp. Man teste das folgende Programm

1 import numpy as np

2

3 v = np.array([1, 2, 3])

4

5 for i in range(10):

6 v = v∗v7 print(v)

Der Befehlt v∗v ist eine komponentenweise Multiplikation des Vektors, d.h.

(v∗v)i = vi ∗ vi

Das Ergebnis unterscheidet sich von dem üblichen Datentyp int. In der Tat liefert type(v[0])den Typ numpy.int64. Dies ist eine ganze Zahl im Bereich

{−263, . . . , 263 − 1} = {−9223372036854775808, 9223372036854775807}.

Ist dieser Bereich überschritten, so geht es ohne Fehlermeldung bei den negativen Zahlen wei-ter.

3. Vielleicht der wichtigste Punkt ist, dass sämtliche Methoden der Bibliothek numpy sehr effi-zient in der Programmiersprache C++ geschrieben sind. Hierdurch ist teils extreme Beschleu-nigung des Programmablaufs möglich.

Wollen wir mit numpy mit Fließkommazahlen rechnen, so müssen wir bei der Initialisierungdes array’s bereits auf den richtigen Typ achten. Geben wir Zahlen vor, so geschieht dies z.B.mittels

80 ©2018 Thomas Richter

Page 87: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

1 v = np.array([1.0, 2.0, 3.0])

oder aber durch Angabe des Datentypen

1 v = np.array([1, 2, 3],dtype=np.float32)

Man wiederhole wieder das mehrfache quadrieren der Vektoreinträge.

Einige wichtige Datentypen in numpy sind

• np.int8 Ein sogenanntes Byte, eine ganze Zahl im Bereich {−128, . . . , 127}

• np.int16 Ein sogenanntesWord, eine ganze Zahl im Bereich {−32768, . . . , 32767}

• np.int32 Eine eine ganze Zahl im Bereich {−2−31, . . . , 231 − 1}

• np.int64 Eine eine ganze Zahl im Bereich {−2−63, . . . , 263 − 1}

• np.uint8 Ein sogenanntes Byte, eine natürliche Zahl im Bereich {0, . . . , 256}

• np.uint16 Ein sogenanntes Word, eine natürliche Zahl im Bereich {0, . . . , 65535}

• np.uint32 Eine eine natürliche Zahl im Bereich {0, . . . , 232 − 1}

• np.uint64 Eine eine natürliche Zahl im Bereich {0, . . . , 264 − 1}

• np.float16 Ein Fließkommazahl mit halber Genauigkeit

• np.float32 Ein Fließkommazahl mit einfacher Genauigkeit

• np.float64 Ein Fließkommazahl mit doppelter Genauigkeit

ZurManipulation von Vektoren undMatrizen stehen in numpy viele Befehle zur Verfügung, diewir im Folgenden nutzen werden. Wir beginnen mit dem Zugriff auf Elemente eines array’s

1 import numpy as np

2

3 A = np.array([ [1 , −2, 1],

4 [2 , 1, −2],5 [2, −4, −1] ],dtype=np.float32)6

7 print(A) # Zugriff auf die Komplette Matrix / Vektor

8

9 print(A[1,2]) # Zugriff auf ein Element. Zeilenindex dann Spaltenindex

10

11 print(A[:,1]) # Zugriff auf Spalte Nr. 1 (also 2te Spalte)

12

13 print(A[2,:]) # Zugriff auf Zeile Nr. 2 (3te, also letzte Spalte)

14

15 # Zugriff auf Teilmatrix

16 # A_{ij} mit 1 <= i < 3

17 # und 0 <= j < 2

18 print(A[1:3,0:2]) # Zugriff auf Teilmatrix

[email protected] 81

Page 88: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Weiter ist es einfach, mit array’s zu rechnen. Auch hierzu Beispiele:

1 import numpy as np

2

3 A = np.array([ [1 , −2, 1], [2 , 1, −2], [2, −4, −1] ],dtype=np.float32)4 B = np.array([ [5 , 2, −1], [0 , −1, 0], [3, 2, 1] ],dtype=np.float32)

5 u = np.array([2, 1,−2],dtype=np.float32)6 v = np.array([1, 2, 3],dtype=np.float32)

7

8 # Addition zweier array’s gleicher Groesse

9 print(u+v)

10 print(A+B)

11

12 # Transponieren eines matrix−arrays13 print(A.T)

14

15 # Transponieren von Vektor−Arrays hat keinen Effekt16 print(v.T)

17

18 # Addition eines Vektors zu jeder Zeile einer Matrix

19 # dies Funktioniert nur bei n x m − Matrizen und Vektoren

20 # der Laenge m

21 print(A+v)

22

23 # Multiplikation mit einem Skalar

24 print(3∗A)25 print(2∗v+u)26

27 # Eintrags−Weise Multiplikation28 # Dies ist keine Matrix−Matrix−Multiplikation und kein Skalarprodukt!29 print(A∗B)30 print(v∗u)31

32 # Zeilenweise Eintragsweise Multiplikation von Matrix und Vektor

33 # Dies ist kein Matrix−Vektor Produkt!34 print(A∗v)35

36 # Matrix−Matrix Produkt und Matrix−Vektor Produkt37 print( np.dot(A,B) )

38 print( np.dot(B,u) )

Diese Befehl können alle auch mit der Bereichs-Selektion kombiniert werden, z.B.

1 # Fortsetzung...

2

3 # Elementweises Produkt aus Teilbloecken

4 print( A[1:3,0:2] ∗ B[0:2,0:2] )5

6 # Matrix−Vektor Produkt mit Zeilenvektor

82 ©2018 Thomas Richter

Page 89: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7 print( np.dot(A, B[:,2]) )

8

9 # Bei vektoren wird nicht zwischen Zeilenvektoren

10 # und Spaltenvektoren unterschieden

11 print( np.dot(A, B[1,:]) )

Für das Matrix-Matrix Produkt, bzw. für die Matrix-Vektor Multiplikation gibt es statt demnp.dot Befehl eine kurze Form, A@B, bzw A@v.

Um die Leistungsfähigkeit zu beurteilen teste man das folgende Programm, welches eine An-zahl von Matrix-Vektor Multiplikationen auf der Basis von doppelten Listen ausführt:

1 import time

2

3 def init_matrix(n): # Erstellt eine n ∗ n − Hilbertmatrix

4 A = [[]]∗n5 for i in range(n):

6 A[i] = [0] ∗ n7

8 for i in range(n): # Mit Werten fuellen (Hilbert−Matrix)9 for j in range(n):

10 A[i][j] = 1.0/(1.0+i+j)

11 return A

12

13 def init_vector(n): # Erstellt einen Vektor der Laenge n

14 x = [0] ∗ n15 for i in range(n):

16 x[i] = 1.0∗i17 return x

18

19 def vmult(A,x): # Matrix−Vektor Produkt20 n = len(x)

21 y = [0]∗n # Ergebnisvektor22 for i in range(n):

23 for j in range(n):

24 y[i] = y[i] + A[i][j] ∗ x[j]25 return y

26

27 for n in [10,20,40,80,160]:

28 A = init_matrix(n) # Matrix erstellen

29 x = init_vector(n) # Vektor erstellen

30

31 t1 = time.clock()

32 for ex in range(1000): # 1000 Produkte berechnen

33 y = vmult(A,x)

34 t2 = time.clock()

35 print(’Die Berechnung fuer n=%d hat %f Sekunden genauert’ % (n,t2−t1))

[email protected] 83

Page 90: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Bei doppelte Matrixgröße vervierfacht sich die Zeit, der Algorithmus ist also wie erwartetO(n2). Wir wiederholen das Programm auf der Basis von numpy

1 import numpy as np

2 import time

3

4 def init_matrix(n): # Erstellt eine n ∗ n − Hilbertmatrix

5 A = np.zeros( (n,n) ) # leere n ∗ n − Matrix

6 for i in range(n): # fuellen

7 for j in range(n):

8 A[i,j] = 1.0/(1.0+i+j) # Bei numpy [i,j] statt [i][j] !!!

9 return A

10

11 def init_vector(n): # Erstellt einen Vektor der Laenge n

12 x = np.arange(0,n) # kurz fuer 0,1,2,...,(n−1)13 return x

14

15 for n in [10,20,40,80,160]:

16 A = init_matrix(n) # Matrix erstellen

17 x = init_vector(n) # Vektor erstellen

18

19 t1 = time.clock()

20 for ex in range(1000): # 1000 Produkte berechnen

21 y = A@x

22 t2 = time.clock()

23 print(’Die Berechnung fuer n=%d hat %f Sekunden genauert’ % (n,t2−t1))

Das Programm ist weitaus schneller. Vergrößert man die Matrizen, so sieht man wieder dasVerhalten O(n2) jedoch mit einer viel kleineren Konstante.

84 ©2018 Thomas Richter

Page 91: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5. Approximation und Fehler in derAlgorithmischen Mathematik

Bisher sind wir stets davon ausgegangen, dass der Computer - bei korrekter Umsetzung - ex-akt arbeitet. Ist ein Algorithmus als korrekt bewiesen, so wird er auch korrekt ausgeführt.Im Folgenden befassen wir uns mit Problemen, die in ihrer algorithmischen Umsetzung imAllgemeinen nur approximiert werden können. Der wesentliche Grund liegt in den reellenZahlen R, welche wir nun hauptsächlich betrachten werden. Zahlen wie

√2 lassen sich nicht

in endlicher Dezimaldarstellung schreiben - und auch nicht in der Darstellung zu einem an-deren Exponenten als 10. Ein Computer kann sie somit auch nicht mit endlichem Aufwandspeichern. Es entsteht somit zwangsläufig einDarstellungsfehler. Und dieser Fehler wiederholtsich mit jeder Operation, da ja auch z.B. die Summe zweier Zahlen z = x+ y nicht darstellbarist, so dass ein weiterer Fehler hinzukommt.

Die Grundlage für die folgenden Abschnitte ist das Buch Einführung in die Numerische Mathe-matik: Begriffe, Konzepte und zahlreiche Anwendungsbeispiele [11], welches in der Uni-Bibliothekals Online-Version frei verfügbar ist.

Im Rahmen der Vorlesung Algorithmischen Mathematik werden insbesondere die folgendenAbschnitte eine Rolle spielen

• Fehleranalyse, Kondition und Stabilität in Abschnitten 1.2-1.5

• Lineare Gleichungssysteme in Abschnitten 3.1-3.3

• Nullstellenbestimmung in 1D aus den Abschnitten 6.1-6.3

5.1. Zahldarstellung und Fehler

Computer Speichern Zahlen im Binärformat, d.h. statt den Ziffern {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ste-hen die Ziffern {0, 1} zur Verfügung grob gesagt, wird eine ganze Zahl z ∈ Z auf dem Compu-ter gespeichert als

z = [±bn−1bn−2 . . .b0]2 = ±n−1∑i=0

2ibi, bi ∈ {0, 1}

d.h. mit einem Vorzeichen, sowie mit n Ziffern b0, . . . ,bn−1. Verschiedene konkrete Datenfor-men auf demComputer unterscheiden sich in der Anzahl der Stellen sowie in der Darstellungdes Vorzeichens. Ein üblicher Datentyp int hat z.B. insgesamt 32 Bits und kann Zahlen imBereich

[−231, 231 − 1] = [−2 147 483 648,−2 147 483 647]

85

Page 92: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

darstellen. Eine ganze Zahl kann somit exakt dargestellt werden, falls sie den zulässigen Wer-tebereich nicht übersteigt. In Python steht ein weiterer Datentyp long zur Verfügung. Dieserkann prinzipiell (natürlich gibt es eine Speicherbegrenzung) beliebig große Zahlen darstellen.Wird der Wertebereich von int überschritten, z.B. durch x=2∗∗30 ∗ 10, so wird automatisch einWert vom Typ long erzeugt. Als Nutzermerkt man dies nur indirekt, z.B. durch eine reduzierteGeschwindigkeit in der Ausführung. Im Vergleich zu denmeisten anderen Programmierspra-chen ist dieses Verhalten unüblich.

Reelle Zahlen haben oft überhaupt keine endlich Darstellung - auch wenn die Zahlen be-schränkt sind. Etwa bricht die Dezimaldarstellung von

√2 = 1.414213562 . . .

nicht ab. Die Zahl lässt sich somit nicht in endlicher Stellenzahl (weder im 10er noch in einemanderen System) darstellen. Der Computer muss somit zwangsläufig approximieren und eskommt zu einemDarstellungsfehler. Vereinfacht ausgedrückt approximiert ein Computer reelleZahlen in einer Binärdarstellung mit Vor- und Nachkommastellen, also

x = [±bn−1bn−2 . . .b0.b−1b−2 . . .b−m]2 = ±n−1∑i=−m

2ibi, bi ∈ {0, 1}.

Die genaue Darstellung - im sogenannten IEEE 754-Format - ist komplizierter und verwendeteine Darstellung mit Mantisse - dies sind die eigentlichen Stellen in der Form 0.b1b2b3 . . . -und Exponent zur Speicher der Größe in Form einer Zweierpotenz. Details finden sich in [11,Abschnitt 1.4]. Wichtig ist, dass demComputer stets nur eine beschränkte Zahl von Stellen zurSpeicherung von Zahlen zur Verfügung steht. Zahlen die zu nahe beieinander liegen könnennicht unterschieden werden. Man teste das folgende Programm

1 x = 1000000000

2 if x == x+1/x:

3 print(’Der Computer ist doof’)

Es kommt dabei auf die Gesamtzahl der wesentlichen Stellen an, d.h. vor und nach dem Kom-ma. ImRahmen dieser Vorlesungwerdenwirmit einer vereinfachtenDarstellung rechnen unddefinieren:

Definition 5.1 (Rechnen mit beschränkter Genauigkeit). Eine Rechnung mitm-stelliger Genau-igkeit bedeutet, dass nur m von Null verschiedene Stellen gespeichert werden. Alle weiteren Stellenwerden nach jeder elementaren Operation (Addition, Subtraktion, Division, ...) gerundet

Ein Beispiel zum Rechnen mit 4 Stellen Genauigkeit im Dezimalsystem. Wir wollen

2018 − 1976 + 0.01

berechnen und führen dabei Schritt für aus:

2018 − 1976 = 42=42.00, 42 + 0.01 = 42.01=42.01.

Wir runden zwei mal, es gehen jedoch keine Stellen verloren. In der Addition gilt das Asso-ziativgesetz, d.h. wir können die Aufgabe alternativ schreiben als

(2018 − 1976) + 0.01 = 2018 − (1976 − 0.01)

86 ©2018 Thomas Richter

Page 93: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

und berechnen1976 − 0.01 = 1975.99=1976, 2018 − 1976 = 42=42.

Wieder wird zweimal gerundet, beim ersten Mal leidet die Genauigkeit. Das Assoziativgesetzgilt auf dem Computer nicht!

Rechnen mit 4 Stellen Genauigkeit bezieht sich auch auf große Zahlen, z.B.:

2018 ∗ 8 = 16144=16140,

wir runden nach den ersten 4 wesentlichen Stellen ab.

Darstellungs- und Rundungsfehler müssen auf dem Computer stets berücksichtigt werden.Von besonderer Bedeutung ist der Vergleich zweier Zahlen auf Gleichheit:

1 x=0.1

2 s=0

3 for i in range(10):

4 s=s+x

5

6 if not (s == 1.0):

7 print(’Der Computer ist doof!’)

Auch diese Rechnung kann der Computer nicht exakt ausführen, obwohl die Zahl 0.1 eineendliche - daher eine prinzipiell exakte - Darstellung besitzt. Die Zahl 0.1 lässt sich jedoch imBinärsystem nicht exakt darstellen lassen. Es gilt

0.110 = 0.000110011 . . . ,

die Ziffern 0011 wiederholen sich beliebig oft. Als wesentliche Größe definieren wir die Ma-schinengenauigkeit

Definition 5.2 (Maschinengenauigkeit). DieMaschinengenauigkeit eps ist der maximale relativeRundungsfehler der Zahldarstellung und wird bestimmt als:

eps := inf{x > 0 : rd(1 + x) > 1}

Diese gibt den maximal zu erwartenden relativen Rundungsfehler an. Auf üblichen 32-BitSystem gilt für den Datentyp double für die Maschinengenauigkeit eps ≈ 10−16.

Wirmüssen davon ausgehen, dass jede Zahl auf demComputermit einem relativen Fehler derGrößenordnung eps versehen ist. Nach jeder Zwischenrechnungmüssenwir (mindestens)miteinem weiteren relativen Fehler der Größenordnung eps rechnen.

5.1.1. Kondition{sec:kondition}

Es sei durch f : Rn → Rm ein mathematisches Problem beschrieben. Wir wollen die möglicheAuswirkung eines relativen Fehlers in der Eingabe auf die Ausgabe betrachten. Es sei x ∈ Rndie exakte Eingabe, x ∈ Rn die gestörte. Dann sei

y := f(x), y := f(x).

[email protected] 87

Page 94: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

Wir gehen davon aus, dass die Aufgabe selbst fehlerfrei gelöst werden kann. Es ist

y− y = f(x) − f(x) = f(x+ δx) − f(x),

wobei δx = x− x der Fehler in der Eingabe ist. Wir betrachten diese vektorwertige GleichungKomponente für Komponente. Es ist

δyj

yj:=yj − yjyj

=fj(x+ δx) − fj(x)

yj=fj(x+ δx) − fj(x)

δxi

δxixi

xiyj

Für |δxi| klein könenn wir den Ausdruck mit Hilfe der ersten Ableitung von fj approximieren

δyj

yj=

(∂fj

∂xi+ O(|δx|)

)xifj(x)

δxixi

Wir approximieren und definieren:{Konditionszahl}

Definition 5.3 (Konditionszahl). Es sei f : Rn → Rm differenzierbar. Dann sind die Konditions-zahlen von f definiert als

κij(x) :=

∣∣∣∣ ∂fj∂xi xifj(x)

∣∣∣∣Die Konditionszahlen geben die relative Verstärkung eines Fehlers in der Eingabe auf das Er-gebnis an, d.h. in erster Näherung gilt

|δyj|

|yj|6 κij(x)

|δxi|

|xi|.

Ist die Konditonszahl groß, so nennen wir die Aufgabe f : Rn → Rm schlecht konditioniert.Ansonsten gut konditioniert. Die Konditionszahl ist eine Eigenschaft der Aufgabe und hat nochnichts mit einem Algorithmus zur Durchführung zu tun.

Details und Beispiele finden sich in [11, Abschnitt 1.3].

5.1.2. Stabilität von Algorithmen{sec:stabilitaet}

Es sei f : Rn → Rm eine mathematische Aufgabe. Wir untersuchen nun algorithmen zumLösen oder zur Approximation der Aufgabe. Im Mittelpunkt der Untersuchung steht dabeidas Wechselspiel zwischen Kondition der Aufgabe und Stabilität des Algorithmus. Während dieKondition die inhärente Schwierigkeit der Aufgabe beschreibt und ein Maß für die Fehler-verstärkung angibt, die wir erwarten müssen, wir die Stabilität des Algorithmus die praktischeUmsetzung der Lösung beschreiben.

Wir beginnen mit einem einfachen Beispiel, der Suche nach Nullstellen eines quadratischenPolynoms

f(x) = x2 − px+ q,

welches sich - bei Kenntnis der beiden Nullstellen x1, x2 ∈ C auch schreiben lässt als

f(x) = (x− x1)(x− x2) = x2 − (x1 + x2)x+ x1x2,

also p = x1 + x2 und q = x1x2. Dieser Zusammenhang ist der Satz von Vieta.

88 ©2018 Thomas Richter

Page 95: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

Wir untersuchen zunächst dieKonditionierungderNullstellensuche, d.h. dieAuswirkung vonrelativen Fehlern in p und q auf die Nullstellen x1 und x2. Aufbauend auf der p/q-Formel

x1/2 =p

2±√p2

4− q

und unter Verwendung des Satzes von Vieta erhalten wir

κp =∣∣∣1 + x2

x1

1 − x2x1

∣∣∣, κq =∣∣∣ 1

1 − x2x1

∣∣∣.Die Nullstellensuche ist somit schlecht konditioniert wenn x1 ≈ x2 ansonsten ist sie gut kon-ditioniert. Wir betrachten nun als gut konditionierten Fall das Polynom

f(x) = x2 − 4x+ 0.01,

mit den beiden Nullstellen

x1 ≈ 3.9975, x2 ≈ 0.00250156.

Hier gelten die Konditionszahlen

κp ≈ 1, κq,x1 ≈ 1, κq,x2 ≈ 0.001,

es ist somit keine Fehlerverstärkung zu erwarten.

Wir lösen die Aufgabe nun Schritt für Schritt mit der p/q-Formel und verwenden stets vier-stellige Arithmetik:

1 a1 = p2/4 a1 = 4.0002 a2 = a1 − q a2 = 3.9903 a3 =

√a2 a3 = 1.997

4

5 x1 = p/2+ a3 x1 = 3.9976 x2 = p/2− a3 x2 = 0.003

Wir berechnen die relative Fehler

x1 − x1x1

≈ 0.00013 = 0.013%,x2 − x2x2

≈ 0.20 = 20%.

Die erste Nullstelle kann sehr gut berechnet werden, der rel. Fehler ist mit 10−4 in der Grö-ßenornung der Genauigkeit vierstelliger Arithmetik. Die zweite Nullstelle erfährt jedoch einewesentliche Verstärkung zu einem Fehler von 20%, obwohl die Konditionszahl hier auf keineProbleme hinweist.

Das Problem liegt in Zeile 6, es gilt p/2 ≈ a3 so dass es zu Auslöschung kommt. Wir könnendie zweite Nullstelle alternativ über den Satz von Vieta berechnen, d.h.

1 a1 = p2/4 a1 = 4.0002 a2 = a1 − q a2 = 3.9903 a3 =

√a2 a3 = 1.997

4

5 x1 = p/2+ a3 x1 = 3.9976 x2 = q/x1 x2 = 0.002502

[email protected] 89

Page 96: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

mit einem relativen Fehlerx2 − x2x2

≈ 0.00018 ≈ 0.018%,

entsprechend dem Fehler in der ersten Nullstelle. Wir schlagen nun ein stabiles Verfahren zurBerechnung von Nullstellen quadratischer Polynome vor:

1 a1 = p2/42 a2 = a1 − q3 a3 =

√a2

4 Fa l l s p > 0 :5 x1 = p/2+ a3

6 x2 = q/x17 Sonst :8 x2 = p/2− a3

9 x1 = q/x2

Der Unterschied beider Methoden lässt sich mit Hilfe der Vorwärtsanalyse untersuchen. Wirgehen davon aus, dass in allen Schritte bis zur Berechnung von a3 ein relativer Fehler derGröße a3 = a3(1 + ε) entstanden ist. Weiter sei ohne Einschränkung p > 0. Dann gilt

x1 =(p

2+ a3(1 + ε)

)(1 + ε ′) ⇒ x1 − x1

x1= ε ′ +

a3

x1ε+ O(eps2),

und bei Berechnung von x2 mit der p/q-Formel

x2 =(p

2− a3(1 + ε)

)(1 + ε ′) ⇒ x2 − x2

x2= ε ′ −

a3

x2ε+ O(eps2).

Der Fall x2 ≈ 0.0025 ≈ 0 zeigt hier die enorme Verstärkung des Fehlers.

Verwenden wir zur Berechnung von x2 alternativ den Satz von Vieta so erhalten wir

x2 =q

x1(1 + ε ′′) =

q

x1(1 + ε ′) + a3ε(1 + ε ′′)

also den relativen Fehler (bei x2 = q/x1)

x2 − x2x2

=x1 + ε

′′x1x1 + x1ε ′ + a3ε

− 1 =x1 + ε

′′x1 − (x1 + x1ε′ + a3ε)

x1 + ε ′x1 + a3ε,

abgeschätzt bei |ε|, |ε ′|, |ε ′′| < eps zu∣∣∣∣ x2 − x− 2

x2

∣∣∣∣ 6 eps 2|x1|+ |a3|

|x1(1 + ε ′x1 + a3ε)|,

was auf gute Stabilität hindeutet, da x1 ≈ 4.

Berechnung von Eigenwerten Als abschließendes Beispiel betrachtenwir die Berech-nung von Eigenwerten einer Matrix A ∈ Rn×n. Gesucht sind Werte λ ∈ Cmit

Aw = λw,

wobei w ∈ Cn ein zugehöriger Eigenvektor ist. Es stellt sich zunächst wieder die Frage nachder Konditionierung der Eigenwertsuche: wie überträgt sich ein Fehler in der Eingabe, d.h.

90 ©2018 Thomas Richter

Page 97: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

also in der Matrix A ∈ Rn×n, auf den Fehler in den Eigenwerten λ. Es kann gezeigt werden,siehe hierzu [11, Abschnitt 5.1], dass das Problem prinzipiell nicht schlecht konditioniert ist.Unter bestimmten Bedingungen gilt die Abschätzung

|λ(A) − λ(A)| 6 ‖W‖2‖W−1‖2‖δA‖,

wobeiW = [w1 · · ·wn] die Matrix ist, deren Spaltenvektoren gerade die Eigenvektoren von Asind. Die Abschätzung ist folgendermaßen zu lesen: zu jedem Eigenwert λ(A) von A existiertein Eigenwert λ(A) der gestörten Matrix, so dass die Ungleichung gilt.

Die 2-Norm einer Matrix ist die Spektralnorm und ist für allgemeine Matrizen definiert als

‖W‖2 := max{|λ|12 : λ ist Eigenwert vonWTW}.

Ist dieMatrixA symmetrisch so existiert einOrthonormalsystemvonEigenwerten, d.h. 〈wi,wj〉 =δij. Dann giltWTW = I, d.h. auch ‖W‖2 = 1 und auch ‖W−1‖2 = 1.

Wir betrachten als Beispiel die Matrix

A =

(9.99 4.464.46 1.99

)mit den Eigenwerten

λ1 ≈ 11.98 λ2 ≈ −0.0009599.

Die Matrix ist symmetrisch, so dass wir von einer guten Konditionierung des Eigenwertpro-blems ausgehen können.

Zur Berechnung der Eigenwerte stellenwir das charakteristische Polynom auf. Bei vierstelligerArithmetik ergibt sich

det

(9.99 − λ 4.46

4.46 1.99 − λ

)≈ λ2 − 11.98λ+ 19.88 − 19.89 = λ2 − 11.98λ− 0.01 (5.1) {ew:1}{ew:1}

Wir rechnen die Nullstellen mit dem stabilen Algorithmus aus und erhalten (man beachte dasVorzeichen, also p = 11.98)

1 a1 = p2/4 a1 ≈ 35.882 a2 = a1 − q a2 ≈ 35.893 a3 =

√a2 a3 ≈ 5.991

4 Fa l l s p > 0 :5 λ1 = p/2+ a3 λ1 = 11.98

6 λ2 = q/x1 λ2 = −0.00083477 Sonst :8 λ2 = p/2− a3

9 λ1 = q/x2

Die Eigenwerte sind mit den folgenden relativen Fehlern versehen

λ1 − λ1λ1

≈ 0,λ2 − λ2λ2

≈ 0.13 ≈ 13%.

Der größere Eigenwert wird sehr gut genähert (der Fehler ist hier natürlich nicht exakt Null,stimmt aber in den ersten vier Stellen mit dem exakten Wert aus (5.1) überein). Obwohl ein

[email protected] 91

Page 98: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

stabiles Verfahren zur Berechnung der Nullstellen verwendet wurde liegt ein Fehler von 13%vor. Das Problem liegt im Ansatz selbst: schon die Berechnung des charakteristischen Poly-noms beinhaltet große Fehler durch Auslöschung. Wir haben bei vierstelliger Rechnung dasgestörte Polynom

χ(λ) = λ2 − 11.98λ− 0.01

erhalten, exakte Rechnung ergibt jedoch

χ(λ) = λ2 − 11.98λ− 0.0115,

d.h., der Koeffizient q = −0.01 tägt bereits einen relativen Fehler von gut 11%. Auf Basis ei-nes stark gestörten Polynoms können wir nicht erwarten, exakte Nullstellen zu erhalten. Eindirekter Algorithmus zur Berechnung der Eigenwerte als Nullstellen des charakteristischen Po-lynoms ist also im Allgemeinen nicht stabil.

Wir suchen alternative Wege zur Approximation der Eigenwerte, ohne zuvor das charakte-ristische Polynom zu berechnen. Ist ein Eigenvektor w bekannt, so lässt sich der zugehörigeEigenwert einfach bestimmen

Aw = λw ⇒ λ =[Aw]kwk

,

wobei k ∈ {1, . . . ,n} eine beliebige Zeile der vektorwertigen Gleichung ist - natürliche eineZeile mit wk 6= 0.

Wir betrachten die folgende Iteration:{Potenzmethode zur Eigenwertberechnung}{Eigenwerte!Potenzmethode}

Definition 5.4 (Potenzmethode). Sei A ∈ Rn×n, x(0) ∈ Rn beliebig und k ∈ {1, . . . ,n} ein Index.Für i = 1, 2, . . . iteriere

(i) x(i) := Ax(i−1)

(ii) λ(i) :=x(i)k

x(i−1)k

=[Ax(i−1)]k

x(i−1)k

(iii) x(i) =1

x(i)k

x(i).

Satz 5.5 (Potenzmethode). Es seiA ∈ Rn×n eine symmetrischeMatrix mit Eigenwerten λ1, . . . , λn,so dass der betragsgrößte Eigenwert separiert ist, d.h.

|λ1| 6 |λ2| 6 · · · 6 |λn−1| < |λn|.

Durchw1, . . . ,wn sei ein zugehöriges Orthonormalsystem aus Eigenvektoren gegeben. Für den Index kgelte [wn]k 6= 0 und der Startwert x(0) habe eine nicht-triviale Komponente bzglwn. Dann konvergiertdie Potenzmethode gegen den betragsgrößten Eigenwert λn.

Beweis. Wir betrachten die Vektoren

x(l) = Anx(0)

und schreiben

x(0) =

n∑i=1

αiwi.

92 ©2018 Thomas Richter

Page 99: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

Dann folgt

x(l) =

n∑i=1

λliαiwi = αnλln

(n−1∑i=1

(λiλn

)lαiαnwi +wn

)Es ist |λi/λn| < 1 daher gilt

x(l) = αnλln (o(1) +wn) (l→∞).

Wir normieren und erhalten

x(l) =x(l)

[x(l)]k=

1

[wn]k(o(1) +wn) (l→∞).

Der Vektor x(l) konviergiert für l → ∞ in den Eigenraum zur λn, der von wn aufgespanntwird. Somit folgt

λ(l) :=[Ax(l)]k[x(l)]k

→ λn (l→∞).

Ein ausführlicher Beweis, der auch eine Abschätzung der Konvergenzrate angibt findet sichin [11, Satz 4.5].

Die Potenzmethode ist eine sehr einfache Iteration zur Näherung des betragsgrößten Eigen-werts. Wir haben den größten Eigenwert jedoch bereits gut berechnen können, daher betrach-ten wir diese Methode hier nicht weiter. Wir nutzen jedoch die einfache Umformung

Aw = λw ⇔ A−1w = λ−1w,

die uns einen Bezung zwischen Eigenwert von A und der Inversen A−1 gibt. Nun gilt: derKehrwert des betragsgrößten Eigenwert µ vonA−1, also λ = µ−1 ist der betragskleinste Eigen-wert von A. Wir wollen also die Potenzmethode auf die inverse Matrix A−1 anwenden:

x(l) = A−1x(l−1), µ(l) =x(l)k

x(l−1)l

, x(l) :=1

x(l)k

x(l)

um somit eine Approximation λ = 1/µ(l) des betragskleinsten Eigenwerts von A zu erhalten.Diese Methode heißt Inverse Iteration oder Von-Mises-Iteration.

Wir starten die Iteration mitx(0) =

(1−2

)In jedem Schritt müssen wir das lineare Gleichungssystem

Ax(l) = x(l−1)

lösen. Hierzu bestimmen wir die Inverse per

A−1 =1

det(A)

(1.99 −4.46−4.46 9.99

)

[email protected] 93

Page 100: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

Bei vierstelliger Rechnung ergibt sich

A−1 =

(−199 446446 −999

).

Umeiner Enttäuschungnach langerRechnung entgegenzuwirken stoppenwir hier dasweitereVorgehen und untersuchen zunächst den Fehler in der inversen Matrix, also A−1 − A−1. Esgilt

‖A−1 −A−1‖‖A−1‖

≈ 0.15 = 15%.

Die Inverse ist also bereits mit einem sehr großen Fehler behaftet. Wir können nicht davonausgehen, dass ein approximatives Verfahren zur Berechnung der Eigenwerte auf Basis vondieser gestörten Matrix eine gute Approximation liefert.

Wir werden die linearen Gleichungssystem Ax = x, die in jedem Schritt der Potenzethodeauftauchen, daher mit einem iterativen Verfahren lösen. Wir wählen hierzu die Richardson-Iteration, die ausgehend von einem Startvektor x0 Iterierte nach der Vorschrift

xk = xk−1 + P−1(b−Axk−1)

liefert. Als Vorkonditionierer P−1 wählen wir die oben berechnete Approximation der Inversen,also

P−1 :=

(−199 446446 −999

).

Wir starten nun die Potenzmethode ausgehend von x(0) = (1,−2)T . Im ersten Schritt lösenwir (

9.99 4.464.46 9.99

)x(1) = x(0)

mit Hilfe der Richardson-Iteration. Es ist mit x0 = x(0)

x1 =

(1−2

)+

(−199 446446 −999

)((1−2

)−

(9.99 4.464.46 9.99

)(1−2

))≈(

1−2

)+

(−199 446446 −999

)(−0.07−2.48

)≈(

1−2

)+

(−10922446

)≈(−10912444

)Wir machen einen zweiten Schritt

x2 =

(−10912444

)+

(−199 446446 −999

)((1−2

)−

(9.99 4.464.46 9.99

)(−10912444

))≈(−10912444

)+

(−199 446446 −999

)(−0.150.30

)≈(−10912444

)+

(163.7−366.6

)≈(−927.42077

)

94 ©2018 Thomas Richter

Page 101: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

und einen dritten Schritt

x3 =

(−927.42077

)+

(−199 446446 −999

)((1−2

)−

(9.99 4.464.46 9.99

)(−927.42077

))≈(−927.42077

)+

(−199 446446 −999

)(2.3060.974

)≈(−927.42077

)+

(−24.4955.45

)≈(−951.92132

)und einen vierten

x4 =

(−951.92132

)+

(−199 446446 −999

)((1−2

)−

(9.99 4.464.46 9.99

)(−951.92132

))≈(−951.92132

)+

(−199 446446 −999

)(1.7610.794

)≈(−951.92132

)+

(3.685−7.8

)≈(−948.22124

)Wir stoppen hier die Iteration und akzeptieren x4 als Lösung des linearen Gleichungssystems.Angewendet auf größere Gleichungssystememuss hier eine systematische Abbruchskontrolleerfolgen, z.B. durch Kontrolle des Residuums

‖dk‖ = ‖b−Axk‖,

welches Null ist, falls xk die exakte Lösung ist.

Wir haben nun eine Näherung an x(1) und berechnen eine erste Näherung des inversen Eigen-werts (wir wählen k = 1)

µ(1) =−948.2

1= −948.2 ⇒ λ(1) =

1

µ(1)≈ −0.001055,

und wir normierenx(1) =

1

−948.2x(1) ≈

(1

−2.240

)Zur Berechnung von x(2), gegeben als(

9.99 4.464.46 9.99

)x(2) = x(1)

wenden wir wieder die Richardson-Iteration an. Wir verkürzen die Rechnung und gegen nurdas Ergebnis nach einigen Schritten an:

x1 =

(1

−2.240

)+

(−199 446446 −999

)((1

−2.240

)−

(1.99 −4.46−4.46 9.99

)(1

−2.240

))· · · → . . . x5 ≈

(−10492350

)

[email protected] 95

Page 102: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

5.1. Zahldarstellung und Fehler

Wir erhalten als zweite Näherung an den inversen Eigenwert

µ(2) =x(2)1

x(1)≈ −1049

1⇒ λ(2) =

1

µ(2)≈ −0.0009533.

Diese zweite Iteration ist eine Approximation mit dem relativen Fehler

λ(2) − λ

λ≈ 0.0069 = 0.67%.

96 ©2018 Thomas Richter

Page 103: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6. Lineare Gleichungssysteme{la:sec:lgs}

Das Lösen von linearen Gleichungssystemen (LGS) ist eine der grundlegenden Aufgaben inder Mathematik. Oft sind Probleme nicht direkt in Form eines linearen Gleichungssystemsgegeben, sondern ergeben sich im Zuge der mathematischen Modellierung. Solche linearenGleichungssysteme sind unter Umständen aber sehr groß. Groß bedeutet, dass Gleichungs-systeme mit vielen Millionen1 bis Milliarden2 Unbekannten gelöst werden müssen. Wir wer-den uns in diesem Abschnitt ausschließlich mit reellwertigen Matrizen A ∈ Rn×n befassen.Methoden zum Lösen von linearen Gleichungsystemen klassifiziert man als direkte Verfahren,welche die Lösung des Gleichungssystems unmittelbar und bis auf Rundungsfehlereinflüsseexakt berechnen und iterative Verfahren, welche die Lösung durch eine Fixpunktiteration ap-proximieren. In diesem Kapitel befassen wir uns zunächst mit direkten Methoden.

Als einführendes Beispiel betrachten wir das einfache Gleichungssystem(0.988 0.9600.992 0.963

)(x

y

)=

(0.0840.087

)mit der Lösung (x,y)T = (3,−3)T .Wir bestimmendie LösungnumerischdurchGauß-Eliminationmit dreistelliger Rechengenauigkeit. Die Gauß-Elimination setzen wir dabei als bekannt vor-aus: ( )

0.988 0.960 0.0840.992 0.963 0.087 ×0.988/0.992( )0.988 0.960 0.0840.988 0.959 0.0866 ↓ −( )0.988 0.959 0.084

0 0.001 −0.0026

Mithilfe der Gauß-Elimination haben wir die Matrix A auf eine Dreiecksgestalt transformiert.Die rechte Seite b wurde entsprechend modifiziert. Das resultierende Dreieckssystem kannnun sehr einfach durch Rückwärtseinsetzen gelöst werden (bei dreistelliger Rechnung):

0.001y = −0.0026 ⇒ y = −2.6

0.988x = 0.087 − 0.959 · (−2.6) ≈ 2.58 ⇒ x = 2.61.

1Beispielsweisemuss imZuge der europäischen RaumfahrtmissionGaia einGleichungssystemmit 600Millionen(also 6 · 108) Unbekannten gelöst werden [1].

2Im Jahr 2016 wurden auf einem sogenannten Petascale-Computer, also einem Parallelrechner mit mehr als 1015FLOPS, lineare Gleichungssysteme mit bis zu 6 · 1011 (0.6 Trillionen) Unbekannten gelöst [6].

97

Page 104: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Wir erhalten also (x,y) = (2.61,−2.60). Der relative Fehler der numerischen Lösung beträgtsomit mehr als 10%. Die numerische Aufgabe, ein Gleichungssystem zu lösen, scheint alsoentweder generell sehr schlecht konditioniert zu sein (siehe Kapitel 5.1.1), oder aber das Eli-minationsverfahren zur Lösung eines linearen Gleichungssystems ist numerisch sehr instabilund nicht gut geeignet. Der Frage nach der Konditionierung und Stabilität gehen wir im fol-genden Abschnitt auf den Grund.

Wie eingangs motiviert, treten in der praktischen Anwendung oft sehr große Gleichungssys-teme Ax = b auf. Bei der numerischen Approximation von partiellen Differentialgleichungenmüssen also MatrizenA ∈ Rn×n mit sehr großem n invertiert werden. (Man nennt das Löseneines linearen Gleichungssystems oft Invertieren, auch wenn die Inverse A−1 nicht wirklichaufgestellt wird.) Hinzu kommt, dass ein solches lineares Gleichungssystem oft wiederholtgelöst werden muss. Neben der Stabilität des Lösungsprozesses wird auch die numerischeEffizienz eine große Rolle spielen. Man versuche, eine 20 × 20-Matrix mit dem GaußschenEliminationsverfahren zu invertieren.

6.1. Grundlagen der Linearen Algebra{sec:la:grundlagen}

Wir sammeln zunächst einige Definitionen und grundlegende Resultate der linearen Algebra.Für ausführliche Darstellungen verweisen wir auf die Literature, z.B. [3]. Es sei V stets einVektorraum über dem Körper K. Üblicherweise betrachten wir den Raum der reellwertigenVektoren V = Rn.

Definition 6.1 (Basis). Eine Teilmenge B = {v1, . . . , vn} ⊂ V eines Vektorraums überK heißt Basis,falls sich jedes Element v ∈ V eindeutig als Linearkombination der Basisvektoren B darstellen lässt:

v =

n∑i=1

αivi, αi ∈ K.

Die eindeutige Darstellbarkeit jedes v ∈ V durch Basisvektoren erlaubt es, den Vektorraum V

mit dem Vektorraum der Koeffizientenvektoren α ∈ Kn zu identifizieren. Daher können wiruns in diesem Abschnitt im Wesentlichen auf diesen Raum (bzw. auf Rn) beschränken. AlleEigenschaften und Resultate übertragen sich auf V. Zum Beispiel ist ein Polynom eindeutigsowohl in Monom-, Newton- oder Lagrange-Basis darstellbar und dann durch entsprechendeKoeffizienten bestimmt.

Definition 6.2 (Norm). Eine Abbildung ‖ · ‖ : V → R+ heißt Norm, falls sie die folgenden dreiEigenschaften besitzt:

1. positive Definitheit: ‖x‖ > 0 ∀x ∈ V,

‖x‖ = 0 ⇒ x = 0,

2. Linearität: ‖αx‖ = |α| ‖x‖ ∀x ∈ V, α ∈ K,

3. Dreiecksungleichung: ‖x+ y‖ 6 ‖x‖+ ‖y‖ ∀x,y ∈ V.

98 ©2018 Thomas Richter

Page 105: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Ein Vektorraum mit einer Norm heißt normierter Raum. Im Kn häufig verwendete Normensind die Maximumsnorm ‖ · ‖∞, die euklidische Norm ‖ · ‖2 sowie die l1-Norm ‖ · ‖1:

‖x‖∞ := maxi=1,...,n

|xi|, ‖x‖2 :=

(n∑i=1

|xi|2

) 12

, ‖x‖1 :=n∑i=1

|xi|.

ImVektorraumRn sowie in allen endlich-dimensionalenVektorräumengilt der folgendewich-tige Satz:

Satz 6.3 (Normäquivalenz). Zu zwei beliebigen Normen ‖ · ‖ sowie ‖ · ‖ ′ im endlich-dimensionalenVektorraum V existiert eine Konstante c > 0, sodass gilt:

1

c‖x‖ 6 ‖x‖ ′ 6 c‖x‖ ∀x ∈ V.

Dieser Satz bedeutet, dass alle Normen in endlich-dimensionalen Vektorräumen äquivalentsind. Da Normen wesentlich für den Konvergenzbegriff sind, bedeutet dieses Resultat, dasseine Folge xn → x, welche bzgl. einer Norm ‖ · ‖ konvergiert, auch bzgl. jeder anderen Norm‖ ·‖ ′ konvergiert. Dieser Zusammenhang ist typisch für endlich-dimensionale Räume und giltz.B. nicht in (unendlich-dimensionalen) Funktionenräumen. So gilt z.B. für die Funktionenfol-ge fn(x) = exp(−nx2)

‖fn − 0‖L2([−1,1]) −−−−→n→∞ 0, jedoch ‖fn − 0‖∞ −−−−→

n→∞ 1,

bezüglich der L2-Norm sowie der Maximumsnorm:

‖f‖L2([−1,1]) :=

(∫1−1

|f(x)|2 dx) 1

2

, ‖f‖∞ := supx∈[−1,1]

|f(x)|.

Neben Normen spielen Räume, in denen ein Skalarprodukt existiert, eine wichtige Rolle: {la:def:scp}

Definition 6.4 (Skalarprodukt). Eine Abbildung (·, ·) : V × V → K heißt Skalarprodukt, falls siedie folgenden Eigenschaften besitzt:

1. Definitheit: (x, x) > 0 ∀x ∈ V, x 6= 0,

(x, x) = 0 ⇒ x = 0

2. Linearität: (x,αy+ z) = α(x,y) + (x, z) ∀x,y, z ∈ V, α ∈ K,

3. Hermitesch: (x,y) = (y, x) ∀x,y ∈ V,

dabei ist z die komplexe Konjugation von z ∈ C.

In reellen Räumen gilt die echte Symmetrie (x,y) = (y, x). Weiter folgt aus 2. und 3.

(αx,y) = α(x,y).

Das bekannteste Skalarprodukt ist das euklidische Skalarprodukt für Vektoren x,y ∈ Rn:

(x,y)2 = xTy =

n∑i=1

xiyi.

[email protected] 99

Page 106: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Vektorräume mit Skalarprodukt werden Prä-Hilbert-Räume genannt. Komplexe Vektorräumemit Skalarprodukt nennt man auch unitäre Räume, im Reellen spricht man von euklidischenRäumen.

Skalarprodukte sind eng mit Normen verknüpft:

Satz 6.5 (Induzierte Norm). Es sei V ein Vektorraum mit Skalarprodukt. Dann ist durch

‖x‖ =√

(x, x), x ∈ V,

auf V die induzierte Norm gegeben.

Ein Prä-Hilbert-Raum ist somit immer auch ein normierter Raum. Falls der Prä-Hilbert-RaumV bzgl. dieser Norm vollständig ist, also ein Banach-Raum (siehe z.B. [15]) ist, so heißt VHilbert-Raum.

Die euklidische Norm ist die vom euklidischen Skalarprodukt induzierte Norm:

‖x‖2 = (x, x)122 .

Einige wichtige Sätze gelten für Paare aus Skalarprodukt und induzierter Norm:

Satz 6.6. Es sei V ein Vektorraum mit Skalarprodukt (·, ·) und induzierter Norm ‖ · ‖. Dann gilt dieCauchy-Schwarzsche Ungleichung:

|(x,y)| 6 ‖x‖ ‖y‖ ∀x,y ∈ V,

sowie die Parallelogrammidentität:

‖x+ y‖2 + ‖x− y‖2 = 2‖x‖2 + 2‖y‖2 ∀x,y ∈ V.

Hiermit folgt

Satz 6.7 (Skalarprodukt und induzierte Norm). Es sei V ein Vektorraum mit Skalarprodukt (·, ·)und ‖ · ‖ die induzierte Norm. Dann gilt

‖x‖ = supy∈V , y6=0

(x,y)

‖y‖,

sowie‖x‖ = sup

y∈V , ‖y‖=1(x,y).

Beweis. Für y = x/‖x‖ dann folgt sofort (x,y) = ‖x‖ und hiermit ist jeweils ein “6” gezeigt.Mit der Cauchy-Scharz Ungleichung gilt

(x,y) 6 ‖x‖ ‖y‖ ⇒ ‖x‖ > (x,y)

‖y‖∀y ∈ V,

so dass auch die andere Richtung folgt.

Wir definieren weiter:

100 ©2018 Thomas Richter

Page 107: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Definition 6.8 (Orthogonalität). Zwei Vektoren x,y ∈ V eines Prä-Hilbert-Raums heißen orthogo-nal, falls (x,y) = 0.

Die Einführung einer Normabbildung auf V ermöglicht es, den Abstand ‖x−y‖ zu definieren.Die Existenz eines Skalarprodukts ermöglicht es, zwei Elementen einen Winkel zuzuordnen.Es gilt im euklidischen Skalarprodukt

cos(^(x,y)) =(x,y)2‖x‖2‖y‖2

,

und hieraus folgt x ⊥ y, falls (x,y)2 = 0. Dieser euklidische Winkelbegriff und Orthogonali-tätsbegriff lässt sich auf beliebige Räume mit Skalarprodukt übertragen.

Eine der Aufgaben der numerischen linearen Algebra ist die Orthogonalisierung (oder auchOrthonormalisierung) von gegebenen Systemen von Vektoren:

Definition 6.9 (Orthonormalbasis). Eine Basis B = {v1, . . . , vn} von V heißt Orthogonalbasisbezüglich des Skalarprodukts (·, ·), falls gilt:

(φi,φj) = 0 ∀i 6= j,

und Orthonormalbasis, falls gilt:(φi,φj) = δij

mit dem Kronecker-Symbol

δij =

{1 i = j

0 i 6= j.

Mit unterschiedlichen Skalarprodukten existieren unterschiedliche Orthonormalbasen zu einund demselben Vektorraum V . Orthogonalität stimmt dann im Allgemeinen nicht mit demgeometrischen Orthogonalitätsbegriff des euklidischen Raums überein:

Beispiel 6.10 (Skalarprodukte und Orthonormalbasis). Es sei V = R2. Durch

(x,y)2 := x1y1 + x2y2, (x,y)ω := 2 x1y1 + x2y2,

sind zwei verschiedene Skalarprodukte gegeben. Das erste ist das euklidische Skalarprodukt. Die Ska-larprodukteigenschaften des zweiten sind einfach zu überprüfen. Durch

x1 =1√2(1, 1)T , x2 =

1√2(−1, 1)T ,

ist eine Orthonormalbasis bezüglich (·, ·)2 gegeben. Es gilt jedoch:

(x1, x2)ω =1

2(−2 + 1) =

−1√26= 0.

Eine Orthonormalbasis bzgl. (·, ·)ω erhalten wir z.B. durch

x1 =1√3(1, 1)T , x2 =

1

2(−1, 2)T .

[email protected] 101

Page 108: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Wir betrachten nundenVektorraumallerRn×m-Matrizen.AuchdieserVektorraum ist endlich-dimensional und prinzipiell könnenwir den Vektorraum der n×m-Matrizenmit demVektor-raum der (nm)-Vektoren identifizieren. Von besonderem Interesse ist für uns der Vektorraumder quadratischen Rn×n-Matrizen.

Definition 6.11 (Determinante). Auf dem Vektorraum Rn×n der n× nMatrizen ist die Determi-nante eine Abbildung det : Rn×n → R mit den Eigenschaften

1. normiert: det(I) = 1

2. alternierend: Sei A = (a1, . . . ,an) mit den Zeilenvektoren (oder Spaltenvektoren) ai ∈ Rndann gilt für 1 6 i 6= j 6 n

det(a1, . . . ,ai, . . . ,aj, . . . ,an

)= −det

(a1, . . . ,aj, . . . ,ai, . . . ,an

)3. multilinear: Für Zeilen-, bzw. Spaltenvektoren a1, . . . ,an ∈ Rn sowie einem weiteren Vektorb ∈ Rn gilt

det(a1, . . . ,ai + b, . . . ,an

)= det

(a1, . . . ,ai, . . . ,an

)+ det

(a1, . . . ,b, . . . ,an

),

sowie mit einem Skalar λ ∈ R gilt

det(a1, . . . , λai, . . . ,an

)= λ det

(a1, . . . ,ai, . . . ,an

).

Es gilt:

Satz 6.12 (Determinante). Es gibt genau eine Determinante det : Rn×n → R. Sei A ∈ Rn×n mitKoeffizienten A = (aij)ij. Dann gilt

det(A) =∑σ∈Pn

sign(σ)

n∏i=1

Aiσi ,

mit allen Permutationen σ aus Pn von {1, 2, . . . ,n}.{la:def:eigenwerte}

Definition 6.13 (Eigenwerte, Eigenvektoren). Die Eigenwerte λ einer Matrix A ∈ Rn×n sinddefiniert als Nullstellen des charakteristischen Polynoms:

det(A− λI) = 0

Die Menge aller Eigenwerte einer Matrix A heißt das Spektrum von A

σ(A) := {λ ∈ C, λ Eigenwert von A}.

Der Spektralradius spr : Rn×n → R+ ist der betragsmäßig größte Eigenwert:

spr(A) := max{|λ|, λ ∈ σ(A)}

Ein Element w ∈ Rn \ {0} heißt Eigenvektor zum Eigenwert λ, falls gilt:

Aw = λw.

102 ©2018 Thomas Richter

Page 109: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Bei der Untersuchung von linearen GleichungssystemenAx = b stellt sich zunächst die Frage,ob ein solches Gleichungssystemüberhaupt lösbar und ob die Lösung eindeutig ist.Wir fassenzusammen:

Satz 6.14 (Reguläre Matrix). Für eine quadratische Matrix A ∈ Rn×n sind die folgenden Aussagenäquivalent:

1. Die Matrix A ist regulär.

2. Die transponierte Matrix AT ist regulär.

3. Die Inverse A−1 ist regulär.

4. Das lineare Gleichungssystem Ax = b ist für jedes b ∈ Rn eindeutig lösbar.

5. Es gilt det(A) 6= 0.

6. Alle Eigenwerte von A sind ungleich null.

Wir definieren weiter: {la:def:pos}

Definition 6.15 (Positive Definitheit). Eine Matrix A ∈ Kn×n heißt positiv definit, falls

(Ax, x) > 0 ∀x 6= 0, x ∈ Kn.

Sie heißt positiv semidefinit, falls

(Ax, x) > 0 ∀x ∈ Kn.

Entsprechend heißt die Matrix negativ definit, falls

(Ax, x) < 0 ∀x 6= 0, x ∈ Kn,

und negativ semidefinit, falls(Ax, x) 6 0 ∀x ∈ Kn.

Trifft keine dieser Ungleichungen zu, so heißt die Matrix indefinit.

Umgekehrt können wir aus der definierenden Eigenschaft der positiven Definitheit einer Ma-trix ablesen: Falls A positiv definit und Hermitesch ist, so ist durch (A·, ·) ein Skalarproduktgegeben. Es gilt: {la:satz:pos}

Satz 6.16 (Positiv definite Matrizen). Es sei A ∈ Rn×n eine symmetrische Matrix. Dann ist Agenau dann positiv definit, falls alle (reellen) Eigenwerte von A positiv sind. Ist A symmetrisch positivdefinit, so sind alle Diagonalelemente vonA positiv, d.h. echt größer null, und das betragsmäßig größteElement steht auf der Diagonalen.

Beweis. (i) Es sei A eine symmetrische Matrix mit einer Orthonormalbasis aus Eigenvektorenw1, . . . ,wn. A sei positiv definit. Dann gilt für einen beliebigen Eigenvektorwi mit Eigenwertλi:

0 < (Awi,wi) = λi(wi,wi) = λi

[email protected] 103

Page 110: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Umgekehrt seien alle λi positiv. Für x =∑ni=1 αiwi mit x 6= 0 gilt:

(Ax, x) =∑i,j

(λiαiωi,αjωj) =∑i

λiα2i > 0

(ii) A sei nun eine reelle, positiv definite Matrix. Es sei ei der i-te Einheitsvektor. Dann gilt:

0 < (Aei, ei) = aii.

Das heißt, alle Diagonalelemente sind positiv.

(iii) Entsprechend wählen wir nun x = ei − sign(aij)ej. Wir nehmen an, dass aji = aij dasbetragsmäßig größte Element der Matrix sei. Dann gilt:

0 < (Ax, x) = aii − sign(aij)(aij + aji) + ajj = aii + ajj − 2|aij| 6 0.

Aus diesem Widerspruch folgt die letzte Aussage des Satzes: Das betragsmäßig größte Ele-ment muss ein Diagonalelement sein.

Für Normen auf dem Raum der Matrizen definieren wir weitere Struktureigenschaften:{def:matrixnorm}

Definition 6.17 (Matrixnormen). Eine Norm ‖ · ‖ : Rn×n → R+ heißt Matrixnorm, falls siesubmultiplikativ ist:

‖AB‖ 6 ‖A‖ ‖B‖ ∀A,B ∈ Rn×n.

Sie heißt verträglich mit einer Vektornorm ‖ · ‖ : Rn → R+, falls gilt:

‖Ax‖ 6 ‖A‖ ‖x‖ ∀A ∈ Rn×n, x ∈ Rn.

Eine Matrixnorm ‖ · ‖ : Rn×n → R+ heißt von einer Vektornorm ‖ · ‖ : Rn → R+ induziert, fallsgilt:

‖A‖ := supx 6=0

‖Ax‖‖x‖

.

Für eine induzierte Matrixnorm gilt stets:

‖A‖ := supx 6=0

‖Ax‖‖x‖

= sup‖x‖=1

‖Ax‖ = sup‖x‖61

‖Ax‖

Es ist leicht nachzuweisen, dass jede von einer Vektornorm induzierte Matrixnorm mit dieserauch verträglich ist. Verträglich mit der euklidischen Norm ist aber auch die Frobenius-Norm

‖A‖F :=

n∑i,j=1

a2ij

12

, (6.1){la:frobeniusnorm}{la:frobeniusnorm}

welche nicht von einer Vektornorm induziert ist. Für allgemeineNormen auf demVektorraumder Matrizen gilt nicht notwendigerweise ‖I‖ = 1, wobei I ∈ Rn×n die Einheitsmatrix ist.Dieser Zusammenhang gilt aber für jede von einer Vektornorm induzierte Matrixnorm. Wirfassen im folgenden Satz die wesentlichen induzierten Matrixnormen zusammen:

104 ©2018 Thomas Richter

Page 111: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

{la:satz:matrixnorm}

Satz 6.18 (Induzierte Matrixnormen). Sei A ∈ Rn×n. Die aus der euklidischen Vektornorm, derMaximumsnorm sowie der l1-Norm induzierten Matrixnormen sind die Spektralnorm ‖ · ‖2, diemaximale Zeilensumme ‖ · ‖∞, sowie die maximale Spaltensumme ‖ · ‖1:

‖A‖2 =√

spr(ATA), spr(B) := max{|λ|, λ ist Eigenwert von B},

‖A‖∞ = maxi=1,...,n

m∑j=1

|aij|,

‖A‖1 = maxj=1,...,m

n∑i=1

|aij|.

Beweis. (i) Es gilt:

‖A‖22 = supx 6=0

‖Ax‖22‖x‖22

= supx 6=0

(Ax,Ax)

‖x‖22= supx 6=0

(ATAx, x)

‖x‖22.

Die Matrix ATA ist symmetrisch und hat als solche nur reelle Eigenwerte. Sie besitzt eineOrthonormalbasis ωi ∈ Rn von Eigenvektoren mit Eigenwerten λi > 0. Alle Eigenwerte λisind größer gleich null, denn:

λi = λi(ωi,ωi) = (ATAωi,ωi) = (Aωi,Aωi) = ‖Aωi‖2 > 0 (6.2) {xx:1}{xx:1}

Es sei x ∈ Rn beliebig mit Basisdarstellung x =∑i αiωi. Es gilt dann wegen (ωi,ωj)2 = δij

die Beziehung ‖x‖22 =∑i α

2i mit αi ∈ R:

‖A‖22 = sup|α|6=0

(∑i αiA

TAωi,∑i αiωi)∑

i α2i

= sup|α|6=0

(∑i αiλiωi,

∑i αiωi)∑

i α2i

= sup|α|6=0

∑i λiα

2i∑

i α2i

6 maxiλi,

wobei|α| = max

i|αi|.

Es sei nun umgekehrt durch λk der größte Eigenwert gegeben. Dann gilt wegen (6.2) mit αi =δki:

0 6 maxiλi = λk =

∑i

λiα2i =∑i,j

(λiαiωi,αjωj) = (ATAx, x) = ‖Ax‖22. (6.3) {xx:2}{xx:2}

Also gilt maxi λi 6 ‖A‖22.

(ii) Wir zeigen das Ergebnis exemplarisch für die Maximumsnorm:

‖Ax‖∞ = sup‖x‖∞=1

maxi

m∑j=1

aijxj

[email protected] 105

Page 112: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.1. Grundlagen der Linearen Algebra

Diese Summe mit ‖x‖∞ = 1 nimmt ihr Maximum an, falls |xj| = 1 und falls das Vorzeichen xjso gewählt wird, dass aijxj > 0 für alle j = 1, . . . ,m. Dann gilt:

‖Ax‖∞ = maxi

m∑j=1

|aij|

Als Nebenresultat erhalten wir aus (6.3), dass jeder Eigenwert betragsmäßig durch die Spek-tralnorm der Matrix A beschränkt ist. Es gilt sogar mit beliebiger Matrixnorm und verträgli-cher Vektornorm für einen Eigenwert λmit zugehörigem Eigenvektor w ∈ Rn von A:

|λ| =|λ| ‖w‖‖w‖

=‖Aw‖‖w‖

6‖A‖ ‖w‖‖w‖

= ‖A‖

Eine einfache Schranke für den betragsmäßig größten Eigenwert erhält man also durch Ana-lyse beliebiger (verträglicher) Matrixnormen.

Aus Satz 6.18 folgern wir weiter, dass für symmetrische Matrizen die ‖ · ‖2-Norm mit demSpektralradius der Matrix selbst übereinstimmt, daher der Name Spektralnorm.

Wir rekapitulieren zuletzt ein weiteres Resultat der linearen Algebra:{satz_grundlagen_la_rang_A_ATA}

Satz 6.19. Es sei A ∈ Rm×n eine beliebige rechteckige Matrix einer zugrunde liegenden linearenAbbildung L : Rn → Rm. Dann gilt:

Rang(A) = Rang(AT ) = Rang(AAT ) = Rang(ATA),

wobei Rang(A) := dim(Bild(A)) den (Spalten-)Rang der Matrix A bezeichnet, also die maximaleAnzahl linear unabhängiger Spaltenvektoren.

Beweis. (i)Wir nutzen die zentrale Aussage der linearen Algebra, dass der Zeilenrangmit demSpaltenrang übereinstimmt. Des Weiteren gilt für eine Matrix B ∈ Rr×s der Dimensionssatz

s = Rang(B) +Def(B),

wobei Def(B) := dim(Kern(B)) den Defekt der Matrix B bezeichnet. Der Kern der zugehöri-gen Abbildung LB ist definiert als Kern(B) := {x ∈ Rs| LBx = 0 ∈ Rr}.

(ii)Die Dimensionsformel wird nun jeweils auf die Matrizen B := ATA ∈ Rn×n und B := A ∈Rm×n angewendet:

n = Rang(ATA) +Def(ATA),

n = Rang(A) +Def(A).

Da die linken Seiten gleich sind, erhalten wir sofort:

Rang(ATA) +Def(ATA) = Rang(A) +Def(A)

⇒ Rang(A) = Rang(ATA) +Def(ATA) −Def(A). (6.4){la_dim_satz_rang_kern}{la_dim_satz_rang_kern}

106 ©2018 Thomas Richter

Page 113: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.2. Störungstheorie und Stabilitätsanalyse von linearen Gleichungssystemen

(iii) Auf der anderen Seite gilt aber Kern(A) ⊂ Kern(ATA). Speziell gilt in Kern(ATA), dassATAx = 0. Daraus folgt xTATAx = ‖Ax‖22 = 0, also auch ‖Ax‖2 = 0 und damitAx = 0. Dahergilt also auch die umgekehrte Richtung: Kern(ATA) ⊂ Kern(A).

(iv) Die letzte Aussage zusammen mit (6.4) liefert das gewünschte Resultat

Rang(A) = Rang(ATA).

6.2. Störungstheorie und Stabilitätsanalyse vonlinearen Gleichungssystemen

Zu einer quadratischen regulären Matrix A ∈ Rn×n sowie einem Vektor b ∈ Rn betrachtenwir das lineare Gleichungssystem

Ax = b.

Durch numerische Fehler, Rundungsfehler, Eingabefehler oder durch Messungenauigkeitenliegen sowohl A als auch b nur gestört vor:

Ax = b

Dabei sei A = A+ δA sowie b = b+ δbmit den Störungen δA sowie δb.

Wir kommen nun zur Kernaussage dieses Abschnitts und wollen die Fehlerverstärkung beimLösen von linearenGleichungssystemen betrachten. Fehler können dabei sowohl in derMatrixA als auch in der rechten Seite b auftauchen. Wir betrachten zunächst Störungen der rechtenSeite. {la:satz:kond1}

Satz 6.20 (Störung der rechten Seite). Es sei A ∈ Rn×n eine reguläre Matrix, b ∈ Rn. Durchx ∈ Rn sei die Lösung des linearen Gleichungssystems Ax = b gegeben. Es sei δb eine Störung derrechten Seite b = b + δb und x die Lösung des gestörten Gleichungssystems Ax = b. Weiter sei ‖ · ‖eine mit einer Vektornorm ‖ · ‖ verträgliche Matrixnorm. Dann gilt:

‖δx‖‖x‖

6 cond(A)‖δb‖‖b‖

,

mit der Konditionszahl der Matrix

cond(A) = ‖A‖ · ‖A−1‖.

Beweis. Es sei ‖·‖ eine beliebigeMatrixnormmit verträglicher Vektornorm ‖·‖. Für die Lösungx ∈ Rn und gestörte Lösung x ∈ Rn gilt:

x− x = A−1(Ax−Ax) = A−1(b− b) = A−1δb

Also:‖δx‖‖x‖

6 ‖A−1‖‖δb‖‖x‖

· ‖b‖‖b‖

= ‖A−1‖‖δb‖‖b‖

· ‖Ax‖‖x‖

6 ‖A‖ · ‖A−1‖︸ ︷︷ ︸=:cond(A)

‖δb‖‖b‖

[email protected] 107

Page 114: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.2. Störungstheorie und Stabilitätsanalyse von linearen Gleichungssystemen

{la:bem:vmult}

Bemerkung 6.21 (Konditionszahl einer Matrix). Die Konditionszahl einer Matrix spielt die ent-scheidende Rolle in der numerischen linearen Algebra. Betrachten wir etwa die Konditionierung derMatrix-Vektor-Multiplikation y = Ax, so erhalten wir bei gestörter Eingabe x = x+ δx wieder

‖δy‖‖y‖

6 cond(A)‖δx‖‖x‖

.

Die Konditionszahl einer Matrix hängt von der gewählten Norm ab. Da jedoch alle Matrixnormenim Rn×n äquivalent sind, sind auch alle Konditionsbegriffe äquivalent. Mit Satz 6.18 folgern wir fürsymmetrische Matrizen für den Spezialfall cond2(A):

cond2(A) = ‖A‖2 · ‖A−1‖2 =max{|λ|, λ Eigenwert von A}min{|λ|, λ Eigenwert von A}

.

Wir betrachten nun den Fall, dass die Matrix A eines linearen Gleichungssystems mit einerStörung δA versehen ist. Es stellt sich zunächst die Frage, ob die gestörte Matrix A = A + δAüberhaupt noch regulär ist.{la:hilfsatz:1}

Hilfsatz 6.22. Es sei durch ‖ · ‖ eine von der Vektornorm induzierte Matrixnorm gegeben. Weiter seiB ∈ Rn×n eine Matrix mit ‖B‖ < 1. Dann ist die Matrix I+ B regulär und es gilt die Abschätzung

‖(I+ B)−1‖ 6 1

1 − ‖B‖.

Beweis. Es gilt‖(I+ B)x‖ > ‖x‖− ‖Bx‖ > (1 − ‖B‖)‖x‖.

Da 1 − ‖B‖ > 0, ist durch I+ B eine injektive Abbildung gegeben. Also ist I+ B eine reguläreMatrix. Weiter gilt:

1 = ‖I‖ = ‖(I+ B)(I+ B)−1‖ = ‖(I+ B)−1 + B(I+ B)−1‖> ‖(I+ B)−1‖− ‖B‖ ‖(I+ B)−1‖ = ‖(I+ B)−1‖(1 − ‖B‖) > 0.

Mit diesem Hilfssatz können wir im Folgenden auch auf die Störung der Matrix eingehen:{la:satz:kond2}

Satz 6.23 (Störung der Matrix). Es seiA ∈ Rn×n eine reguläre Matrix, b ∈ Rn. Weiter sei x ∈ Rndie Lösung des linearen Gleichungssystems Ax = b und sei A = A + δA eine gestörte Matrix mit‖δA‖ 6 ‖A−1‖−1. Für die gestörte Lösung x = x+ δx von Ax = b gilt:

‖δx‖‖x‖

6cond(A)

1 − cond(A)‖δA‖/‖A‖‖δA‖‖A‖

.

Beweis. Wir betrachten den Fall, dass die rechte Seite nicht gestört ist: δb = 0. Dann gilt für dieLösung x sowie die gestörte Lösung x und den Fehler δx := x− x:

(A+ δA)x = b

(A+ δA)x = b+ δAx⇒ δx = −[A+ δA]−1δAx.

108 ©2018 Thomas Richter

Page 115: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.2. Störungstheorie und Stabilitätsanalyse von linearen Gleichungssystemen

Da laut Voraussetzung ‖A−1δA‖ 6 ‖A−1‖ ‖δA‖ < 1, folgt mit Hilfssatz 6.22:

‖δx‖ 6 ‖[I+A−1δA]−1A−1δA‖ ‖x‖ 6 ‖A−1‖1 − ‖A−1δA‖

‖δA‖ ‖x‖

6cond2(A)

1 − ‖A−1‖‖δA‖‖δA‖‖A‖

‖x‖

Das Ergebnis erhalten wir durch Erweitern mit ‖A‖/‖A‖.

Diese beiden Störungssätze können einfach kombiniert werden, um gleichzeitig die Störungdurch rechte Seite und Matrix abschätzen zu können: {la:satz:stoerung}

Satz 6.24 (Störungssatz für lineare Gleichungssysteme). Es sei A ∈ Rn×n eine reguläre Matrix,b ∈ Rn die rechte Seite. Weiter sei x ∈ Rn die Lösung des linearen Gleichungssystems Ax = b

mit einer regulären Matrix A ∈ Rn×n. Für die Lösung x ∈ Rn des gestörten Systems Ax = b mitStörungen δb = b− b und δA = A−A gilt unter der Voraussetzung

‖δA‖ < 1

‖A−1‖

die Abschätzung‖δx‖‖x‖

6cond(A)

1 − cond(A)‖δA‖/‖A‖

(‖δb‖‖b‖

+‖δA‖‖A‖

)mit der Konditionszahl

cond(A) = ‖A‖ ‖A−1‖.

Beweis. Wir kombinieren die Aussagen von Satz 6.20 und 6.23. Hierzu sei x die Lösung vonAx = b, x die gestörte Lösung Ax = b und x die Lösung zu gestörter rechter Seite Ax = b.Dann gilt:

‖x− x‖ 6 ‖x− x‖+ ‖x− x‖ 6 cond(A)‖δb‖‖b‖‖x‖+ cond(A)

1 − cond(A)‖δA‖‖A‖

‖δA‖‖A‖

‖x‖.

Beachte ‖δA‖ < ‖A−1‖−1

0 6 cond(A)‖δA‖‖A‖

< ‖A‖ ‖A−1‖ 1

‖A‖ ‖A−1‖= 1.

Also gilt

cond(A) 6cond(A)

1 − cond(A)‖δA‖‖A‖

.

Damit folgt die Aussage.

Mit diesem Ergebnis kehren wir zum einführenden Beispiel aus Abschnitt 6 zurück:

A =

(0.988 0.9590.992 0.963

)⇒ A−1 ≈

(8302 −8267

−8552 8517

)

[email protected] 109

Page 116: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

In der maximalen Zeilensummennorm ‖ · ‖∞ gilt:

‖A‖∞ = 1.955, ‖A−1‖∞ ≈ 17069, cond∞(A) ≈ 33370.

Das Lösen eines linearen Gleichungssystems mit der Matrix A ist also äußerst schlecht kondi-tioniert. Hieraus resultiert der enormeRundungsfehler imBeispiel zu BeginndesKapitels.Wirhalten hier fest: Bei großer Konditionszahl ist die Konditionierung des Problems sehr schlecht,d.h., der große Fehler ist immanent mit der Aufgabe verbunden und nicht unbedingt auf einStabilitätsproblem des Verfahrens zurückzuführen.

6.3. Das Gaußsche Eliminationsverfahren und dieLR-Zerlegung

Das wichtigste Verfahren zum Lösen eines linearen Gleichungssystems Ax = b mit quadra-tischer Matrix A ∈ Rn×n ist das Gaußsche Eliminationsverfahren: Durch Elimination derEinträge unterhalb der Diagonale wird die MatrixA ∈ Rn×n in den ersten n− 1 Schritten aufeine obere rechte Dreiecksgestalt gebracht:

∗ ∗ ∗ · · · ∗∗ ∗ ∗ ∗∗ ∗ ∗ ∗... . . . ...∗ ∗ ∗ · · · ∗

→∗ ∗ ∗ · · · ∗0 ∗ ∗ ∗0 ∗ ∗ ∗... . . . ...0 ∗ ∗ · · · ∗

→ · · · →∗ ∗ ∗ · · · ∗0 ∗ ∗ ∗0 0 ∗ ∗... . . . ...0 0 · · · 0 ∗

Mit der rechten oberen Dreiecksmatrix R ∈ Rn×n (R = (rij)

ni,j=1 mit rij = 0 für i > j) kann

das reduzierte GleichungssystemRx = b,

durch Rückwärtseinsetzen gelöst werden, wobei b aus b durch Anwenden der Eliminations-schritte entsteht. Wir betrachten zunächst dieses Rückwärtseinsetzen:

{la:algo:rueck}Algorithmus 6.1: RückwärtseinsetzenEs sei R ∈ Rn×n eine reguläre rechte obere Dreiecksmatrix, d.h. rii 6= 0. Die Lösung x ∈ Rnvon Rx = b ist gegeben durch:

1 import numpy as np

2

3 def rueckwarts(R,b):

4 assert len(R) == len(b),"falsche Eingabegroesse!"

5 n = len(R)

6 x = np.zeros(n) # Ergebnisvektor

7 for i in reversed(range(n)): # Schleife von n−1 bis 08 x[i] = b[i]

9 for j in range(i+1,n): # Rueckwarts−Eliminieren10 x[i] = x[i] − R[i,j]∗x[j]11 x[i] = x[i] / R[i,i] # Durch Diagonale teilen

12 return x # Ergebnis zurueck

110 ©2018 Thomas Richter

Page 117: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

Wir benutzen hier zwei neue Strukturen in Python, einerseits die Anweisung assert, einepraktische Methode zur Überprüfung von Bedingungen die gelten müssen, wenn nicht einProgrammierfehler oder eine Fehl-Benutzung vorliegt. Die Bedeutung von assert BED,"text"↪→ ist etwa if not BED: print("text") sowie eine sofortige Beeingigung des Programms. Hierwird getestet, ob Matrix R und rechte Seite b die richtige Größe haben. Weiter verwendenwir das Schlüsselwort reversed, welches die Reihenfolge der Elemente in range umdreht. Statt0, 1, . . . ,n− 1 erhalten wir also die Sequenz n− 1,n− 2, . . . , 0.

Wir verwenden die Datenstrukturen aus numpy, jedoch ohne diese effzient einzusetzen. Etwaskryptisch, aber bei großenMatrizenweit schneller könntenwir Zeilen 9-10 ersetzen durch dieAnweisung

9 x[i] = x[i] − np.dot(R[i,i+1:n],x[i+1:n])

Es gilt: {la:satz:rueck}

Satz 6.25 (Rückwärtseinsetzen). Es sei R ∈ Rn×n eine rechte obere Dreiecksmatrix mit rii 6= 0.Dann ist die Matrix R regulär und das Rückwärtseinsetzen erfordert

NR(n) =n2

2+O(n)

elementare Operationen.

Beweis. Es gilt det(R) =∏rii 6= 0. Also ist die Matrix R regulär.

Jeder Schritt des Rückwärtseinsetzens besteht aus Additionen, Multiplikationen und Divisiondurch die Diagonalelemente. Bei rii 6= 0 ist jeder Schritt durchführbar.

Zur Berechnung von xi sind n−iMultiplikationen undAdditionen notwendig. Hinzu kommteine Division pro Schritt. Dies ergibt

n+

n−1∑i=1

(n− i) = n+ (n− 1)n−(n− 1)n

2=n2

2+n

2.

Die Transformation von A auf Dreiecksgestalt geschieht durch zeilenweise Elimination:

a11 a12 a13 . . . a1n

a21 a22 a23 . . . a2n

a31 a32 a33. . . a3n

...... . . . . . . ...

an1 an2 an3 . . . ann

a11 a12 a13 . . . a1n

0 a(1)22 a

(1)23 . . . a

(1)2n

0 a(1)32 a

(3)33

. . . a(1)3n

...... . . . . . . ...

0 a(1)n2 a

(1)n3 . . . a

(1)nn

a11 a12 a13 . . . a1n

0 a(1)22 a

(1)23 . . . a

(1)2n

0 0 a(2)33

. . . a(2)3n

...... . . . . . . ...

0 0 a(2)n3 . . . a

(2)nn

→ · · · → A(n−1) =: R

[email protected] 111

Page 118: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

Beginnend mit A(0) := A werden sukzessive Matrizen A(i) erzeugt mit A(n−1) =: R. Dabeiwird in Schritt i des Verfahrens die i-te Spalte vonA(i−1) unterhalb der Diagonalen eliminiert.Dies geschieht durch Subtraktion des g(i)k -Fachen der i-ten Zeile von der k-ten. Hierbei gilt fürk = i+ 1, . . . ,n

g(i)k :=

a(i−1)ki

a(i−1)ii

,

und die neue Zeile berechnet sich zu

a(i)kj = a

(i−1)kj − g

(i)k a

(i−1)ij , k = i+ 1, . . . ,n, j = i, . . . ,n.

Damit diese Vorschrift durchgeführt werden kann, muss stets a(i−1)ii 6= 0 gelten. Dies folgt

nicht zwingend aus der Regularität vonA und allerA(i). Wir gehen zunächst davon aus, dassa(i−1)ii 6= 0 erfüllt ist, und kommen später auf den allgemeinen Fall zurück. Im i-ten Eliminati-

onsschritt bleiben die ersten i−1 Zeilen und Spalten unverändert. Der i-te Eliminationsschrittlässt sich kompakt in Form einer Matrix-Matrix-Multiplikation

A(i) = F(i)A(i−1)

schreiben mit der Eliminationsmatrix (alle nicht spezifizierten Einträge sind null):

F(i) :=

1. . .

1

−g(i)i+1

. . .... . . .

−g(i)n 1

, g

(i)k :=

a(i−1)ki

a(i−1)ii

.

Mehrfache Anwendung von Eliminationsmatrizen führt zu der Darstellung:

R = A(n−1) = F(n−1)A(n−2) = F(n−1)F(n−2)A(n−3) = F(n−1) · · · F(1)︸ ︷︷ ︸=:F

A(0) = FA. (6.5){la:gauss:1}{la:gauss:1}

Matrizen mit der Gestalt der Eliminationsmatrizen F(i) heißen Frobenius-Matrizen. Es gilt derfolgende Satz:{la:satz:frobenius}

Satz 6.26 (Frobenius-Matrix). Jede Frobenius-Matrix F(i) ∈ Rn×n ist regulär und es gilt:

F(i) :=

1. . .

1

−gi+1. . .

... . . .−gn 1

⇒ [F(i)]−1 :=

1. . .

1

gi+1. . .

... . . .gn 1

112 ©2018 Thomas Richter

Page 119: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

Für zwei Frobenius-Matrizen F(i1) und F(i2) mit i1 < i2 gilt:

F(i1)F(i2) = F(i1) + F(i2) − I =

1. . .

1

−g(i1)i1+1 1... . . .... 1... −g

(i2)i2+1

. . ....

... . . .−g

(i1)n −g

(i2)n 1

.

Beweis. Dies folgt durch komponentenweises Nachrechnen.

Bei der Multiplikation von Frobenius-Matrizen ist darauf zu achten, dass diese nicht kommu-tativ ist. Es gilt:

F(i2)F(i1) 6= F(i1) + F(i2) − I für i1 < i2

Aus dem Multiplikationsverhalten von Frobenius-Matrizen können wir für i1 < i2 < i3 eineeinfache Verallgemeinerung ableiten:

F(i1)F(i2)F(i3) = F(i1)(F(i2) + F(i3) − I) = F(i1)F(i2) + F(i1)F(i3) − F(i1)

= F(i1) + F(i2) − I+ F(i1) + F(i3) − I− F(i1)

= F(i1) + F(i2) + F(i3) − 2I

Wir setzen nun (6.5) fort undmit F−(i) := [F(i)]−1 gilt bei Verwendung von Satz 6.26 zunächst,dass F als Produkt von regulären Matrizen selbst regulär ist. Also folgt:

A = F−1R = [F(n−1) · · · F(1)]−1R = F−(1) · · · F−(n−1)︸ ︷︷ ︸=:L

R

Die Matrix L ist nach der Verallgemeinerung von Satz 6.26 eine untere Dreiecksmatrix mitDiagonaleinträgen 1:

L =

1

g(1)2 1

g(1)3 g

(2)3 1

g(1)4 g

(2)4 g

(3)4 1

...... . . . . . . . . .

g(1)n g

(2)n · · · · · · g(n−1)

n 1

Wir fassen zusammen:

[email protected] 113

Page 120: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

{la:satz:lr}

Satz 6.27 (LR-Zerlegung). Es sei A ∈ Rn×n eine quadratische, reguläre Matrix. Angenommen,alle bei der Elimination auftretenden Diagonalelemente a(i−1)

ii seien ungleich null. Dann existiert dieeindeutig bestimmte LR-Zerlegung in eine rechte obere reguläre Dreiecksmatrix R ∈ Rn×n sowie ineine linke untere reguläre Dreiecksmatrix L ∈ Rn×n mit Diagonaleinträgen 1. Der Aufwand zurDurchführung der LR-Zerlegung beträgt

1

3n3 +O(n2)

elementare Operationen.

Beweis. (i) Eindeutigkeit. Angenommen, es existieren zwei LR-Zerlegungen

A = L1R1 = L2R2 ⇔ L−12 L1 = R2R

−11 .

Das Produkt von Dreiecksmatrizen ist wieder eine Dreiecksmatrix, also müssen beide Pro-dukte Diagonalmatrizen sein. Das Produkt L−1

2 L1 hat nur Einsen auf der Diagonale, also folgt

L−12 L1 = R2R

−11 = I,

und somit L1 = L2 und R1 = R2.

(ii) Durchführbarkeit. Jeder Schritt der Elimination ist durchführbar, solange nicht durcha(i−1)ii =

0 geteilt werden muss. Die Matrix F ist per Konstruktion regulär und somit existiert auch dieMatrix L.

(iii) Aufwand. Im i-ten Eliminationsschritt

A(i) = F(i)A(i−1)

sind zunächst n − i arithmetische Operationen zur Berechnung der g(i)j für j = i + 1, . . . ,nnotwendig. Die Matrix-Matrix-Multiplikation betrifft nur alle Elemente akl mit k > i sowiel > i. Es gilt

a(i)kl = a

(i−1)kl − g

(i)k a

(i−1)il , k, l = i+ 1, . . . ,n.

Hierfür sind (n−i)2 arithmetische Operationen notwendig. Insgesamt summiert sich der Auf-wand in den n− 1 Schritten zu:

NLR(n) =

n−1∑i=1

(n− i+ (n− i)2

)=

n−1∑i=1

(i+ i2

),

und mit den bekannten Summenformeln folgt:

NLR(n) =n3

3+n

3

Die LR-Zerlegung kann zum Lösen von linearen Gleichungssystemen verwendet werden:

114 ©2018 Thomas Richter

Page 121: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

Algorithmus 6.2: Lösen von linearen Gleichungssystemen mit der LR-ZerlegungEs sei A ∈ Rn×n eine reguläre Matrix, für welche die LR-Zerlegung existiert.

1 Erstelle LR−Zerlegung A = LR2 Vorwärtseinsetzen: Ly = b3 Rückwärtseinsetzen: Rx = y

Die Vorwärtselimination läuft entsprechend des Rückwärtseinsetzens in Algorithmus 6.1 undgemäß Satz 6.25 benötigt sie O(n2) Operationen. Das eigentliche Lösen eines linearen Glei-chungssystems ist also weit weniger aufwendig als das Erstellen der Zerlegung. In vielen An-wendungsproblemen, etwa bei der Diskretisierung von parabolischen Differentialgleichun-gen, müssen sehr viele Gleichungssysteme mit unterschiedlichen rechten Seiten, aber identi-schenMatrizen hintereinander gelöst werden. Hier bietet es sich an, die Zerlegung nur einmalzu erstellen und dann wiederholt anzuwenden.

Bemerkung 6.28 (PraktischeAspekte). DieMatrix L ist eine linke untereDreiecksmatrixmit Einsenauf der Diagonale. Die bekannten Diagonalelemente müssen demnach nicht gespeichert werden. Ebensomüssen die Nullelemente derMatrizenA(i) unterhalb der Diagonale nicht gespeichert werden. Es bietetsich an, die Matrizen L und R in der gleichen quadratischen Matrix zu speichern. In Schritt i gilt dann:

A(i) =

a11 a12 a13 · · · · · · · · · a1n

l21 a(1)22 a

(1)23

...

l31 l32 a(2)33

. . . ...... . . . . . . ...... li+1,i a

(i)i+1,i+1 · · · a(i)i+1,n

...... . . . ...

ln1 ln2 · · · ln,i a(i)n,i+1 . . . a

(i)nn

Dabei sind die fett gedruckten Werte die Einträge von L. Die Werte oberhalb der Linie ändern sich imVerlaufe des Verfahrens nicht mehr und bilden bereits die Einträge L sowie R.

Da die LR-Zerlegung an Ort und Stelle eine besondere Bedeutung einnimmt, geben wir hierden entsprechenden Algorithmus an:

{listing:lr}Algorithmus 6.3: LR-Zerlegung einer Matrix A ohne ZusatzspeicherEs sei A = (aij)ij ∈ Rn×n eine reguläre Matrix, deren LR-Zerlegung existiert

1 import numpy as np

2

3 def LR(A):

4 for i in range(n):

5 assert not(A[i,i] == 0),"Pivot−Element ist Null!"6 for k in range(i+1,n):

7 A[k,i] = A[k,i]/A[i,i]

8 for j in range(i+1,n):

9 A[k,j] = A[k,j] − A[k,i]∗A[i,j]

[email protected] 115

Page 122: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.3. Das Gaußsche Eliminationsverfahren und die LR-Zerlegung

Algorithmus 6.3 arbeitet mit den Elementen der Eingabematrix A selbst. Diese wird verän-dert und enthält schließlich die Matrizen L (bis auf die Diagonale) und R. numpy arrays sindmutable-Datentypen, sie können also ihren Wert ändern. siehe hierzu auch Bemerkung 2.5 inAbschnitt 2.1. Es handelt sich also um Call by Reference, die Ergebnis-Matrix muss nicht mit-tels return Anweisung als Kopie zurückgegeben werden. Gerade bei sehr großen Matrizen istdieses Verhalten aus Speichergründen natürlich sehr wichtig. Auch dieser Algorithmus kanndurch entsprechende Nutzung von numpy-Mechanismen stark beschleunigt werden.

Das Element a(i−1)ii wird das Pivot-Element genannt. Da wir durch dieses Element teilen müs-

sen überprüfen wir, dass es stets ungleich Null ist. Dies ist jedoch für reguläre Matrizen nichtzwingend notwendig. Wir betrachten als Beispiel die Matrix

A :=

1 4 22 8 11 2 1

.

Im ersten Schritt zur Erstellung der LR-Zerlegung ist a(0)11 = 1 und es gilt:

A(1) = F(1)A =

1 0 0−2 1 0−1 0 1

1 4 22 8 11 2 1

=

1 4 20 0 −30 −2 −1

Andieser Stelle bricht derAlgorithmus ab, denn es gilta(1)22 = 0.Wir könnten denAlgorithmusjedoch mit der Wahl a(i)32 = −2 als neues Pivot-Element weiterführen. Dies geschieht systema-tisch durch Einführen einer Pivotisierung. Im i-ten Schritt des Verfahrens wird zunächst eingeeignetes Pivot-Element aki in der i-ten Spalte mit k > i gesucht. Die k-te und i-te Zeile wer-den getauscht und die LR-Zerlegung kann weiter durchgeführt werden. Für weitere Detailsverweisen wir auf die Literatur, z.B. [11].

Die LR-Zerlegung ist eines der wichtigsten direkten Verfahren zum Lösen von linearen Glei-chungssystemen. Der Aufwand zur Berechnung der LR-Zerlegung steigt allerdingsmit dritterOrdnung sehr schnell. Selbst auf modernen Computern übersteigt die Laufzeit für große Glei-chungssysteme schnell eine sinnvolle Grenze:

n Operationen (≈ 13n

3) Zeit LR-Zerlegung

100 300 · 103 30 µs1 000 300 · 106 30 ms10 000 300 · 109 30 s

100 000 300 · 1012 10 h1 000 000 300 · 1015 1 Jahr

Tabelle 6.1.: la:tab:lr-zeitRechenzeit zum Erstellen der LR-Zerlegung einer Matrix A ∈ Rn×n auf einemRechner mit 10 GigaFLOPS bei optimaler Auslastung

Bei der Diskretisierung von partiellen Differentialgleichungen treten Gleichungssysteme mitn = 106 ∼ 109 auf. Die Matrizen verfügen dann aber über Struktureigenschaften wie Sym-metrie oder über ein besonders dünnes Besetzungsmuster (in jeder Zeile sind nur einige we-nige Einträge ungleich null). Die linearen Gleichungssysteme, die bei der Finite-Elemente-

116 ©2018 Thomas Richter

Page 123: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.4. Die Cholesky-Zerlegung für positiv definite Matrizen

Diskretisierung der Laplace-Gleichung (beschreibt z.B. die Auslenkung einer Membran) ent-stehen haben bei entsprechender Diskretisierung unabhänging von n nur fünf Einträge proZeile. Die so entstehenden linearen Gleichungssysteme lassen sich bei effizienter Implemen-tierung der LR-Zerlegung auch bei n = 1 000 000 in weniger als einer Minute lösen.

6.4. Die Cholesky-Zerlegung für positiv definiteMatrizen

{sec:cholesky}

Nicht jede reguläre Matrix A ∈ Rn×n erlaubt eine Zerlegung der Art A = LR. Ob Pivotisie-rung notwendig ist, wird meist erst im Lauf der Zerlegung ersichtlich. Eine wichtige KlassevonMatrizen sind die positiv definitenMatrizen, siehe Definition 6.15 sowie Satz 6.16. Es zeigtsich, dass für symmetrisch positiv definite Matrizen A ∈ Rn×n eine symmetrische ZerlegungA = LLT in eine untere Dreiecksmatrix L erstellt werden kann. Diese ist immer ohne Pivoti-sierung durchführbar und wird Cholesky-Zerlegung genannt. Der Aufwand zum Erstellen derCholesky-Zerlegung ist erwartungsgemäß nur halb so groß wie der Aufwand zum Erstellender LR-Zerlegung.

Satz 6.29 (LR-Zerlegung einer positiv definiten Matrix). Die Matrix A ∈ Rn×n sei symmetrischpositiv definit. Dann existiert eine eindeutige LR-Zerlegung ohne Pivotisierung.

Beweis. Wir führen den Beweis per Induktion. Dazu sei A eine symmetrisch positiv definiteMatrix. Ein Schritt der LR-Zerlegung ist durchführbar, da laut Satz 6.16a11 > 0 gilt.Wir zeigen,dass die Teilmatrix Aij>1 nach einem Eliminationsschritt wieder symmetrisch positiv definitist. Es gilt aufgrund der Symmetrie von A:

aij = aij −a1jai1

a11= aji −

a1iaj1

a11= aji,

d.h., Aij>1 ist symmetrisch. Nun sei x ∈ Rn ein Vektor x = (x1, x) ∈ Rnmit x = (x2, . . . , xn) ∈Rn−1 beliebig. Den Eintrag x1 werden wir im Laufe des Beweises spezifizieren. Es gilt wegender positiven Definitheit von A:

0 < (Ax, x) =∑ij

aijxixj = a11x21 + 2x1

n∑j=2

a1jxj +

n∑i,j=2

aijxixj

= a11x21 + 2x1

n∑j=2

a1jxj +

n∑i,j=2

(aij −

a1jai1

a11

)︸ ︷︷ ︸

=aij

xixj +

n∑i,j=2

a1jai1

a11xixj

= a11

x21 + 2x11

a11

n∑j=2

a1jxj +1

a211

n∑i,j=2

a1jai1xixj

+

n∑i,j=2

aijxixj

= a11

x1 + 1

a11

n∑j=2

a1jxj

2

+ (Ai,j>1x, x)

[email protected] 117

Page 124: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.4. Die Cholesky-Zerlegung für positiv definite Matrizen

Die positive Definitheit von Aij>1 folgt somit bei der Wahl

x1 = −1

a11

n∑j=2

a1jxj.

Für eine symmetrisch positiv definiteMatrixA ist die LR-Zerlegung immer ohne Pivotisierungdurchführbar. Dabei treten nur positive Pivot-Elemente a(i−1)

ii auf. Das heißt, die Matrix R hatnur positive Diagonalelemente rii > 0. Es seiD ∈ Rn×n die Diagonalmatrix mit dii = rii > 0.Dann gilt

A = LR = LDR

mit einer rechten oberen Dreiecksmatrix R, welche nur Einsen auf der Diagonalen hat. Da Asymmetrisch ist, folgt:

A = LR = LDR = RTDLT = AT

Aufgrund der Eindeutigkeit der LR-Zerlegung gilt L = RT und R = DLT . Da D nur positiveDiagonaleinträge hat, existiert die Matrix

√D und wir schreiben:

A = LR = LD12︸︷︷︸

=:L

D− 12 R︸ ︷︷ ︸

=LT

Wir fassen zusammen:

Satz 6.30 (Cholesky-Zerlegung). Es seiA ∈ Rn×n eine symmetrisch positiv definite Matrix. Dannexistiert die Cholesky-Zerlegung

A = LLT

in eine untere linke Dreiecksmatrix L. Sie kann ohne Pivotisierung in

n3

6+O(n2)

elementaren Operationen durchgeführt werden.

Anstelle eines Beweises gebenwir einen effizienten Algorithmus zur direkten Berechnung derCholesky-Zerlegung an. Hier kann der notwendige Aufwand leicht aus demKoeffizientenver-gleich bei A = LT L abgelesen werden:

{algo:cholesky}Algorithmus 6.4: Direkte Berechnung der Cholesky-ZerlegungGegeben sei eine symmetrisch positiv definite Matrix A ∈ Rn×n. Dann sind die Einträge lij,j 6 i der Cholesky-Zerlegung bestimmt durch die Vorschrift:

1 def cholesky(A):

2 n = len(A)

3 L = np.zeros( (n,n) )

4 for j in range(n):

5 L[j,j] = A[j,j]

6 for k in range(j):

7 L[j,j] = L[j,j] − L[j,k]∗L[j,k]8 L[j,j] = np.sqrt(L[j,j])

118 ©2018 Thomas Richter

Page 125: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.5. Dünn besetzte Matrizen und Bandmatrizen

9 for i in range(j+1,n):

10 L[i,j] = A[i,j]

11 for k in range(j):

12 L[i,j] = L[i,j]−L[i,k]∗L[j,k]13 L[i,j] = L[i,j] / L[j,j]

Der Algorithmus kann iterativ aus der Beziehung LLT = A hergeleitet werden. Es gilt:

aij =

min{i,j}∑k=1

likljk

Wir gehen Spaltenweise für j = 1, 2, . . . ,n vor. Das heißt, L sei für alle Spalten bis j−1 bekannt.Dann gilt in Spalte j für das Diagonalelement:

ajj =

j∑k=1

l2jk ⇒ ljj =

√√√√ajj − j−1∑k=1

l2jk

Ist das j-te Diagonalelement ljj bekannt, so gilt für i > j:

aij =

j∑k=1

likljk ⇒ lijljj = aij −

j−1∑k=1

likljk

⇒ lij = l−1jj

(aij −

j−1∑k=1

likljk

)

6.5. Dünn besetzte Matrizen und Bandmatrizen{sec:duenn}

Der Aufwand zum Erstellen der LR-Zerlegung wächst sehr schnell mit der Größe der Matrixan. In vielen Anwendungsproblemen treten, wie oben bereits angerissen, dünn besetzte Matri-zen auf:

Definition 6.31 (Dünn besetzte Matrix). Eine Matrix A ∈ Rn×n heißt dünn besetzt, falls dieMatrix A nur O(n) von null verschiedene Einträge besitzt. Das Besetzungsmuster (im Englischensparsity pattern) B ⊂ {1, . . . ,n}2 von A ist die Menge aller Indexpaare (i, j) mit aij 6= 0.

Andere, weniger strengeDefinitionen von dünn besetztenMatrizen verlangen, dass dieMatrixO(n log(n)) oder auchO(n

√n) beziehungsweise einfach o(n2) von null verschiedene Einträge

besitzt.

Ein Beispiel für dünn besetzte Matrizen sind Tridiagonalmatrizen der Form

A ∈ Rn×n, aij = 0 ∀|i− j| > 1.

Für Tridiagonalmatrizen kann die LR-Zerlegung sehr effizient durchgeführt werden: {la:satz:thomas}

Satz 6.32 (Thomas-Algorithmus). Es seiA ∈ Rn×n eine reguläre Tridiagonalmatrix. Die MatrizenL und R der LR-Zerlegung von A sind wieder Tridiagonalmatrizen und können in O(n) Operationenerstellt werden.

[email protected] 119

Page 126: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.5. Dünn besetzte Matrizen und Bandmatrizen

Beweis. Folgt aus Satz 6.34.

Eine Verallgemeinerung von Tridiagonalsystemen sind die Bandmatrizen:{def:bandmatrix}

Definition 6.33 (Bandmatrix). Eine MatrixA ∈ Rn×n heißt Bandmatrixmit Bandbreitem ∈ N,falls

aij = 0 ∀|i− j| > m.

Eine Bandmatrix hat höchstens n(2m+ 1) von null verschiedene Einträge.

Es zeigt sich, dass die LR-Zerlegung einer Bandmatrix wieder eine Bandmatrix ist und dahereffizient durchgeführt werden kann.{la:satz:lr-band}

Satz 6.34 (LR-Zerlegung einer Bandmatrix). Es seiA ∈ Rn×n eine Bandmatrix mit Bandbreitem.Die LR-Zerlegung (ohne Permutierung)

LR = A

ist wieder eine Bandmatrix, d.h.

Lij = Rij = 0 ∀|i− j| > m,

und kann inO(nm2)

Operationen durchgeführt werden.

Beweis. Übung.

Der Unterschied, eine LR-Zerlegung für eine voll besetzte Matrix und eine Bandmatrix durch-zuführen, ist enorm. Zur Diskretisierung der Laplace-Gleichung mit finiten Differenzen müs-sen lineare Gleichungssysteme mit der sogenanntenModellmatrix gelöst werden:

A =

Am −Im 0 · · · 0

−Im Am −Im...

0 −Im. . . . . . 0

... . . . . . . −Im0 · · · 0 −Im Am

, Am =

4 −1 0 · · · 0

−1 4 −1...

0 −1. . . . . . 0

... . . . . . . −10 · · · 0 −1 4

(6.6){modellmatrix}{modellmatrix}

Die Matrix A ∈ Rn×n (für eine Quadratzahl n) hat die Bandbreite m =√n. In Tabelle 6.2

geben wir die notwendigen Rechenzeiten zum Erstellen der LR-Zerlegung auf aktueller Hard-ware an. Man vergleiche mit Tabelle 6.1.

Die Modellmatrix ist eine Bandmatrix mit Bandbreite m =√n, hat aber in jeder Zeile neben

demDiagonalelement höchstens vier von null verschiedene Einträge ai,i±1 und ai,i±m. Bei sodünn besetztenMatrizen stellt sich die Frage, ob die LR-Zerlegung, also die Matrizen L und R,das gleiche dünne Besetzungsmuster haben. Es zeigt sich jedoch, dass die LR-Zerlegung einerdünn besetzten Bandmatrix im schlechtesten Fall selbst eine dicht besetzte Bandmatrix ist.

Der Aufwand zur Berechnung der LR-Zerlegung einer dünn besetzten Matrix hängt wesent-lich von der Sortierung, also der Pivotisierung der Matrix ab. Wir betrachten hierzu ein einfa-ches Beispiel:

120 ©2018 Thomas Richter

Page 127: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.5. Dünn besetzte Matrizen und Bandmatrizen

n Operationen Zeit (Bandstruktur) Zeit (voll besetzt)

100 105 1 µs 30 µs1 000 106 100 µs 30 ms10 000 108 10 ms 30 s

100 000 1010 1 s 10 h1 000 000 1012 2 min 1 Jahr

Tabelle 6.2.: la:tab:lr-zeit1Rechenzeit zum Erstellen der LR-Zerlegung einer Bandmatrix A ∈ Rn×n mitBandbreite m =

√n auf einem Rechner mit 10 GigaFLOPS. Zum Vergleich die

Zeiten für eine voll besetzte Matrix, siehe Tabelle 6.1.

Beispiel 6.35 (LR-Zerlegung einer dünn besetzten Matrix). Wir betrachten die beiden Matrizen:

A1 :=

1 2 3 42 1 0 03 0 1 04 0 0 1

, A2 :=

1 0 0 40 1 0 30 0 1 24 3 2 1

.

Die beidenMatrizen gehen durch simultanes Vertauschen der ersten und vierten sowie der zweiten unddritten Zeile und Spalte auseinander hervor. Es gilt:

PTA1P =

0 0 0 10 0 1 00 1 0 01 0 0 0

1 2 3 42 1 0 03 0 1 04 0 0 1

0 0 0 10 0 1 00 1 0 01 0 0 0

=

1 0 0 40 1 0 30 0 1 24 3 2 1

= A2

Die LR-Zerlegung der Matrix A1 (ohne Pivotisierung) lautet:

L1 =

1 0 0 02 1 0 03 2 1 04 8

3 1 1

R1 =

1 2 3 40 −3 −6 −80 0 4 40 0 0 7

3

und für die Matrix A2 erhalten wie (wieder ohne Pivotisierung)

L2 =

1 0 0 00 1 0 00 0 1 04 3 2 1

R2 =

1 0 0 40 1 0 30 0 1 20 0 0 −28

Obwohl beide Matrizen bis auf Zeilen- und Spaltentausch das gleiche lineare Gleichungssystem be-schreiben, haben die LR-Zerlegungen ein gänzlich unterschiedliches Besetzungsmuster: Die LR-Zerlegungvon Matrix A1 ist voll besetzt, während die LR-Zerlegung zu Matrix A2 mit dem gleichen dünnen Be-setzungsmuster auskommt wie die Matrix A2 selbst.

Dieses Beispiel lässt sich auf die entsprechende n×n-Matrix verallgemeinern. In Fall 1 sind n2 Einträ-ge zum Speichern der LR-Zerlegung notwendig, in Fall 2 nur 3n. Für n� 1 000 ist dieser Unterschiedentscheidend. Die Anzahl der benötigten Operationen unterscheidet sich in beiden Fällen noch wesent-licher.

[email protected] 121

Page 128: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.5. Dünn besetzte Matrizen und Bandmatrizen

Dünn besetzte Matrizen treten in der Anwendung oft auf, etwa bei der Diskretisierung vonDifferentialgleichungen, aber auch bei der Berechnung von kubischen Splines. Damit die LR-Zerlegung aus der dünnen Besetzungsstruktur Nutzen ziehen kann, muss die Matrix entspre-chend permutiert (man spricht in diesem Zusammenhang auch von der “Sortierung der Un-bekannten”) sein. Werden Nulleinträge in A in der LR-Zerlegung überschrieben, so sprichtman von fill-ins. Die aktuelle Forschung zurWeiterentwicklung der LR-Zerlegung befasst sichweniger mit der Berechnung der LR-Zerlegung selbst als mit effizienten Sortierverfahren zurReduktion der fill-ins. Wir wissen, dass die LR-Zerlegung einer Bandmatrix mit Bandbreitem wieder eine (voll besetzte) Bandmatrix mit Bandbreite m ist und in O(nm2) Operationendurchgeführt werden kann. Eine Idee zur Sortierung der Matrix A besteht nun darin, die Ein-träge so anzuordnen, dass die sortierte Matrix eine Bandmatrix mit möglichst dünner Band-breite ist. Wir verweisen auf die Literatur [11].

122 ©2018 Thomas Richter

Page 129: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.5. Dünn besetzte Matrizen und Bandmatrizen

6.5.1. Parallele LR-Zerlegung

Die Leistungsfähigkeit von Computer steigt beständig. Gordon Moore, ein US-Ingenieur undChipentwickler postulierte 1965, dass sich die Anzahl von Bauteilen (z.B. Transistoren) in Pro-zessoren etwa alle 2 Jahre verdoppelt, dies ist als Moore’s Law3 bekannt und hat sich in denletzten 40 Jahren als sehr zutreffend erwiesen:

Die Anzahl an Transitoren ist nicht gleichbedeutend mit der Geschwindigkeit der Prozesso-ren, da noch andere Faktoren im Design eine große Rolle spielen. Im wesentliche können wiraber davon ausgehen, dass die Entwicklung der Geschwindigkeit, gemessen in Floating PointOperations per Second (FLOPS) entsprechend verläuft, siehe Tabelle 6.3mit einer Übersicht überverschiedene Computer im Laufe der Jahre. Ein Computer rechnet in Takten und jede Operati-on benötigt eine bestimmte Anzahl von Takten. Im Laufe der Jahre ist einerseits die Effizienzgestiegen, d.h. eine Multiplikation kann nun in einem Takt durchgeführt werden, hat früheraber über 5 Takte gebraucht. Auf der andereren Seite ist die Taktfrequenz, also die Anzahl derTakte pro Sekunde stark gestiegen und liegt bei aktuellen Prozessoren zwischen 2 und 4 GHz(G = 109). Der Intel 8086 hatte im Jahr 1978 eine Taktrate von 4.77 MHz (M = 106). Diese Ent-wicklung stimmt noch nicht mit Moore’s Law überein. Die Taktrate hat sich in etwa 40 Jahrenumden Faktor 700 erhöht, die Anzahl der Bauteile (und etwa die Leistungsfähigkeit) ist im sel-ben Zeitraum ummehr als den Faktor 100 000 gestiegen. Auch wenn man eine Steigerung der3Moore’s Law: https://de.wikipedia.org/wiki/Mooresches_Gesetz

[email protected] 123

Page 130: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

CPU Jahr FLOPS Preis Energieverbrauch

Zuse Z3 1941 0.3 Einzelstücke 4 kWIBM 704 1955 5 · 103 >10 000 000 EUR 75 kWIntel 8086 + 8087 1980 50 · 103 2 000 EUR 200 Wi486 1991 1.4 · 106 2 000 EUR 200 WIPhone 4s 2011 100 · 106 500 EUR 10 W2 x Pentium III 2001 800 · 106 2 000 EUR 200 WCore i7 2011 100 · 109 1 000 EUR 200 WHelics I (Heidelberg) 2002 1 · 1012 1 000 000 EUR 40 kWNVIDIA GTX 580 (GPU) 2010 1 · 1012 500 EUR 250 WK Computer 2011 10 · 1015 > 500 000 000 EUR 12 000 kWNeumann (OVGU) 2016 100 · 1012 1 000 000 EUR ?Sunway TaihuLight 2016 93 · 1015 250 000 000 EUR 15 500 kWiPhone X 2017 325 · 109 1 000 EUR 5 WSummit 2018 122 · 1015 200 000 000 EUR 13 000 kW

Tabelle 6.3.: tab:compGleitkommageschwindigkeit sowie Anschaffungskosten einiger aktueller undhistorischer Computer. Mega M = 106, Giga G = 109, Terra T = 1012, PetaP = 1015, Exa E = 1018. Moderne Systeme varieren je nach Einsatzgebiet enorm.Das iPhone X ist etwas 3 mal schneller als eine Top-CPU im Jahr 2011, hat jedocheinen 40-fach niedrigeren Energiebedarf als diese.

Effizienz, vielleicht um den Faktor 10 hinzurechnet, liegen diese Zahlen weit auseinander. DerGrund liegt darin, dass moderne Prozessoren mehrere Recheneinheiten (Kerne) haben. Dereinzelne Kern wird nicht mehr exponentiell schneller, in der Gesamtheit steigt die Leistungjedoch weiterhin gemäß Moore’s Law an.

Damit diese Leistung in Algorithmen nutzbar ist, müssen Aspekte der Parallelisierung genutztwerden: Algorithmen müssen so angepasst werden, dass möglichst viele Rechenoperationenunabhängig von einander auf verschiedenen Kernen ausgeführt werden können. Eine guteParallelisierung von numerischen Verfahren ist sehr aufwendig. Es müssen Probleme betrach-tet werden, die bei einer rein mathematischen Sichtweise keine Rolle spielen. Ein Verfahrenkann gut sein auf einem bestimmten Computertyp, auf einem anderen jedoch vollkommenversagen. Für weiter gehende Studien verweisen wir auf die reichhaltige Literatur, sowohlüber theoretische Konzepte des parallelen Rechnens als auch über praktische Anwendungenund Tipps zur Umsetzung [10, 13].

6.6. Iterative Lösungsverfahren

Die in bisher kennengelernten Zerlegungsverfahren (also LR und Cholesky-Zerlegung) habenalle eine kubische Laufzeit (n3), oder, angewendet auf Bandmatrizen mit Bandbreite m eineLaufzeit von (nm2). Gerade bei sehr großen Problemen wächst der Aufwand so schnell an,dass die Lösung in sinnvoller Zeit nicht zu erreichen ist, siehe Tabelle 6.1. Neben der Laufzeitspielt der Speicheraufwand eine zentrale Rolle. Zur Speicherung einer voll besetzten Matrix

124 ©2018 Thomas Richter

Page 131: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

A ∈ Rn×n mit n = 1 000 000 sind bei doppelter Genauigkeit etwa 8 Terabyte Speicher not-wendig. Dies ist nur auf größten Parallelrechnern möglich. Direkte Zerlegungsroutinen wiedie LR-Zerlegung sind jedoch denkbar schlecht zur Parallelisierung geeignet. Handelt es sichum eine Bandmatrix mit Bandbreitem =

√n = 1 000 so sind es immer noch 8 Gigabyte.

Die linearen Gleichungssysteme, die aus den meisten Anwendungen resultieren (etwa bei derDiskretisierung von Differentialgleichungen), sind sehr dünn besetzt, d.h., in jeder Zeile ste-hen nur einigewenige Einträge. Eine dünn besetzteMatrixmitn = 1 000 000, aber nur 5Einträ-gen pro Zeile (wie die Modellmatrix) benötigt zur Speicherung nur etwa 40 MB und passt aufjeden Laptop. Das Problem an den Zerlegungsmethoden ist jedoch, dass zwar die EigenschaftBandmatrix erhalten bleibt, nicht aber die Eigenschaft dünn besetzt. Die Cholesky-Zerlegungder Modellmatrix ist zwar eine Bandmatrix, die Bänder sind aber fast alle voll besetzt. ZurVisualisierung in Python kann der Befehl matplotlib.pyplot.spy(A) verwendet werden, etwa

1 # ...

2 A = modellmatrix(100)

3 plt.spy(A)

4 plt.show()

5

6 L = cholesky(A)

7 plt.spy(L)

8 plt.show()

Ein weiterer Nachteil der Zerlegungsverfahren sind numerische Stabilitätsprobleme. DurchRundungsfehler beimZerlegungsprozess gilt für die LR-Zerlegung üblicherweise nurA 6= LR.Das heißt, obwohl die LR-Zerlegung eine direkte Methode darstellt, kann das Gleichungssys-tem nicht exakt gelöst werden.

In diesem Abschnitt werden wir eine neue Klasse von Lösungsverfahren für lineare Glei-chungssysteme herleiten, die sogenannten Fixpunktverfahren. Anstelle einer direkten Lösungwerden wir die Lösung x von Ax = b in einem iterativen Prozess

x0, x1, . . .

approximieren, d.h. wir entwickeln Folgen mit xk → x für k → ∞. Unzer Ziel wird es nichtmehr sein, die Lösung zu berechnen, wir werden die Lösung ledigleich annähern und denProzess bei xk stoppen, wenn die Genauigkeit ‖x− xk‖ hinreichend ist.

Es stellt sich nun die Frage nach einer auswertbaren Abschätzung für diesen Fehler, also eineAuswertung, die ohne die echte, aber unbekannte Lösung x auskommt. Ein erster Anhalts-punkt wird durch den Defekt gegeben:

Definition 6.36 (Defekt eines linearen Gleichungssystems). Es sei x ∈ Rn die Näherung zurLösung x ∈ Rn von Ax = b. Die Größe

d(x) := b−Ax,

bezeichnet den Defekt.

Für die exakte Lösung x ∈ Rn von Ax = b gilt d(x) = 0. Je genauer unsere Lösung ist, umsokleiner ist der Defekt. Für allgemeine Approximationen erhalten wir die folgende A-posteriori-Fehlerabschätzung:

[email protected] 125

Page 132: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

{la:satz:fehlerdefekt}

Satz 6.37 (Fehlerabschätzung für lineare Gleichungssysteme). Es sei A ∈ Rn×n eine reguläreMatrix und x ∈ Rn die Approximation zur Lösung x ∈ Rn von Ax = b. Dann gilt

‖x− x‖‖x‖

6 cond(A)‖d(x)‖‖b‖

.

Beweis. Es gilt

x− x = A−1(b−Ax) = A−1d(x) ⇒ ‖x− x‖ 6 ‖A−1‖ ‖d(x)‖.

Teilen durch ‖b‖ = ‖Ax‖ 6 ‖A‖ ‖x‖ liefert das gewünschte Ergebnis

‖x− x‖‖x‖

6 ‖A‖ ‖A−1‖ ‖d(x)‖‖b‖

.

Wenn wir den Defekt als Funktion d : Rn → Rn betrachten, so können wir die gesuchteLösung x ∈ Rn des linearen Gleichungssystems Ax = b auch als Suche nach einer Nullstelled(x) = 0 verstehen.

Definition 6.38 (Fixpunktabbildung). Es sei g : D ⊂ Rn → Rn eine Abbildung. Ein x ∈ Rn heißtFixpunkt von g, falls

g(x) = x.

In der Analysis gibt es zahlreiche Fixpunktsätze, die für gegebene Funktionen angeben, ob Fix-punkte existieren und ob diese vielleicht sogar eindeutig sind. Der bekannteste ist der Ba-nach’sche Fixpunktsatz

Satz 6.39 (Banach’scher Fixpunktsatz). Es sei g : M → M fürM ⊂ Rn stetige Abbildung. g seieine Selbstabbildung, d.h. g(M) ⊂M. Weiter sei g eine Kontraktion, d.h. g erfülle

‖g(x) − g(y)‖ 6 L‖x− y‖ ∀x,y ∈M

mit einer Konstante L < 1. Dann existiert genau ein eindeutiger Fixpunkt z ∈M mit g(z) = z.

Der Beweis wird in der Vorlesung Analysis 2 geführt.

Aufbauend auf diesem Satz werden wir nun Approximationsverfahren zum Lösen linearerGleichungssystem formulieren.

Definition 6.40 (Fixpunktverfahren zumLösen linearer Gleichungssysteme). Es seiA ∈ Rn×nsowie b ∈ Rn und C ∈ Rn×n eine beliebige Matrix. Für einen beliebigen Startwert x0 ∈ Rn iterierefür k = 1, 2, . . .

xk = xk−1 + C(b−Axk−1). (6.7){fix:la:fixpunkt}{fix:la:fixpunkt}

Alternativ führen wir die Bezeichnungen B := I− CA und c := Cb ein. Dann gilt

xk = Bxk−1 + c.

126 ©2018 Thomas Richter

Page 133: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

AufgrundderKonstruktion kannman sich leicht klarmachen, dass durch dieVorschrift g(x) =Bx+c = x+C(b−Ax)wirklich eine Fixpunktiterationmit der Lösung vonAx = b als Fixpunktgegeben ist, denn es gilt

xk = xk−1 + Cd(xk−1).

Gilt nun xk−1 = xmit Ax = b so ist d(x) = 0, also

xk = xk−1 + C0 = xk−1.

Die Konvergenz von linearen Fixpunktiterationen kann leichtmit demBanachschen Fixpunkt-satz untersucht werden: {satz:konv}

Satz 6.41. Es seiA,C ∈ Rn×n, b ∈ Rn und B := I−CA. Durch ‖·‖ sei eine natürliche Matrixnormsowie eine mit ihr verträgliche Vektornorm bezeichnet. Angenommen es gilt

‖B‖ 6 ρ < 1,

so konvergiert die Fixpunktiteration

xk = xk−1 + Cd(xk)

für jeden Startwert x0 ∈ Rn gegen die Lösung x des linearen Gleichungsystems Ax = b.

Beweis. (i)Wir weisen die Bedingungen des Banach’schen Fixpunktsatz nach. Hierzu sei

g(x) = x+ C(b−Ax).

Die Abbildung g ist Selbstabbildung von Rn → Rn. Weiter gilt für x,y ∈ Rn

‖g(x) − g(y)‖ = ‖x+ C(b−Ax) − y− C(b−Ay)‖ = ‖x− y− CA(x− y)‖= ‖(I− CA)(x− y)‖ 6 ‖I− CA‖ ‖x− y‖.

Angenommen nun ‖B‖ = ‖I − CA‖ 6 ρ < 1, so ist die Abbildung g eine Kontraktion, d.h. esexistiert genau ein Fixpunkt.

(ii) Nun sei x0 ∈ Rn ein beliebiger Startwert und x ∈ Rn der eindeutige Fixpunkt von g, dasheißt, es gilt g(x) = x. Dann folgern wir

‖xk − x‖ = ‖g(xk−1) − g(x)‖ 6 ρ‖xk−1 − x‖.

Wir können dieses Prinzip rekursiv anwenden und erhalten

‖xk − x‖ 6 ρ‖xk−1 − x‖ 6 ρ2‖xk−2 − x‖ 6 · · · 6 ρk‖x0 − x‖.

Wegen ρ < 1 gilt ρk → 0 für k→∞, also

limk→∞ ‖xk − x‖ = 0 ⇒ xk → x.

[email protected] 127

Page 134: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

Das Ergebnis liefert einerseits eine Konstruktionsvorschrift für allgemeine Iterationsverfahrenzur Lösung von linearen Gleichungssystemen, sogar eine Fehlerabschätzung mittels

‖xk − x‖ 6 ρk−1‖x1 − x‖ = ρk‖x0 − x‖.

Mit Satz 6.37 folgt‖xk − x‖‖x‖

6 ρk cond(A)‖d(x0)‖‖b‖

,

und falls wir als Startwert x0 = 0 wählen, so gilt d(x0) = 0 und wir erhalten

‖xk − x‖‖x‖

6 ρk cond(A).

Auf der anderen Seite ist das Ergebnis uneindeutig, da die Konvergenzrate ρ = ‖B‖ von dergewählten natürlichen Matrixnorm abhängt. Die Matrix

B =

(0.8 0.80.1 0.1

)z.B. erfüllt ‖B‖∞ = 1.6 aber ‖B‖1 = 0.9. Dies kann jedoch nicht bedeuten, dass die Iterationmal konvergiert, mal nicht, denn die Iterationsvorschrift selbst hängt ja gar nicht von derNormab. Vielmehr ist der Satz so zu lesen:

Bemerkung 6.42. Angenommen, es gibt eine Matrixnorm ‖ · ‖ mit zugehöriger verträglicher Vektor-norm, so dass Satz 6.41 mit ρmin = ‖B‖ < 1 erfüllt ist. Dann konvergiert die Iteration in jeder Normmit Rate ρmin. Dies folgt aus der Äquivalenz aller Normen im endlich dimensionalen VektorraumRn.

Es stellt sich jedoch die Frage nach der natürlichenMatrixnorm, in welcher dieMatrixB den minimalenWert ρmin annimmt. Es existiert jedoch keine allgemeine Norm, die stets den minimalen Wert liefert.Es kann jedoch gezeigt werden, dass es zu jeder Matrix B ∈ Rn×n und zu jedem ε > 0 eine Normnatürliche Matrixnorm ‖ · ‖ε gibt, so dass

spr(B) 6 ‖B‖ε 6 spr(B) + ε

gilt, wobei spr(B) der sogenannte Spektralradius der Matrix B ist, also der Betrag des größten Ei-genwerts von B. Für symmetrische Matrizen gilt spr(B) = ‖B‖2, die Spektralnorm ist also gerade dieoptimale Norm, die stets das beste Ergebnis liefert.

6.6.1. Konstruktion von Fixpunktverfahren

Satz 6.41 legt das theoretische Fundament für allgemeine Fixpunktiterationen. Für die (opti-male) natürliche Matrixnorm muss ρ = ‖B‖ = ‖I − CA‖ < 1 gelten. Ziel dieses Abschnitts istdie Konstruktion von Iterationsmatrizen C, welche

- möglichst nahe an der Inversen C ≈ A−1 liegen, damit ‖I − CA‖ = ‖(A−1 − C)A‖ 6‖A−1 − C‖ ‖A‖ � 1,

- eine möglichst einfache Berechnung der Iteration xk = Bxk−1 + c ermöglichen.

128 ©2018 Thomas Richter

Page 135: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

Die erste Forderung ist einleuchtend und C = A−1 stellt in diesem Sinne die optimale Ma-trix dar. Dann gilt ρ = 0. Die zweite Bedingung beschreibt den Aufwand zum Durchführender Fixpunktiteration. Wählen wir etwa C = R−1L−1 so bedeutet jeder Schritt ein Vorwärts-und ein Rückwärtseinsetzen, d.h. einen Aufwand der Größenordnung (n2). Hinzu kommendie (n3) Operationen zum einmaligen Erstellen der Zerlegung. Die Wahl C = I erlaubt ei-ne sehr effiziente Iteration mit (n) Operationen in jedem Schritt, ohne zusätzlichen Aufwandzum Aufstellen der Iterationsmatrix C. Die Einheitsmatrix I ist jedoch im Allgemeinen einesehr schlechte Approximation von A−1. Beide Forderungen sind Maximalforderungen undscheinen sich zu widersprechen. Die Wahl von C = I führt auf die Richardson-Iteration:

Definition 6.43 (Richardson-Iteration). Zur Lösung von Ax = b sei x0 ∈ Rn ein beliebiger Start-wert. Iteriere für k = 1, 2, . . .

xk = xk−1 +ω(b−Axk−1)

mit einem Relaxationsparameterω > 0.

Obwohl diese Iteration so einfach scheint, gilt der folgende Satz:

Satz 6.44 (Richardson-Iteration). Sei A ∈ Rn×n eine symmetrisch positiv definite Matrix. Dannexistiert einω > 0 mit

ρω := ‖I−ωA‖2 < 1.

Der Beweis ist einfach, benötigt aber das Konzept der Eigenwerte.

Zur Konstruktion weiterer einfacher iterativer Verfahren spalten wir die Matrix A additiv aufzu A = L+D+ Rmit

A =

0 . . . 0

a21. . .

... . . . . . .an1 . . . an,n−1 0

︸ ︷︷ ︸

=:L

+

a11 . . . 0

. . .. . .

0 . . . ann

︸ ︷︷ ︸

=:D

+

0 a12 . . . a1n

. . . . . . .... . . an−1,n

0 . . . 0

︸ ︷︷ ︸

=:R

.

Diese additive Zerlegung ist nicht mit der multiplikativen LR-Zerlegung zu verwechseln. Istdie Matrix A bekannt, so kann die additive Zerlegung in L,D,R ohne weitere Berechnungenangegeben werden.

Wir definieren die zwei wichtigsten Iterationsverfahren:

Definition 6.45 (Jacobi-Verfahren). Zur Lösung von Ax = b mit A = L +D + R sei x0 ∈ Rn einbeliebiger Startwert. Iteriere für k = 1, 2, . . .

xk = xk−1 +D−1(b−Axk−1)

bzw. mit der Jacobi-Iterationsmatrix J := −D−1(L+ R)

xk = Jxk−1 +D−1b.

[email protected] 129

Page 136: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

Definition 6.46 (Gauß-Seidel-Verfahren). Zur Lösung vonAx = bmitA = L+D+R sei x0 ∈ Rnein beliebiger Startwert. Iteriere für k = 1, 2, . . .

xk = xk−1 + (D+ L)−1(b−Axk−1)

bzw. mit der Gauß-Seidel-Iterationsmatrix H := −(D+ L)−1R

xk = Hxk−1 + (D+ L)−1b.

Für positiv definite Matrizen A kann wieder gezeigt werden, dass Jakabi- und Gauß-SeidelVerfahren konvergieren. Für die Konvergenzraten ρJ und ρGS gilt dann

ρGS = ρ2J.

Dies bedeutet, dass zum Erreichen der Toleranz tol beim Gauss-Seidel-Verfahren nur halbso viele Schritte notwendig sind, wie bei der Jakabi-Iteration. Die Definitionen scheinen nahezu legen, dass der Aufwand für das Gauß-Seidel-Verfahren weit höher ist, da eine linke untereDreiecksmatrix (D+L) invertiert werdenmuss. Eine genauereAnalyse zeigt jedoch, dass beideVerfahren den gleichen Aufwand erfordern (Übung).

6.6.2. Konvergenz von Fixpunktiterationen

Ist die Matrix A dünn besetzt, so ist ein Schritt von Jakobi- oder Gauß-Seidel-Verfahren sehreffizient durchführbar. Ein einfaches Experiment zeigt jedoch, dass die Anzahl der benötigtenSchritte zumErreichen einer vorgegebenenToleranz tol > 0mit derMatrixgröße steigt. Bei derModellmatrix erhalten wir zum Erreichen von tol = 10−4 die folgende Anzahl von benötigtenSchritten

n 25 100 400 1600Schritte 69 235 865 3299

Vergrößert sich n um den Faktor 4, so steigt auch die Anzahl der benötigten Schritte etwaum den Faktor 4. Angewendet auf die Modellmatrix bedeutet dies, dass die Komplexität zumLösen des linearen GleichungssystemsAx = bmit der Jakobi-Iteration also O(n2) beträgt. EinFaktor n durch die steigende Zahl der Schritte, ein Faktor n durch den Aufwand pro Schritt.Die Konvergenzrate ρ des Verfahrens hängt scheinbar von der Matrixgröße ab. Bei fester Ratekönnenwir die Anzahl der benötigten Schritte ktol zum Erreichen der Toleranz tol berechnenals

‖b− xktol‖∞ 6 ρktol ‖b‖∞︸ ︷︷ ︸=1

!< 10−4 ⇔ ktol log10(ρ)

!< −4 ⇔ ktol

!>

−4

log10(ρ),

da x0 = 0, und b = 1, und das Vorzeichen dreht sich schließlich um, da Konvergenz ρ < 1 alsolog10(ρ) < 0 voraussetzt.

Vergleichen mit dem Cholesky-Verfahren - bei Ausnutzen der Bandstruktur - zeigt sich alsokein direkter Vorteil. Hinzu kommt, dass das Gleichungssystem nicht im eigentlichen Sinnegelöst wurde, sondern nur approximiert.

130 ©2018 Thomas Richter

Page 137: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

Abschließend wollen wir nun analysieren, was der Grund für die schlechter werdende Kon-vergenzgeschwindigkeit ρ bei steigender Matrixgröße n ist. Zunächst stellen wir fest, dassdie Konvergenzrate ρ nicht unmittelbar von der Matrixgröße n selbst abhängen kann. Hierzumodifiziere man die Modellmatrix im Programm zur Konvergenzanalyse und betrachte eineentsprechende Matrix mit Diagonale Aii = 5. Die benötigte Anzahl von Schritten ktol (zumErreichen einer festen Toleranz) steigt nun nicht mehr, es ist ktol = O(1) und der Gesamtauf-wand sinkt auf O(n).

Bemerkung 6.47 (Optimales Verfahren zum Lösen linearer Gleichungssysteme). Es sei A ∈Rn×n eine dünn besetzte Matrix mit maximal d Einträgen pro Zeile. Kein Verfahren zur Approxima-tion der Lösung Ax = b kann die Komplexität O(nd) unterschreiten.

Die Idee ist offensichtlich: Jeder Eintrag der Matrix A hat eine potentielle Auswirkung auf dieLösung x. Es ist daher notwendig, jeden Eintrag der Matrix mindestens einmal in die Berech-nung der Lösung einfließen zu lassen. Somit muss der Aufwand mindestens O(nd) betragen.

1 import numpy as np

2 import time

3 import matplotlib.pyplot as plt

4

5 def modellmatrix(m):

6 n = m∗m7 A = np.diag(4∗np.ones(n)) # Diagonalen

8 for i in range(m):

9 for j in range(m−1):10 A[m∗i+j,m∗i+j+1]= −1.0 # rechte Nebendiagonale

11 A[m∗i+j+1,m∗i+j] = −1.0 # linke Nebendiagonale

12 if i>0: # linker Nebendiagonalblock

13 for j in range(m):

14 A[m∗(i−1)+j,m∗i+j] = −1.015 if i<m−1: # rechter Nebendiagonalblock

16 for j in range(m):

17 A[m∗(i+1)+j,m∗i+j] = −1.018 return A

19

20 def jakobi(A,b,tol): # Jacobi−iteration. x0=021 n = len(A)

22 x = np.zeros(n)

23 d = b−A@x # erstes residuum

24 res = np.max(np.abs(d)) # Norm von Defekt

25 X = np.array(res) # Fehler merken (fuer Ausgabe)

26 while res>tol: # Toleranz erfuellt?

27 x = x+1.0/np.diag(A)∗d # Ein Jakobi−Schritt28 d = b−A@x # neues Residuum

29 res = np.max(np.abs(d)) # Norm von Defekt

30 X = np.append(X,res) # Fehler merken

31 return [x,X]

32

33 for ex in range(5): # 4 Durchgaenge

[email protected] 131

Page 138: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

34 m = 2∗∗ex∗5 # Bandbreite und Matrixgroesse

35 n = m∗m36 A = modellmatrix(m) # Matrix und rechte Seite erstellen

37 b = np.ones(n)

38

39 [x,X] = jakobi(A,b,1.e−4)40

41 # Ausgabe der Konvergenzhistorie

42 plt.semilogy(X,label=’Jacobi, n=%d’ % n)

43

44 # Alternativ , doppelt−logarithmischer Plot45 #plt.loglog(X,label=’Jacobi, n=%d’ % n)

46

47 plt.legend() # Anzeige der labels

48 plt.show()

Wir betrachten zur Analyse ein vereinfachtes, aber eng verwandtes Problemmit der reduzier-ten Modellmatrix A ∈ Rn×n und

A =

2 −1 0 · · · 0

−1 2. . . . . . ...

0. . . . . . . . . 0

... . . . . . . 2 −10 · · · 0 −1 2

(6.8){modellmatrix:red}{modellmatrix:red}

Diese Matrix scheint - mit maximal 3 Einträgen pro Zeile - weit einfacher, es zeigt sich je-doch der gleiche Zusammenhang zwischen Matrixgröße und Anzahl der benötigten Jakobi-Schritten. Vergrößern wir hier den Diagonaleintrag von 2 auf zum Beispiel 3, so erhalten wirwieder stabile Konvergenz, mit einer Rate ρ < 1 die nicht von n abhängt. Mit Ad bezeichnenwir daher die allgemeine Matrix, mit der Diagonale Adii = d.

Zur Untersuchung der Konvergenz gemäß Satz 6.41 müssen wir die Matrix

Bd = I−D−1Ad

untersuchen. Hier gilt

Bd =1

d

0 1 0 · · · 0

1 0. . . . . . ...

0. . . . . . . . . 0

... . . . . . . 0 10 · · · 0 1 0

Zur Analyse der Konvergenzrate muss eine Norm ‖ · ‖ gefunden werden mit ρ := ‖Bd‖ < 1.In der maximalen Zeilensummen-Norm gilt

‖Bd‖∞ =2

d,

132 ©2018 Thomas Richter

Page 139: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

d.h. Konvergenz folgt beiρ∞ :=

2

d< 1 ⇔ d > 2.

Dieses Ergebnis lässt sich auch einfach auf die größere Modellmatrix übertragen, hier folgtKonvergenz bei d > 4. Weiter können wir dem Ergebnis ablesen, dass die Konvergenzrateunabhängig von der Matrixgröße n ist. Für z.B. d = 3 gilt

ρ =2

3,

und die Genauigkeit tol = 10−4 kann in(2

3

)ktol< 10−4 ⇔ ktol >

−4

log10(2/3)≈ 22.7,

d.h. in ktol = 23 Schritten erreicht werden. Für den Fall d = 2 (entsprechend dem Fall d = 4 inder ursprünglichen Modellmatrix) können wir auf Basis der maximalen Zeilensumme keineKonvergenz nachweisen.

Es zeigt sich, dass Konvergenz z.B. in der Spektralnorm

‖Bd‖2 = maxx∈Rn

‖Bdx‖2‖x‖2

,

basierend auf der euklidischen Norm nachgewiesen werden kann. {satz:norm:B}

Satz 6.48. Es sei B = I−D−1A ∈ Rn×n mit der vereinfachten Modellmatrix. Es gilt

‖B‖2 6 1 − O

(1

n2

).

Beweis. Für x ∈ Rn gilt

Bx =1

2

x2

x1 + x3...

xn−2 + xnxn−1

,

also

‖Bx‖22 =1

4

(x22 +

n−1∑i=2

(xi−1 + xi+1)2 + x2n−1

)

=1

4

(x21 +

n−1∑i=2

(x2i−1 + 2xi−1xi+1 + x

2i+1

)+ x2n−1

)

61

4

(x21 +

n−1∑i=2

2x2i + x2n +

n−1∑i=2

(εix

2i−1 + ε

−1i x

2i+1

))

61

4

((1 + ε2)x

21 + (2 + ε3)x

22 +

n−2∑i=3

(2 + εi+1 + ε

−1i−1

)x2i

+(2 + ε−1

n−2

)x2n−1 +

(1 + ε−1

n−1

)x2n

),

[email protected] 133

Page 140: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

wobei wir die Young’sche Ungleichungmit Parametern ε2, . . . , εn−1 > 0 verwendet haben. Esgilt nun, das Maximum

‖B‖22 = maxx∈Rn x 6=0

‖Bx‖22‖x‖22

zu berechnen und zu zeigen, dass dieses echt kleiner als 1 ist. Es sei nun x ∈ Rn ein Vektor,für den das Maximum angenommen wird.

Wir wählen nun die εi > 0 gemäß

εi =i+ 1

i,

mit der Eigenschaft

εi+1 + ε−1i−1 =

i+ 2

i+ 1+i− 1

i=

2i2 + 2i− 1

i2 + i= 2 −

1

2i2 + 2i.

Ferner gilt für die Randterme

1 + ε2 < 2, 2 + ε3 < 3, 2 + εn−2 < 3, 1 + εn−1 < 2.

Zusammen können wir folgern, dass

‖Bx‖22 6n∑i=1

(1 −

1

8(i2 + i)

)x2i 6

(1 −

1

8(n2 + n)

) n∑i=1

x2i ,

also

‖B‖2 6(

1 −1

8n2 + 8n

) 12

Mit der Ungleichung√

1 − h 6 1 −h

20 6 h < 1

folgt

‖B‖2 6 1 −1

16n2 + 16n=: ρn < 1.

Mit diesen Ergebnissen können wir Konvergenz der Jakobi-Iteration abschätzen.

Satz 6.49 (Konvergenz der Jakobi-Iteration). Es sei A die Modellmatrix (6.8). Die Jakobi-Iterationkonvergiert mit der Konvergenzrate

ρ = 1 − O

(1

n2

).

Zur Reduktion des Fehlers um eine feste Toleranz tol > 0 sind

ktol = O(n2)

Schritte notwendig, so dass der Gesamtaufwand O(n2) beträgt.

134 ©2018 Thomas Richter

Page 141: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

Beweis. Für die Matrix B gilt laut Satz 6.48

‖B‖2 6 ρn = 1 −1

16n2 + 16n6 1 −

1

32n2.

Der Faktor ρn ist gerade die Konvergenzrate im Jakobi-Verfahren in jedem Schritt. D.h. eineReduktion um tol ist in ktol Schritten gemäß

ρktoln < tol ⇔ ktol log(ρn) < log(tol)

zu erreichen. Wegen ρn < 1 folgt

ktol >− log(tol)

− log(ρn)

Weiter ist

− log(ρn) = − log

(1 −

1

32n2

)=

1

32n2+

1

2 · (32n2)2+

1

3 · (32n2)3+ · · · ,

daher sindktol > (− log(tol)) 32n2

Schritte notwendig.

Der Beweis kann einfach auf die originale Modellmatrix (6.6) mit Bandbreite m und n = m2

übertragen werden. Für diese gilt ρ = 1 − O(1/m2) = 1 − O(1/n).

Dieses erste iterative Lösungsverfahren kann selbst bei der einfachenModellmatrix dieCholesky-Zerlegung bei Ausnutzen der Bandstruktur nicht schlagen. In weiteren Untersuchungen ist esdas Ziel Verfahren mit den folgenden beiden Eigenschaften zu entwickeln

1. Jeder Schritt des Verfahrens muss möglichst einfach sein.

2. Das Verfahren soll eine möglichst gute Konvergenzrate ρ < 1 haben.

Den ersten Punkt haben wir bereits perfekt erfüllt. Jeder Schritt im Jakobi-Verfahren hat einelineare Laufzeit, die wir nicht unterbieten können. Ziel ist es Verfahren mit besserer Konver-genzrate zu entwickeln.

1. Die Klasse der Abstiegsverfahren kombiniert die Iterationen der vergangenen Schritte.Hierzu gehören z.B. das Gradientenverfahren oder das Verfahren der konfiguierten Gra-dienten (CG-Verfahren). Mit diesem Verfahren kann die Laufzeit

O(n32 )

erreicht werden.

2. Die Klasse derMehrgitterverfahren versucht die Lösung des GleichungssystemsAx = bdurch ein vereinfachtes Gleichungssystem mit kleinerer Matrix zu approximieren. Daseigentliche ProblemAx = bwird mit nur sehr wenigen Schritten einer einfachen Iterati-on, zumBeispiel dem Jakobi-Verfahren angenähert. Der verbleibendeDefekt b−Axwirdauf ein kleineres Problem mit Größe n/2 übertragen. Hier erfolgen wieder einige wenigeApproximationsschritte und man geht zum Problem der Größe n/4, usw. Bei effizienterDurchführung lässt sich (für einige Matrixtypen, z.B. der Modellmatrix) die Laufzeit

O(n)

erreichen. Mehrgitterverfahren sind somit optimale Verfahren.

[email protected] 135

Page 142: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

6.6. Iterative Lösungsverfahren

136 ©2018 Thomas Richter

Page 143: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7. Nullstellen und Extremwerte

Wir betrachten die Funktion f : R→ R, gegeben als

f(x) =(x(1 + exp(x)

)+ 10 sin

(3 + log(x2 + 1)

))|x+ 4|

und wollen ihre Eigenschaften analysieren. Aus der Analysis stellen sich z.B. die Fragen nach:

• Definitions- und Wertebereich

• Stetigkeit, Differenzierbarkeit, Integrierbarkeit

• Globale und lokale Minima und Maxima

• Nullstellen

Wir beginnen mit der Analyse der einzelnen Bestandteile. Exponentialfunktion, Sinus sowieder Betrag sind stetige Funktionen auf ganz R. Der Logarithmus ist nur auf den positivenZahlen log : R>0 → Rdefiniert, hier dann auch stetig. Die stetige Funktion x2+1 (ein Polynom)ist auf ganz R definiert und bildet in das Intervall [1,∞) ab. Die Komposition log(x2 + 1) istsomit auf ganz R definiert und hier auch stetig. Summen und Produkte stetiger Funktionensind stetig, daher ist f auf ganz R definiert und auch stetig.

Ähnlich können wir bei der Untersuchung der Differenzierbarkeit vorgehen. Polynome, dieExponentialfunktion sowie der Sinus sind auf ganz R beliebig oft differenzierbar. Der Loga-rithmus ist auf seinem Definitionsbereich (0,∞) differenzierbar, d.h. die zusammengesetzteFunktion log(x2 + 1) ist auch auf ganz R differenzierbar. Einzig die Betragsfunktion ist nichtüberall differenzierbar. Es gilt

d

dxx = 1

d

dx

(1 + exp(x)

)= exp(x)

d

dx

(x2 + 1

)= 2x

d

dxlog(x2 + 1

)=

2x

x2 + 1

d

dx|x+ 4| =

−1 x < −4

1 x > 4

nicht def. x = 4

Aus der Kettenregel und der Produktregel folgt, dass die Funktion f : R → R stetig differen-zierbar ist auf R \ {−4}.

137

Page 144: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Als nächstes untersuchenwir denWertebereich der Funktion f(x). Zunächst gilt−1 6 sin(x) 61, d.h. es folgt

−10 6 10 sin(3 + log(x2 + 1)

)6 10.

Der Faktor |x+ 4| > 0 ist stets positiv. Weiter gilt 1 + exp(x) > 1 für alle x ∈ R. Hieraus folgt

x(1 + exp(x)

)+ 10 sin

(3 + log(x2 + 1)

)→∞ x→∞

x(1 + exp(x)

)+ 10 sin

(3 + log(x2 + 1)

)→ −∞ x→ −∞,

die Funktion f : R→ R erreicht somit alle Werte y ∈ R, ist also surjektiv.

Wir betrachten die Funktion genauer. Es gilt

x(1 + exp(x)

)> 10 x > 2

x(1 + exp(x)

)< −10 x < −10,

also

f(x) =

<0︷ ︸︸ ︷(x(1 + exp(x)

)︸ ︷︷ ︸<−10

+ 10 sin(3 + log(x2 + 1)

)︸ ︷︷ ︸610

)|x+ 4|︸ ︷︷ ︸>0

< 0 für x < −10,

sowie

f(x) =

<0︷ ︸︸ ︷(x(1 + exp(x)

)︸ ︷︷ ︸>10

+ 10 sin(3 + log(x2 + 1)

)︸ ︷︷ ︸610

)|x+ 4|︸ ︷︷ ︸>0

für x > 2. (7.1){fkt:upper}{fkt:upper}

Laut demZwischenwertsatzmuss die stetige Funktion f(x) im Intervall (−10, 2) alsomindestenseineNullstelle haben.Wir können in diesemFall sogar eineNullstelle ablesen. Esmuss f(−4) =0 gelten, da hier der Term |x + 4| verschwindet. Da der Betrag jedoch stets positiv (oder Null)ist, erfolgt an der Stelle x = −4 (vermutlich) kein Vorzeichenwechsel. D.h., im Intervall (−10, 2)muss es mindestens eine weitere Nullstelle geben. Zur weiteren Analyse wollen wir uns durcheinen graphische Darstellung der Funktion besseren Einblick verschaffen.

{algo:funktionsplotter}Algorithmus 7.1: Funktions-Plotter

1 # Externe Bibliotheken

2 import numpy as np

3 import matplotlib.pyplot as plt

4

5 # Definition der Funktion die wir plotten wollen

6 def fkt(x):

7 return (x∗(1+np.exp(x))+10∗(np.sin(3+np.log(x∗x+1))))∗np.abs(x+4)8

9 # Diskrete Punkte aus dem Definitionsbereich

10 # von −10 bis 10 in 1er Schritten (−10,−9,...,8,9)11 X = np.arange(−10,10,1)12

13 # Auswerten der Funktion in den Werten von X

14 # Y und X sind numpy − arrays. fkt wird fuer jeden

15 # eintrag von X ausgefuehrt , Y[i] = fkt(X[i])

138 ©2018 Thomas Richter

Page 145: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

16 Y = fkt(X)

17

18 # Plotten der Funktion

19 plt.plot(X,Y)

20 plt.show()

Diese Darstellung ist wenig hilfreich. Der Wertebereich ist dermaßen groß, dass Details nahebei y = 0 nicht ersichtlich sind. Weiter scheint die Anzahl der Punkte auf der x-Achse etwasgering zu sein.

Wir ändern unseren Funktionsplotter und verwenden den diskreten Definitionsbereich X = np↪→ .arange(−10,2,0.1). Um eine bessere übersicht über mögliche Nullstellen zu erhalten fügenwir auch einen Plot der Nullfunktion hinzu:

1 ...

2

3 # Plotten der Funktion

4 plt.plot(X,Y)

5 Z = 0∗X # Null−Vektor mit gleicher Laenge wie X6 plt.plot(X,Z)

7 plt.show()

Die Funktion scheint somit neben der bereits bekannten Nullstelle bei x = −4 drei weitereNullstelle, etwa bei x ≈ −0.5, x ≈ 0.5 und x ≈ 1.5 zu besitzen. Unklar in diesem Plot ist dasVerhalten im Intervall (−10,−8). Weitere Plots verschaffen hier Klarheit. Dieses Vorgehen zumEingrenzen der Nullstellen verschafft einen überblick, gibt aber keine Garantie, dass nicht eineNullstelle übersehen wird, die zwischen zwei diskreten Punkten auf der x-Achse liegt.

Die Frage nach globalen Maxima undMinima haben wir bereits beantwortet, da die Funktionbei x → ∞ gegen∞ und bei x → −∞ gegen −∞ strebt. Weitere lokale Minima und Maximakönnen wieder mit geeigneten Plots eingeschränkt werden.

In den folgenden Abschnitten werden wir uns mit der Frage beschäftigen, wie wir diese Null-stellen, aber auch Extremwerte einer Funktion exakt berechnen, oder, falls dies nicht möglichist, effizient approximieren. Eswird sich zeigen, dass es oft notwendig ist, eine erste Schätzungder Werte im Vorfeld zu kennen.

7.1. Methoden zur Nullstellensuche

Wir betrachten weiter die Funktion

f(x) =(x(1 + exp(x)) + 10 sin(3 + log(x2 + 1))

)|x+ 4|.

Durch die Anwendung des Zwischenwertsatzes wissen wir, dass mindestens eine Nullstelleim Intervall (−10, 2) liegt und aus einer graphischen Analyse vermuten wir die Existenz voninsgesamt 6 Nullstellen.

[email protected] 139

Page 146: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Ein einfaches numerisches Verfahren zur Approximation von Nullstellen basiert auf der wie-derholten Anwendung des Zwischenwertsatzes. Falls für eine stetige Funktion auf einem In-tervall I = [a,b] gilt, dass f(a) < 0, aber f(b) > 0, so muss es ein z ∈ (a,b) geben mit f(z) = 0.Dies ist die Basis zur Intervallschachtelung. Das Intervall [a,b] wird stets halbiert, und zwarso, dass die Funktion f an den Intervallenden ein unterschiedliches Vorzeichen ausweist. Wirbetrachten hierzu den folgenden einfachen Algorithmus:

{algo:intervall}Algorithmus 7.2: Intervallschachtelung

1 def intervallschachtelung(a,b,n):

2 fa = fkt(a)

3 fb = fkt(b)

4 if fa∗fb>0: # kein Vorzeichenwechsel?

5 print(’Kein Vorzeichenwechsel im Intervall [%f,%f]’ % (a,b))

6 return None

7

8 for i in range(n): # Iteration ueber die Anzahl der Schritte

9 m = (a+b)/2.0

10 fm = fkt(m)

11

12 print(’Schritt %d (a,m,b)=(%f,%f,%f) \t (f(a),f(m),f(b)) = (%f,%f,%f) ’

↪→ % (i+1,a,m,b,fa,fm,fb))

13

14 if fm==0: # NS "zufaellig" gefunden?

15 return m

16

17 if fa∗fm<0: # links weiter

18 b = m

19 fb = fm

20 else: # rechts weiter

21 a = m

22 fa = fm

23 return 0.5∗(a+b)

Wir geben jeweils 10 Iterationen für verschiedene Startintervalle aus. In jedem Schritt gebenwir jeweils die Intervallgrenzen und den Mittelwert aus, also (a,m,b) sowie die jeweiligenFunktionswerte (f(a), f(m), f(b)). Zunächst gilt für intervallschachtelung(−10,10,10)

1 Schritt 1 (−10.00000,0.000000,10.000000) (−1.706240,5.644800,3083981)2 Schritt 2 (−10.00000,−5.000000,0.000000) (−1.706240,−5.284551,5.644800)3 Schritt 3 (−5.000000,−2.500000,0.000000) (−5.284551,−18.519920,5.644800)4 Schritt 4 (−2.500000,−1.250000,0.000000) (−18.519920,−24.137975,5.644800)5 Schritt 5 (−1.250000,−0.625000,0.000000) (−24.137975,−9.551458,5.644800)6 Schritt 6 (−0.625000,−0.312500,0.000000) (−9.551458,−0.210795,5.644800)7 Schritt 7 (−0.312500,−0.156250,0.000000) (−0.210795,3.390652,5.644800)8 Schritt 8 (−0.312500,−0.234375,−0.156250) (−0.210795,1.733114,3.390652)9 Schritt 9 (−0.312500,−0.273438,−0.234375) (−0.210795,0.793239,1.733114)

10 Schritt 10 (−0.312500,−0.292969,−0.273438) (−0.210795,0.298750,0.793239)11 Approximation einer Nullstelle f(z)=0 ist z=−0.302734

140 ©2018 Thomas Richter

Page 147: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Wir erhalten also die Nullstelle, die wir bei etwa x ≈ −0.5 erwartet haben. Starten wir mitintervallschachtelung(−0.3,10,10), so erhalten wir das Ergebnis

1 Kein Vorzeichenwechsel im Intervall [−0.300000,10.000000]

denn die Funktion f(x) ist jeweils positiv. Stattdessen starten wir mit intervallschachtelung↪→ (−0.3,1,10), so erhalten wir das Ergebnis

1 Schritt 1 (−0.300000,0.350000,1.00000) (0.116996,4.815395,−7.609184)2 Schritt 2 (0.350000,0.675000,1.000000) (4.815395,−1.479409,−7.609184)3 Schritt 3 (0.350000,0.512500,0.675000) (4.815395,2.044748,−1.479409)4 Schritt 4 (0.512500,0.593750,0.675000) (2.044748,0.330064,−1.479409)5 Schritt 5 (0.593750,0.634375,0.675000) (0.330064,−0.569100,−1.479409)6 Schritt 6 (0.593750,0.614062,0.634375) (0.330064,−0.117327,−0.569100)7 Schritt 7 (0.593750,0.603906,0.614062) (0.330064,0.107015,−0.117327)8 Schritt 8 (0.603906,0.608984,0.614062) (0.107015,−0.005007,−0.117327)9 Schritt 9 (0.603906,0.606445,0.608984) (0.107015,0.051043,−0.005007)

10 Schritt 10 (0.606445,0.607715,0.60898) (0.051043,0.023028,−0.005007)11 Approximation einer Nullstelle f(z)=0 ist z=0.608350

Auch die anderen Nullstellen können bei Wahl entsprechender Startintervalle gefunden wer-den. Einzig die Nullstelle bei x = −4 ohne Vorzeichenwechsel kann mit Hilfe der Intervallhal-bierung nicht ermittelt werden.

Wir betrachten im Folgenden eine allgemeine Funktion

f : D(f)→ R

und suchen die (oder mehrere) Nullstellen z ∈ D(f) im Definitionsbereich. Dabei kann jedeallgemeine nichtlineare Gleichung

N(x) = y

durch die Transformation f(x) := N(x) − y als eine Nullstellenaufgabe geschrieben werden:

f(x) = 0.

Das allgemeineNullstellenproblemmussmeistmit einem Iterationsverfahren approximiertwer-den. Ausgehend von einem Startwert x0 (oder auch von mehreren Startwerten wie bei der In-tervallschachtelung) erhalten wir mithilfe einer Iterationsvorschrift eine Folge von Punktenxk,k = 1, 2, 3, . . ., deren Grenzwert gegen die Nullstelle z ∈ R konvergiert:

f(x0)→ f(x1)→ f(x2) · · · → f(z) = 0

In der Praxis kann der unendliche Grenzprozess nicht durchgeführt werden. Stattdessen wirddie Iteration bei einem endlichen N ∈ N gestoppt und das Folgenglied xN wird als Approxi-mation der Nullstelle xN ≈ z betrachtet.

Aus dem vorherigen Beispiel ergeben sich unmittelbar wichtige Fragestellungen, die wir indiesem Kapitel untersuchen wollen und die uns in den weiteren Kapiteln wieder begegnenwerden. Im Einzelnen sind dies:

[email protected] 141

Page 148: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

- Welche Aussagen können wir zur Stabilität und der Konditionierung der Nullstellenbe-stimmung machen?

- Wie konstruiert man effiziente und stabile numerische Verfahren?

- Wie schnell konvergiert (xk)k∈N gegen z?Wie könnenwir die BegriffeKonvergenzordnungund Konvergenzrate (Maße für die Konvergenzgeschwindigkeit) quantifizieren? In derAnalysis wird untersucht, ob Folgen konvergieren: xk → z für k → ∞? In der Numerikreicht diese Aussage nicht aus. Es kommt das Konzept der Effizienz ins Spiel: Konvergenzmuss hinreichend schnell vorliegen, sodass eine gute Näherung auch schnell berechnetwerden kann.

- Konvergiert das ausgewählte numerische Verfahren auf beliebig großen Intervallen undmit beliebig gewählten Startwerten x0, oder nur dann, wenn der Startwert x0 bereits hin-reichend nahe an der gesuchten Nullstelle ist? In anderenWorten: Ist das Verfahren lokaloder global konvergent?

- Können wir für eine berechnete Approximation xN eine Abschätzung für den Fehler|xN − z| angeben? Wir werden zwischen der A-priori-und A-posteriori-Fehleranalyse un-terscheiden. Bei der A-priori-Fehleranalyse wird der Fehler |xN − z| vor der Rechnungabgeschätzt. Dies liefert eine grobe Schranke zum Verhalten der Fehlerentwicklung, dieaber nur asymptotisch richtig ist - und somit für quantitative Aussagen oft nutzlos ist.Dagegen wird bei der A-posteriori-Fehleranalyse der Fehler |xN − z|während der Rech-nung abgeschätzt, alle bereits berechneten Approximation x0, x1, . . . , xN können in dieAbschätzung einfließen. A-posteriori-Abschätzungen lassen oft quantitative Aussagenzu, die zur Steuerung des numerischen Verfahrens genutzt werden können.

Im Rest dieses Kapitels werden wir die oben genannten Fragen anhand verschiedener Verfah-ren diskutieren und die Schlüsselbegriffe spezifizieren.

7.1.1. Stabilität und Kondition der Nullstellensuche

Wir suchen Nullstellen von Funktionen f : D → R, also Punkte z ∈ D mit der Eigenschaftf(z) = 0.

Definition 7.1 (Nullstelle). Es sei f : D ⊂ R → R eine stetige Funktion. Dann heißt ein z ∈ Dreelle Nullstelle von f, falls

f(z) = 0.

Angenommen, die Funktion f ist mindestens k-mal stetig differenzierbar für ein k ∈ N und es gilt

f(z) = 0, f ′(z) = 0, . . . , f(k−1)(z) = 0, f(k)(z) 6= 0,

so heißt z ∈ D eine k-fache Nullstelle von f.

Am Beispiel von quadratischen Polynomen

f(x) = x2 − px+ q, p, x ∈ R,

142 ©2018 Thomas Richter

Page 149: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

(IV)

43.532.521.51

3

2.5

2

1.5

1

0.5

0

−0.5

−1

(III)

43.532.521.51

3

2.5

2

1.5

1

0.5

0

−0.5

−1

(II)

43.532.521.51

3

2.5

2

1.5

1

0.5

0

−0.5

−1

(I)

43.532.521.51

3

2.5

2

1.5

1

0.5

0

−0.5

−1

Abbildung 7.1.: Vier möglichen Situationen bei der Nullstellensuche quadratischer Funktio-nen. Von links oben nach rechts unten: (I) zwei klar getrennte Nullstellen, (II)keine reelle Nullstelle, (III) eine doppelte Nullstelle und (IV) zwei reelle Null-stellen nahe beieinander. {nullstellen_figure_stabilitaet}

werden wir zunächst auf die Konditionierung der Nullstellensuche und auf Stabilität von Al-gorithmen eingehen. Die p/q-Formel ist ein direktes Lösungsverfahren:

x1/2 =p

2±√p2

4− q

In Abbildung 7.1 zeigen wir vier verschiedene Situationen:

1. Es gibt zwei reelle Nullstellen, die weit separiert sind.

2. Es gibt nur eine reelle Nullstelle. Diese Nullstelle ist eine doppelte Nullstelle mit f(z) =f ′(z) = 0.

3. Es gibt zwei reelle Nullstellen, die sehr nahe beieinanderliegen.

4. Es existiert keine reelle Nullstelle. Die Funktion hat dann zwei komplexe Nullstellen.

Beispiel 7.2 (Konditionierung der Nullstellensuche quadratischer Polynome). Wir berechnendie Konditionierung der Nullstellenbestimmung in Abhängigkeit von den Koeffizienten. Dazu sei

f(x) = x2 − px+ q = 0, x ∈ R.

Für die Nullstellen x1,2 gilt

x1,2 = x1,2(p,q) =p

2±√p2

4− q

[email protected] 143

Page 150: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

und wegenf(x) = (x− x1)(x− x2) = x

2 − (x1 + x2)x+ x1x2

auchp = x1 + x2, q = x1x2.

Dies ist die Aussage vom Satz von Vieta. Wir berechnen nun Konditionszahlen der Nullstellensuche:

k1p =∂x1

∂p

p

x1=

1 + x2/x11 − x2/x1

, k1q =∂x1

∂q

q

x1=

1

1 − x1/x2,

k2p =∂x2

∂p

p

x2= −

1 + x2/x11 − x2/x1

, k2q =∂x2

∂q

q

x2=

1

1 − x2/x1.

Die Berechnung der Nullstellen x1, x2 ist demnach schlecht konditioniert, falls x1/x2 ∼ 1, wenn al-so beide Nullstellen nahe beieinanderliegen. In diesem Fall können die Konditionszahlen beliebig großwerden. Dies ist die in Abbildung 7.1 (III) skizzierte Situation.

Die Stabilität der p/q-Formel und eine stabile Variante auf der Basis des Satz von Vieta habenwir bereits in Abschnitt 5.1.2 besprochen.

7.1.2. Intervallschachtelung{nullstellen_Intervallschachtelung}

Das einfachste Verfahren zur Nullstellenbestimmung ist die Intervallschachtelung, welche aufeiner Anwendung des Zwischenwertsatzes beruht.

Es sei f ∈ C[a,b] und x,y ∈ [a,b] mit x < y. Falls f(x) und f(y) unterschiedliche Vorzeichenhaben, d.h.

f(x)f(y) < 0,

dann besitzt die Funktion f nach dem Zwischenwertsatz mindestens eine Nullstelle in (a,b).EinenAlgorithmus in Pythonhabenwir bereits angegeben.Dieses zurNullstellensuche grund-legende Verfahren ist einfach zu analysieren:{nullstellen_satz_intervallschachtelung}

Satz 7.3 (Intervallschachtelung). Es sei f ∈ C[a,b] mit f(a)f(b) < 0. Es sei an,bn, xn die durchAlgorithmus 7.2 bestimmte Folge von Intervallen und Mittelpunkten. Es gilt

xn → z, f(z) = 0,

sowie die Fehlerabschätzung

|xn − z| 6b− a

2n+1.

Beweis. (i) Bei a < b gilt stets

a 6 a1 6 · · · 6 an 6 an+1 6 xn 6 bn+1 6 bn 6 · · · 6 b1 6 b.

Das Verfahren ist damit durchführbar. Die Folge xn ist durch zwei monotone (steigende undfallende) Folgen an und bn beschränkt. Die Folge ist daher konvergent. Das Verfahren brichtnur dann ab, wenn f(xn) = 0, wenn also xn = z die gesuchte Nullstelle ist.

144 ©2018 Thomas Richter

Page 151: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

(ii) Es gilt

bn+1 − an+1 =

{xn − an = bn−an

2 f(an)f(xn) < 0

bn − xn = bn−an2 f(an)f(xn) > 0

.

In beiden Fällen folgt

|bn − an| =|b0 − a0|

2n. (7.2){null:intervall:1}{null:intervall:1}

Wegenan 6 xn 6 bn

folgt die Konvergenz von xn → z gegen ein z ∈ [an,bn] ⊂ [a,b].

(iii) Für diesen Grenzwert z gilt wegen der Stetigkeit von f(·)

0 6 f(z)2 = limn→∞ f(an)f(bn) 6 0 ⇒ f(z) = 0.

Der Grenzwert ist somit die gesuchte Nullstelle. Schließlich können wir aus (7.2) die Fehler-abschätzung herleiten. Denn es ist

|xn − z| 6|bn − an|

26

|b− a|

2n+1.

Bemerkung 7.4 (A-priori-Fehlerabschätzung). Die in Satz 7.3 angegebene Fehlerabschätzung

|xn − z| 6b− a

2n+1

ist eineA-priori-Fehlerabschätzung. Sie kann bereits vor der Rechnung ausgewertet werden, um z.B.die benötigte Anzahl von Schritten n zu bestimmen.

Beispiel 7.5 (Intervallschachtelung). Wir betrachten das Intervall I = [0, 1], dann liefert die A-priori- Abschätzung für verschiedene n ∈ N die Schranken

|x9 − z| < 10−3, |x19 − z| < 10−6, |x29 − z| < 10−9.

Das heißt, in der 29-sten Iteration kann eine Genauigkeit von TOL = 10−9 erwartet werden.

Abschließend diskutieren wir noch eine A-posteriori-Fehlerabschätzung, die allerdings diestetige Differenzierbarkeit von f voraussetzt:

Satz 7.6 (A-posteriori-Fehlerabschätzung). Es sei f ∈ C1[a,b] mit f(a)f(b) < 0 und f(z) = 0 fürz ∈ [a,b]. Die Ableitung sei beschränkt:

0 < m 6 |f ′(x)| 6M <∞Für die Nullstelle z von f und die in Satz 7.3 definierte Folge (xn)n∈N gilt dann

|f(xn)|

M6 |xn − z| 6

|f(xn)|

m.

[email protected] 145

Page 152: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Beweis. Mit Taylor-Entwicklung gilt

f(xn) = f(z) + f′(ξ)(xn − z) = f ′(ξ)(xn − z) (7.3) {null:intervall:fehler}{null:intervall:fehler}

mit einer Zwischenstelle ξ ∈ [an,bn]. Es folgt

|f(xn)|

max |f ′(x)|6 |xn − z| 6

|f(xn)|

min |f ′(x)|.

DieA-posteriori-Fehlerschranke kann alsAbbruchkriteriumzumBeendender Intervallschach-telung genutzt werden, falls f stetig differenzierbar in [a,b] ist.

Die Intervallschachtelung ist ein sehr stabiles Verfahren. Aus dem Konstruktionsprinzip folgtunmittelbar, dass die Nullstelle stets im Iterationsintervall eingeschlossen ist. Allerdings kon-vergiert das Verfahren sehr langsam gegen die gesuchte Nullstelle. Aufgrund seiner Stabilitätwird das Intervallschachtelungsverfahren häufig als Startverfahren für andere Verfahren ge-nutzt. Die Intervallschachtelung ist auf reelle skalare Funktionen beschränkt (im Gegensatzzu den weiteren Verfahren, die wir im Anschluss kennenlernen werden). Zum Auffinden vondoppelten Nullstellen mit f(z) = f ′(z) = 0 ist die Intervallschachtelung nicht geeignet. DieFunktion f(x) = x2 ist positiv auf beiden Seiten der Nullstelle.

7.1.3. Das Newton-Verfahren{sec_newton}

Die Intervallschachtelung stellt an die Funktion f nur sehr geringe Anforderungen. Sie mussstetig sein. Wir betrachten nun stetig differenzierbare Funktionen f ∈ C1[a,b]. Betrachtenwir (7.3), so können wir die Taylor-Approximation nach der gesuchten Nullstelle auflösen.Es gilt

z = xn −f(xn)

f ′(ξ).

Wir kennen den Zwischenwert ξ nicht, wissen aber, dass er im Intervall ξ ∈ [an,bn] liegt. EineApproximation ξ ≈ xn

z ≈ xn+1 := xn −f(xn)

f ′(xn)

ist ein guter Kandidat für die Näherung an die Nullstelle. Diese Iteration ist gerade das klas-sische Newton-Verfahren.

Das Newton-Verfahren kann geometrisch interpretiert werden: Die Funktion f wird im Nä-herungswert xn durch ihre Tangente linearisiert und der iterierte Wert xn+1 als Abszisse desSchnittpunktes der Tangente (an f) mit der x-Achse definiert, vergleiche Abbildung 7.2.

{algo:newton1d}Algorithmus 7.3: Newton-Verfahren

1 def newton(x,n):

2 for i in range(n): # Iteration der Newton−Schritte3 d = Dfkt(x) # Berechnung der Ableitung f’(x)

4 if d==0:

5 print(’Newton nicht anwendbar. Ableitung Null in x=%f’ % x)

146 ©2018 Thomas Richter

Page 153: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

x0

z

x1x2

Abbildung 7.2.: Geometrische Interpretation des Newton-Verfahrens. Die neue Iterierte xk+1

ist jeweils die Nullstelle der Tangente an f im Punkt (xk, f(xk)). {fig:newtonverfahren}

6 return None

7 print(’Schritt %d x=%f f(x)=%f’ % (i,x,d))

8 x = x − fkt(x)/d # Berechnung update

9 return x

Die Iteration 7.3 gehört zur Klasse der Fixpunktiterationen mit der Iterationsfunktion

g(x) := x−f(x)

f ′(x), xk+1 = g(xk). (7.4) {nullstellen_Newton1d_Iterationsfunktion}{nullstellen_Newton1d_Iterationsfunktion}

Für einen Fixpunkt z = g(z) gilt offenbar f(z) = 0. Wir zeigen nun als Hauptresultat eineneinfachen Konvergenzbeweis für das Newton-Verfahren: {nullstellen_satz_newton_verfahren}

Satz 7.7 (Newton-Verfahren). Die Funktion f ∈ C2[a,b] habe im Innern des Intervalls [a,b] eineNullstelle z und es seien

m := mina6x6b

|f ′(x)| > 0, M := maxa6x6b

|f ′′(x)| (7.5) {NN:1}{NN:1}

Schranken für erste (nach unten) und zweite Ableitung (nach oben). Es sei ρ > 0 so gewählt, dass

q :=M

2mρ < 1, Kρ(z) := {x ∈ R : |x− z| 6 ρ} ⊂ [a,b]. (7.6) {NN:2}{NN:2}

Dann sind für jeden Startpunkt x0 ∈ Kρ(z) die Newton-Iterierten xk ∈ Kρ(z) definiert und konver-gieren gegen die Nullstelle z. Des Weiteren gelten die A-priori-Fehlerabschätzung

|xk − z| 62m

Mq2k

, k ∈ N,

und die A-posteriori-Fehlerabschätzung

|xk − z| 61

m|f(xk)| 6

M

2m|xk − xk−1|

2, k ∈ N.

Beweis. (i)Der Beweis ist eine einfacheAnwendungder Taylor-Approximation. Für x, z ∈ [a,b]gilt (z ist die Nullstelle)

f(z) = f(x) + f ′(x)(z− x) +f ′′(ξ)

2(z− x)2

[email protected] 147

Page 154: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

mit einem Zwischenwert ξ ∈ [x, z] oder ξ ∈ [z, x]. Für f ′(x) 6= 0, was wegen |f ′(x)| > m > 0 in[a,b] stets gegeben ist, erhalten wir den Zusammenhang

f(x)

f ′(x)= (x− z) −

f ′′(ξ)

2f ′(x)(x− z)2. (7.7) {newton:1}{newton:1}

(ii)Wir zeigen zunächst, dass die Iteration unter den gegebenen Voraussetzungen durchführ-bar ist. Angenommen, xk ∈ Kρ(z). Dann folgt mit (7.7) und der Vorschrift

xk+1 − z = xk −f(xk)

f ′(xk)− z = (xk − z) −

((xk − z) −

f ′′(ξ)

2f ′(xk)(xk − z)

2

),

alsoxk+1 − z =

f ′′(ξ)

2f ′(xk)(xk − z)

2

bzw. abgeschätzt

|xk+1 − z| 6|f ′′(ξ)|

2|f ′(xk)||xk − z|

2 6M

2m|xk − z|

2. (7.8){newton:2}{newton:2}

Im Fall xk ∈ Kρ(z) ist |xk − z| 6 ρ folgt

|xk+1 − z| 6M

2mρ︸ ︷︷ ︸

=q<1

·ρ 6 ρ,

also bleibt xk+1 ∈ Kρ(z) ⊂ [a,b] in der Umgebung der Nullstelle und auch im Definitionsbe-reich von f(·), sodass das Verfahren durchführbar ist.

(iii) Wir können nun gleich die Fehlerabschätzung nachweisen, denn für

ρk :=M

2m|xk − z|

gilt mit (7.8)

ρk =M

2m|xk − z| 6

M

2m

M

2m|xk−1 − z|

2 = ρ2k−1

und iteriertρk 6 ρ2

k

0 ,

also

|xk − z| 62m

M

(M

2m|x0 − z|

)2k

62m

Mq2k

.

(iv) Es bleibt der Nachweis der A-posteriori-Abschätzung. Taylor-Entwicklung bis zur erstenStufe gibt

f(xk) = f(z) + f′(ξ)(xk − z),

also folgt wegen |f ′(ξ)| > m die erste Hälfte der Fehlerabschätzung

|xk − z| 6|f(xk)|

m.

148 ©2018 Thomas Richter

Page 155: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Mit der Newton-Vorschrift folgt mit der Taylor-Entwicklung

f(xk) = f

(xk−1 −

f(xk−1)

f ′(xk−1)

)= f(xk−1) + f

′(xk−1)

(−f(xk−1)

f ′(xk−1)

)+f ′′(ξ)

2

(f(xk−1)

f ′(xk−1)

)2

,

dann die zweite Abschätzung

|f(xk)| 6M

2|xk − xk−1|

2.

Dieser Satz zeigt die quadratische Konvergenz des Newton-Verfahrens, wenn die Funktion fzweimal stetig differenzierbar ist, im Intervall eineNullstelle hat undwenn die erste Ableitungbetragsmäßig vonNull weg beschränkt ist. Der Startwertmuss bereits hinreichend nahe an derNullstelle sein. {bem:newton:abbruch}

Bemerkung 7.8 (Abbruchkriterien des Newton-Verfahrens). Der vorherige Satz gibt uns mit derA-posteriori-Abschätzung auch ein Kriterium zum Abbruch der Iteration in Algorithmus 7.3. Falls zueiner gegebenen Toleranz tol > 0

|f(xk)|

m< tol

oderM

2|xk − xk−1|

2 < tol

gilt, so ist auch |xk − z| < tol. In diese Abbruchkriterien gehen jedoch die Konstantenm undM, alsodie Schranken der Ableitungen von f(x) ein. Diese kennen wir im Allgemeinen nicht. Daher geben wirnoch ein weiteres heuristisches, aber überprüfbares Kriterium an.

Die Iterationwird beendet (d.h., wir haben eine akzeptable Lösung xk+1 in der k-ten Iteration gefunden),falls

|xk+1 − xk|

|xk|< tol (7.9) {nullstellen_abbruch_mit_Abstand}{nullstellen_abbruch_mit_Abstand}

gilt. Die Idee für dieses Kriterium beruht auf der quadratischen Konvergenz. Es gilt|xk − z|

|z|6

|xk+1 − xk|+ |xk+1 − z|

|z|=

|xk+1 − xk|

|z|+O(|xk − z|

2),

falls wir im Bereich der quadratischen Konvergenz sind. Zur Approximation wird schließlich imNenner|z| durch |xk| ersetzt, um eine berechenbare Größe zu erhalten. {bsp:newton:invervall}

Beispiel 7.9 (Newton-Verfahren und Intervallschachtelung). Wir betrachten die Funktion f ausder Einleitung

f(x) = x(1 + exp(x)) + 10 sin(3 + log(x2 + 1)).

Wir haben argumentiert, dass f(x) < 0 für x < −10 und f(x) > 0 für x > 10 gilt. Im Intervall[−10, 10] liegt somit mindestens eine Nullstelle. In der Tat hat die Funktion in diesem Intervall fünfNullstellen. Es gilt (auf sechs Stellen Genauigkeit)

z1 = −9.16359, z2 = −8.65847, z2 = −0.304487,

z4 = 0.608758, z5 = 1.54776.

Wir führen zunächst die Intervallschachtelung durch:

[email protected] 149

Page 156: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

a f(a) b f(b) x f(x) b− a

0 −10 − 10 + 0 + 201 −10 − 0 + −5 − 102 −5 − 0 + −2.5 − 53 −2.5 − 0 + −1.25 − 2.54 −0.625 − 0 + −0.3125 − 1.255 −0.3125 − 0 + −0.15625 + 0.6256 −0.3125 − −0.15625 + −0.234375 + 0.3125

...15 · · · − · + −0.30449 · 0.000153

Nach 15 Schritten erhaltenwir eineApproximation x ≈ −0.30449, welche höchstens den Fehler |x−z| 60.000153 besitzt. Verglichen mit der exakten Nullstelle gilt |x− z3| ≈ 0.000002.

Wir führen nun das Newton-Verfahren aus. Hierbei gilt es einen Startwert zu wählen. Eigentlich müsstedieser Startwert im Sinne von Satz 7.7 gewählt werden. Dies ist bei der vorliegenden Funktion jedochnur schwer möglich. Wir wählen daher zunächst x(0) = 0. Es folgt:

x(0) = 0

x(1) = x(0) −f(x(0))

f ′(x(0))≈ −0.705600 x(1) − z2 ≈ −0.40

x(2) = x(1) −f(x(1))

f ′(x(1))≈ −0.349442 x(2) − z2 ≈ −0.045

x(3) = x(2) −f(x(2))

f ′(x(2))≈ −0.306245 x(3) − z2 ≈ −0.00174

x(4) = x(3) −f(x(3))

f ′(x(3))≈ −0.304490 x(4) − z2 ≈ −0.000003

Nach nur vier Schritten sind die ersten fünf wesentlichen Stellen der Nullstelle z2 bestimmt. Wir be-trachten als Startwert jetzt das linke Intervallende:

x(0) = −10

x(1) = x(0) −f(x(0))

f ′(x(0))≈ −9.46454 x(1) − z1 ≈ 0.3

x(2) = x(1) −f(x(1))

f ′(x(1))≈ −9.24183 x(2) − z1 ≈ 0.08

x(3) = x(2) −f(x(2))

f ′(x(2))≈ −9.17249 x(3) − z1 ≈ 0.008

x(4) = x(3) −f(x(3))

f ′(x(3))≈ −9.16373 x(4) − z1 ≈ 0.00009

Das Newton-Verfahren konvergiert jetzt gegen die Nullstelle z1. Es liegt wieder sehr schnelle Konver-genz vor, nicht jedoch gegen die eigentlich gesuchte Nullstelle z3. Falls das Newton-Verfahren im Bereichder quadratischen Konvergenz liegt, so ist es äußerst schnell. Wenn alle fünf Nullstellen gefunden wer-den sollen, so stellt sich jedoch die Frage nach guten Startwerten. Diese könnten z.B. mit einer Rasterungdes Intervalls, also z.B. durch Berechnen aller f(x) für x ∈ {−10,−9, . . . , 10} gefunden werden.

150 ©2018 Thomas Richter

Page 157: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Bemerkung 7.10. Für eine zweimal stetig differenzierbare Funktion f existiert zu jeder einfachenNullstelle z stets eine (evtl. sehr kleine) Umgebung Kρ(z), für die die Voraussetzungen von Satz 7.7erfüllt sind. Das Problem beim Newton-Verfahren ist also die Bestimmung eines im Einzugsbereichder Nullstelle z gelegenen Startpunktes x0 (lokale Konvergenz). Dieser Startwert kann z.B. mithilfe derIntervallschachtelung (siehe entsprechende Bemerkung oben) berechnet werden. Dann konvergiert dasNewton-Verfahren sehr schnell (quadratische Konvergenz) gegen die Nullstelle z.

Falls der Startpunkt x0 im Einzugsbereich der quadratischen Konvergenz liegt, dann konver-giert das Newton-Verfahren sehr schnell gegen die gesuchte Nullstelle. Es sei z.B. q 6 1

2 , danngilt nach nur zehn Iterationsschritten

|x10 − z| 62m

Mq2

10∼

2m

M10−300.

Beispiel 7.11 (Wurzelberechnung). Dien-teWurzel einer Zahl a > 0 ist die Nullstelle der Funktionf(x) = xn−a. Das Newton-Verfahren zur Berechnung von z = n

√a > 0 lautet (mit f ′(x) = nxn−1):

xk+1 = xk −xnk − a

nxn−1k

=1

n

{(n− 1)xk +

a

xn−1k

}

Folgende Spezialfälle leiten sich daraus ab:

xk+1 =1

2

{xk +

a

xk

}(Quadratwurzel)

xk+1 =1

3

{2xk +

a

x2k

}(Kubikwurzel)

xk+1 = (2 − axk)xk (Kehrwert)

Aufgrund von Satz 7.7 konvergiert xk → z für k→∞, falls x0 nahe genug bei z gewählt wird.

Bei der Wurzelberechnung kann jedoch sogar globale Konvergenz für alle Startwerte x0 > 0 gezeigtwerden. Es kann - unabhängig von x0 - gezeigt werden, dass

x1 >√a

gilt. Im Anschluss kann monotone Konvergenz nachgewiesen werden:

xk+1 < xk k = 2, 3, . . .

Hieraus kann globale Konvergenz gefolgert werden. Quadratische Konvergenz liegt im Allgemeinen erstnach einigen Iterationsschritten vor.

Bemerkung 7.12 (Praktische Berechnung derWurzel). DasNewton-Verfahren kommt auf Compu-tern bei der Berechnung von vielen Größen zum Einsatz, die nicht elementar bestimmt werden können.Da die Iteration nur Multiplikationen, Divisionen und Additionen erfordert, kann es sehr effizient um-gesetzt werden.

[email protected] 151

Page 158: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

7.1.4. Varianten des Newton-Verfahrens

In der Praxis wird das Newton-Verfahren oft als Defektkorrektur-Iteration ausgeführt. Wirdefinieren: {nullstellen:def:defekt}

Definition 7.13 (Defekt). Es sei x ∈ R eine Approximation der Lösung von f(x) = y. Mit

d(x) = y− f(x)

wird der Defekt bezeichnet. Der Defekt wird auch als das Residuum bezeichnet.

Es sei im Folgenden y = 0 (falls nicht, transformieren wir die Gleichung entsprechend um),sodass wir wie üblich ein Nullstellenproblem lösen. Für die Approximation xk ist durch dk :=0 − f(xk) der Defekt der k-ten Iterierten gegeben und wir schreiben das Newton-Verfahren inder Form

{algo:newton:defekt}Algorithmus 7.4: Newton-Verfahren als DefektkorrekturGegeben sei f ∈ C2[a,b]:

1 Wähle x0 ∈ [a,b]2 I t e r i e r e für k = 0, 1, 2, . . .3 dk = −f(xk)4 f ′(xk)wk = dk5 xk+1 = xk + dk

Diese Formulierung des Newton-Verfahrens scheint zunächst künstlich kompliziert. Es wirdeine zusätzliche Variablewk eingeführt. Wir nennen dies das Update. Statt der Division durchdie Ableitung schreiben wir die Update-Gleichung als eine lineare Gleichung:

Suche wk ∈ R : f ′(xk) ·wk = dk ⇔ wk =dkf ′(xk)

.

Im Fall skalarer Funktionen macht dies natürlich keinen Unterschied. Später, bei der Betrach-tung von vektorwertigen Funktionen f : Rn → Rn, ist f ′ jedoch die Jacobi-Matrix f ′ : Rn →Rn×n und die Defektkorrektur-Schreibweise erfordert die Lösung eines linearen Gleichungs-systems anstelle der Multiplikation mit der inversen Matrix. Schließlich werden wir gedämpfteVarianten des Newton-Verfahrens diskutieren, bei denen Schritt 5 in Algorithmus 7.4 ersetztwird durch

5 xk+1 = xk +ωkdk

mit einem Dämpfungsparameter ωk ∈ (0, 1]. Schließlich dient der Defekt gleich als ein Fehler-schätzer für die Newton-Iteration:

Satz 7.14 (Defekt-Fehlerabschätzung). Es sei f ∈ C1[a,b] eine differenzierbare Funktion und z ∈(a,b) die Lösung von f(x) = y. Für die Approximation x ∈ (a,b) gilt die Fehlerabschätzung

|x− z| 61

m|d(x)|

mitm = minx∈[a,b] |f′(x)|.

152 ©2018 Thomas Richter

Page 159: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Beweis. Es gilt mit einem ξ ∈ [a,b]

d(x) = y− f(x) =f(z) − f(x)

z− x(z− x) = f ′(ξ)(z− x).

Hieraus folgt sofort die Behauptung.

Hat die Funktion f(x) im Intervall [a,b] eine doppelte Nullstelle mit f(z) = f ′(z) = 0, so istm = min |f ′| = 0 und Satz 7.7 kann nicht angewendet werden, da die Voraussetzungen nichterfüllt werden können. Es gibt keinen Konvergenzradius ρ > 0, sodass

M

2mρ < 1.

Beispiel 7.15 (Newton-Verfahren für doppelte Nullstellen). Wir betrachten die Funktion f(x) =x2 mit der doppelten Nullstelle f(0) = f ′(0) = 0. Wir führen einige Iterationen

xk+1 = xk −f(xk)

f ′(xk)

durch und wählen als Startwert x0 = 1. Es gilt

x0 = 1, x1 = 0.5, x2 = 0.25, x3 = 0.125, . . .

Die Werte nähern sich der Nullstelle z = 0 an, der Fehler xk − z scheint sich aber in jedem Schritt nurzu halbieren. Wir betrachten das Beispiel genauer und erhalten

xk+1 = xk −f(xk)

f ′(xk)= xk −

x2k2xk

=1

2xk.

Der Iterationswert halbiert sich in jedem Schritt. Dies zeigt, dass das Newton-Verfahren für f(x) = x2in der Tat gegen die Nullstelle konvergiert. Es liegt sogar globale Konvergenz für beliebige Startwertevor. Diese ist jedoch nur linear.

Es stellt sich die Frage, ob das beobachtete Verhalten nur ein Spezialfall ist oder obwir generellKonvergenz auch bei mehrfachen Nullstellen erwarten können. Das Problem bei der Durch-führung ist, dass bei xk → z sowohl f(xk) → 0 als auch f ′(xk) → 0 gilt. Für den Quotientengilt mit der Regel von de l’Hospital [7] bei einer doppelten Nullstelle mit f ′′(z) 6= 0

limxk→z

f(xk)

f ′(xk)= limxk→z

f ′(xk)

f ′′(xk)=f ′(z)

f ′′(z)= 0.

Hieraus könnenwir folgern, dass bei Konvergenz von xk → zdie Iterationwohldefiniert bleibt.Es gilt: {satz_mehrfache_NS_Newton}

Satz 7.16 (Newton-Verfahren bei mehrfachenNullstellen). Es sei z ∈ [a,b] eine p-fache Nullstelleder Funktion f ∈ Cp+1([a,b]), d.h., es gelte

f(z) = f ′(z) = · · · = f(p−1)(z) = 0, f(p)(z) 6= 0.

Weiter seim := min

x∈[a,b]|f(p)(x)| > 0, M := max

x∈[a,b]|f(p+1)(x)| <∞.

[email protected] 153

Page 160: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Dann konvergiert das Newton-Verfahren

xk+1 = xk −f(xk)

f ′(xk)

lokal gegen diese Nullstelle. Die Konvergenz ist nur linear. Das modifizierte Newton-Verfahren

xk+1 = xk − pf(xk)

f ′(xk)

konvergiert lokal quadratisch gegen die Nullstelle.

Beweis. Wir verzichten hier darauf, eine quantitative Abschätzung für den Konvergenzradiusanzugeben. Mit einemω > 0 sei

xk+1 = xk −ωf(xk)

f ′(xk).

Für den Fehler xk+1 − z gilt wie im Beweis zu Satz 7.7

xk+1 − z =

(1 −ω

f(xk)

(xk − z)f ′(xk)

)(xk − z). (7.10){newton:3}{newton:3}

Wir entwickeln f(xk) um die Nullstelle:

f(xk) =

p−1∑i=0

f(i)(z)

i!(xk − z)

i︸ ︷︷ ︸=0

+f(p)(ξxk,z)

p!(xk − z)

p =f(p)(ξxk,z)

p!(xk − z)

p

mit einer Zwischenstelle ξxk,z aus [xk, z] bzw. [z, xk]. Ableiten dieser Formel nach xk liefert

f ′(xk) =f(p)(ξxk,z)

p!p(xk − z)

p−1 +(xk − z)

p

p!

d

dxkf(p)(xxk,z)︸ ︷︷ ︸

=:R(xk,z,p)

.

Der Rest R(xk, z,p) beinhaltet die p + 1-te Ableitung von f. Diese ist nach Voraussetzung be-schränkt. Wir setzen diese Entwicklungen in (7.10) ein:

xk+1 − z =

1 −ω

f(p)(ξxk,z)

p! (xk − z)p

f(p)(ξxk,z)

(p−1)! (xk − z)p +R(xk,z,p)

p! (xk − z)p+1

(xk − z)

=

1 −ω

p

1

1 +R(xk,z,p)

pf(p)(ξxk,z)(xk − z)

(xk − z)

Nach Voraussetzung gilt|R(xk, z,p)|

p|f(p)|6M

mp,

daher ist für |xk − z| klein genug

|R(xk, z,p)|

p|f(p)||xk − z| 6 1.

154 ©2018 Thomas Richter

Page 161: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Mit (1 + h)−1 = 1 +O(h) folgt schließlich

xk+1 − z =

(1 −

ω

p+O(|xk − z|)

)(xk − z).

Für ω = 1, also dem üblichen Newton-Verfahren, folgt lineare Konvergenz, für ω = p folgtlokal quadratische Konvergenz.

Bemerkung 7.17. Dieser Satz zeigt, dass sich das Newton-Verfahren auch für mehrfache Nullstelleneignet. Ist die Vielfachheit p der Nullstelle bekannt, so kann sogar quadratische Konvergenz gewonnenwerden. Im Allgemeinen wird es jedoch schwer sein, p optimal zu bestimmen.

Das Newton-Verfahren konvergiert im Einzugsbereich sehr schnell. Ein Nachteil ist natürlich,dass in jedem Schritt des Verfahrens die Ableitung f ′(xk) berechnet werden muss. Das kannunter Umständen sehr aufwendig sein. In vielen Fällen ist man daher an Varianten des Verfah-rens interessiert, welche die Berechnung der Ableitung vermeiden. Eine Möglichkeit ist, dieAbleitung nicht in jedem Schritt neu zu berechnen:

{algo:newton:einfach}Algorithmus 7.5: Vereinfachtes Newton-Verfahren

1 def newton_vereinfacht(x,n):

2 d = Dfkt(x) # Berechne Ableitung am Startwert

3 for i in range(n): # Iteration

4 x = x − fkt(x)/d # Update

Eine sinnvolle Wahl ist etwa c = x0. Es gilt:

Satz 7.18 (Konvergenz des vereinfachten Newton-Verfahrens). Es sei f ∈ C2([a,b]) und z ∈[a,b] eine Nullstelle. Weiter sei

m = minx∈[a,b]

|f ′(x)| > 0, M = maxx∈[a,b]

|f ′′(x)| <∞,

sowie ρ ∈ R mitq :=

2M

mρ < 1, Kρ(z) ⊂ [a,b].

Dann konvergiert für alle x0, c ∈ Kρ(z) das vereinfachte Newton-Verfahren linear gegen die Nullstelle.Es gilt

|xk − z| 6 qk|x0 − z|.

Beweis. Der Beweis ist eine einfache Modifikation von Satz 7.7.

Das vereinfachte Newton-Verfahren konvergiert nur noch linear. Die Konvergenz kann jedoch,falls f ′(c) eine gute Approximation für f ′(xk) ist, sehr gut sein. Das vereinfachte Newton-Verfahren spielt dann seine Vorteile aus, falls die erste Ableitung aufwendig zu berechnen ist.Ein Kompromiss zwischen schneller Konvergenz und effizienter Durchführung kann erreichtwerden, wenn die Ableitung nicht in jedem Schritt, aber z.B. in jedem n-ten Schritt neu aufge-baut wird. Dann kann superlineare Konvergenz gefolgert werden.

Eine weitere Variante des Newton-Verfahrens basiert auf der Approximation der Ableitungmithilfe eines Differenzenquotienten. Wir stellen einen einfachen Algorithmus vor:

[email protected] 155

Page 162: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

{algo:newton:einfach}Algorithmus 7.6: Approximiertes Newton-Verfahren

1 def newton_approximiert(x,n,eps):

2 for i in range(n): # Iteration

3 fx = fkt(x)

4 feps = fkt(x+eps)

5 x = x − eps∗fx/(fx−feps) # Update

Jeder Iterationsschritt erfordert die zweifache Auswertung der Funktion f. Hier habenwir deneinseitigen Differenzenquotienten gewählt. Es ist natürlich eine Variante mit dem zentralenDifferenzenquotienten

f ′(x) =f(x+ ε) − f(x− ε)

2ε+O(h2)

möglich. Dann müssen in jedem Schritt drei Auswertungen der Funktion f erfolgen. Für deneinfachen Differenzenquotienten gilt

f ′(x) =f(x+ ε) − f(x)

ε+f ′′(ξ)

mit ε ∈ [x, x+ ε]. Hiermit folgt für die Iteration

xk+1 = xk −f(xk)

f ′(xk) +f ′′(ξ)

2 ε= xk −

f(xk)

f ′(xk)

1

1 +f ′′(ξ)f ′(xk)

ε

.

Da ε klein ist, gilt mit (1 + h)−1 = 1 +O(h) weiter

xk+1 = xk −f(xk)

f ′(xk)+f(xk)f

′′(ξ)

f ′(xk)2O(ε).

Die approximierteNewton-Iteration ist alsowirklich eineApproximationdes üblichenNewton-Verfahrens. Für ε > 0 klein genug ist in der praktischen Anwendung gute Konvergenz zu er-reichen. Die korrekte Wahl von ε kann sich aber als sehr schwierig erweisen. Zu kleine Wertevon ε führen bei der Approximation der Ableitung zu Abschneidefehlern. Zu große ε führenzu einer schlechten Approximation der Ableitungen.

156 ©2018 Thomas Richter

Page 163: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.1. Methoden zur Nullstellensuche

Das folgende Python-Programm approximiert die kleinste Nullstelle bei x ≈ mit Hilfe desapproximierten Newton-Verfahrens bei verschiedenen Schrittweiten ε für die Berechnung desDifferenzenquotienten. Der Verlauf des Residuums |x(n)|wird jeweils graphisch dargestellt.

1 import matplotlib.pyplot as plt

2 import numpy as np

3

4 def fkt(x):

5 return (x∗(1+np.exp(x))+10∗(np.sin(3+np.log(x∗x+1))))∗np.abs(x+4)6

7 def newton_approx(x,tol,eps):

8 fx = fkt(x)

9 residual=[np.abs(fx)] # Alle Residuen merken

10 while np.abs(fx)>tol: # iterieren is Toleranz erreicht

11 feps = fkt(x+eps) # 2te Auswertung fuer Approximation f’

12 x = x − eps ∗ fx/(feps−fx) # update

13 fx = fkt(x) # neues residuum ausrechnen

14 residual.append(np.abs(fx)) # .. und merken

15 return residual ,x

16

17 R,z = newton_approx(−10,1.e−12,1.e−2)18 plt.semilogy(R,label="e−2")19 plt.legend()

20

21 R,z = newton_approx(−10,1.e−12,1.e−8)22 plt.semilogy(R,label="e−8")23 plt.legend()

24

25 R,z = newton_approx(−10,1.e−12,1.e−14)26 plt.semilogy(R,label="e−14")27 plt.legend()

28

29 plt.show()

Eine etwas exotische Variante des Newton-Verfahrens ist die Sekantenmethode. Sie ist eng ver-wandt mit dem approximierten Newton-Verfahren. Die Ableitung in xk wird approximiert alsDifferenzenquotient zwischen den beiden zurückliegenden Werten

f ′(xk) ≈f(xk) − f(xk−1)

xk − xk−1.

Dies führt zu der Iteration

xk+1 = xk −xk − xk−1

f(xk) − f(xk−1)f(xk).

Gilt im Laufe der Approximation xk → z, so folgt xk − xk−1 → 0, sodass die Genauigkeit derApproximation immer besser wird. Dies lässt auf gute Konvergenz des Verfahrens hoffen.

[email protected] 157

Page 164: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.2. Konvergenzbegriffe

7.2. Konvergenzbegriffe{Nullstellen_Konvergenztheorie}

In diesemAbschnitt wird die Konvergenz iterativer Verfahren anhand der bereits diskutiertenBeispiele in einen allgemeinen Rahmen gefasst. Die theoretischen Resultate werden allgemeinfür Fixpunktverfahren hergeleitet, sodass das Newton-Verfahren als ein Spezialfall aufgefasstwerden kann. Die Aussagen dieses Abschnitts sind auf andere iterative Verfahren, die wir spä-ter kennenlernen werden, ebenfalls anwendbar, z.B. auf die iterative Lösung von Gleichungs-systemen.

Definition 7.19 (Konvergenzordnung). Wir nennen ein Iterationsverfahren zur Berechnung einerNullstelle z von Konvergenz mit der Ordnung p mit p > 1, wenn gilt:

|xk − z| 6 c|xk−1 − z|p

mit einer festen Konstanten c > 0. Im Fall p = 1, d.h. linearer Konvergenz, heißt die beste Konstantec ∈ (0, 1) die lineare Konvergenzrate. Gilt bei linearer Konvergenzrate zusätzlich ck → 0 für k→∞,sprich

|xk − z| 6 ck |xk−1 − z|,

so sprechen wir von superlinearer Konvergenz.

Die folgenden Überlegungen sind durch die bereits bekannten Abschätzungen motiviert. Fürdie Intervallschachtelung gilt

|xn − z| 6b− a

2n+1

mit der Konvergenzrate 12 und der Konvergenzordnung p = 1 (lineare Konvergenz).

Das Newton-Verfahren besitzt (lokal) in der Umgebung einer Nullstelle das Konvergenzver-halten

|xk − z| 6 c |xk−1 − z|2.

Wir sprechen von einem quadratisch konvergenten Verfahren oder auch von einem Verfahren2ter Ordnung.

Grundsätzlich gilt (zumindest asymptotisch), dass superlinear konvergente Folgen schnellerals (schlicht) lineare Folgen konvergieren. Außerdem konvergieren Verfahren mit Ordnungp+1 schneller als Verfahren mit der Ordnung p. Außerdem gilt: Je kleiner die Konvergenzratec ist, desto schneller ist die Konvergenz. Allerdings hat die Konvergenzordnung wesentlichgrößeren Einfluss auf die Konvergenzgeschwindigkeit, als die Konvergenzrate.

Im Folgenden betrachten wir Fixpunktprobleme der Form

xk+1 = g(xk), k = 0, 1, 2, . . .

Bei Fixpunktiterationenmit stetig differenzierbarerAbbildungg(·) giltmit demMittelwertsatzder Analysis ∣∣∣∣xk+1 − z

xk − z

∣∣∣∣ = ∣∣∣∣g(xk) − g(z)xk − z

∣∣∣∣→ |g ′(z)| für k→∞ (7.11){nullstellen_equation_fixpunkt}{nullstellen_equation_fixpunkt}

Hieraus folgern wir, dass die lineare Konvergenzrate asymptotisch für k → ∞ gerade gleich|g ′(z)| ist. Dementsprechend liegt im Fall g ′(z) = 0 (mindestens) superlineare Konvergenz vor.

Aus (7.11) können wir folgende Definition ableiten:

158 ©2018 Thomas Richter

Page 165: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.2. Konvergenzbegriffe

Definition 7.20. Ein Fixpunkt z einer stetig differenzierbaren Abbildung g(·) heißt anziehend, falls|g ′(z)| < 1 ist. Im Fall |g ′(z)| > 1 wird ein Fixpunkt abstoßend genannt.

Der folgende Satz liefert ein einfaches Kriterium zur Bestimmung der Konvergenzordnungeiner differenzierbaren Fixpunktiteration. Er kann auch zur Konstruktion von Verfahren mithoher Ordnung genutzt werden: {nullstellen_satz_1}

Satz 7.21 (Iterative Verfahren mit Ordnung p > 2). Die Funktion g(·) sei in einer Umgebung desFixpunktes z p-mal stetig differenzierbar. Die Fixpunktiteration xk+1 = g(xk) hat genau dann dieOrdnung p, wenn

g ′(z) = . . . = g(p−1)(z) = 0 und g(p) 6= 0.

Beweis. (i) “⇐”Es sei g ′(z) = . . . = g(p−1)(z) = 0. Mithilfe der Taylor-Formel gilt

xk+1 − z = g(xk) − g(z) =

p−1∑j=1

(xk − z)j

j!g(j)(z) +

(xk − z)p

p!g(p)(ξk)

für ξk ∈ (xk+1, z). Damit erhalten wir die Abschätzung

|xk+1 − z| 61

p!max |g(p)| |xk − z|

p.

(ii) “⇒”Es sei nun umgekehrt die Iteration von p-ter Ordnung, sprich

|xk+1 − z| 6 c|xk − z|p.

Falls es ein minimalesm 6 p − 1 mit g(m)(z) 6= 0 gäbe, aber g(j)(z) = 0, j = 1, . . . ,m − 1, sowürde jede Iterationsfolge (xk)k∈N mit hinreichend kleinem |x0 − z| 6= 0) notwendig gegen zkonvergieren wie

|xk − z| 6

∣∣∣∣ 1

m!g(m)(ξk)

∣∣∣∣ |xk−1 − z|m,

also mit der Ordnungm. Hier finden wir aber einen Widerspruch zu der Annahme, dass dieIteration von der Ordnung p ist:

|g(m)(z)| = limk→∞ |g(m)(ξk)| 6 c m! lim

k→∞ |xk − z|p−m = 0

Hieraus folgt, dass für g ′(z) = . . . = g(p−1)(z) = 0, aber g(p)(z) 6= 0, sodass die Iteration nichtvon höherer Ordnung als p sein kann. {nullstellen_konvergenzbegriffe_darstellung_Newton_als_Fixpunkt}

Beispiel 7.22 (Newton-Verfahren als Fixpunktverfahren). Die allgemeine Fixpunktiteration lautet:

xk+1 = g(xk), k = 0, 1, 2, . . . (7.12) {nullstellen_konvergenzbegriffe_fixpunktiter}{nullstellen_konvergenzbegriffe_fixpunktiter}

Das bereits diskutierte Newton-Verfahren lässt sich in dieser Notation wie folgt herleiten. Es sei wieüblich f die Funktion des Nullstellenproblems und h eine hinreichend glatte Funktion, die in einerUmgebung der Nullstelle z nicht verschwindet. Es sei

g(x) := x+ h(x)f(x) (7.13) {nullstellen_konvergenzbegriffe_fixpunktfunktion}{nullstellen_konvergenzbegriffe_fixpunktfunktion}

[email protected] 159

Page 166: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

7.2. Konvergenzbegriffe

mit der Fixpunkt-Eigenschaft g(z) = z die zu (7.12) zugehörige Iterationsfunktion. Wir wollen h(x)so bestimmen, dass wir eine Fixpunktiteration der Ordnung 2 erhalten. Anwendung der Produktregelund Satz 7.21 ergeben in z

g ′(z) := 1 + h ′(z) f(z)︸︷︷︸=0

+h(z)f ′(x)!= 0.

Hieraus folgt die Bedingung an h(x) in z

h(z) = −1

f ′(z).

Wir wählen h(x) nun für alle x gemäß diese Vorschrift, sodass

h(x) := −1

f ′(x).

Einsetzen in (7.13) liefert die Iterationsfunktion

g(x) := x−f(x)

f ′(x),

und die Iterationsvorschrift

xk+1 := g(xk) = xk −f(xk)

f ′(xk), k = 0, 1, 2, . . .

Beispiel 7.23 (Konvergenzordnung des Newton-Verfahrens). Im umgekehrten Fall zu Beispiel7.22 sei das Newton-Verfahren nun als bekannt vorausgesetzt. Mithilfe des Satzes 7.21 kann explizitdie Konvergenzordnung des Newton-Verfahrens ermittelt werden. Es gilt

g ′(z) = 1 −f ′(z)2 − f(z)f ′′(z)

f ′(z)2=f(z)f ′′(z)

f ′(z)2= 0.

Für die zweite Ableitung gilt in der Nullstelle

g ′′(z) =f ′′(z)

f ′(z),

im Allgemeinen g ′′(z) 6= 0. Damit ist das Newton-Verfahren (wie bereits vorher diskutiert) lokal qua-dratisch konvergent.

160 ©2018 Thomas Richter

Page 167: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8. Optimierung

Unter einem Optimierungsproblem werden wir die Minimierung einer Funktion f(x) auf einemzulässigen Bereich X ⊂ Rn mit n ∈ N verstehen. Die Funktion f(x) nennen wir Zielfunktion.Gesucht ist also ein x ∈ Xmit der Eigenschaft

f(x) 6 f(y) ∀y ∈ X.

JedesMinimierungsproblem lässt sichmittelsg(x) := −f(x) als einMaximierungsproblem schrei-ben

minx∈X

f(x) ⇔ maxx∈X

g(x).

Daher werden wir stets nur Minimierungsprobleme untersuchen und definieren {def:minimierung}

Definition 8.1 (Minimierung). Es sei f : X → R mit X ⊂ Rn eine stetige Funktion. Ein Punktx ∈ Rn mit x ∈ X heißt zulässiger Punkt. x ∈ X heißt lokales Minimum falls es ein ε > 0 gibt, sodass

f(x) 6 f(y) ∀y ∈ Bε(x) := {z ∈ Rn ∩ X, ‖z− x‖ < ε},

er heißt striktes oder isoliertes Minimum falls es ein ε > 0 gibt, so dass

f(x) < f(y) ∀y ∈ Bε(x) := {z ∈ Rn ∩ X, ‖z− x‖ < ε},

er heißt globales Minimum fallsf(x) 6 f(y) ∀y ∈ X,

und globales striktes Minimum falls

f(x) < f(y) ∀y ∈ X.

Wir bezeichnen im Folgenden mit ‖ · ‖ : Rn → R die euklidische Norm und mit 〈·, ·〉 das eukli-dische Skalarprodukt.

In Abbildung 8.1 zeigen wir eine Funktion f ∈ C(R), welche alle diese beschiedenen Minimabesitzt

f(x) =

sin(4x) + sin(x) + 1

4x2 x < x∗,

sin(4x∗) + sin(x∗) +14x

2∗ x∗ 6 x 6 x∗ + 1

2

sin(4(x− 14)) + sin(x− 1

4) +14(x−

14)

2 x > x∗.

, x∗ ≈ 2.72086.

Das Auffinden von globalen Minima ist eine sehr schwierige Aufgabe, vergleichbar mit demFinden von allen Nullstellen einer Funktion. Wir werden uns daher im Wesentlichen mit derSuche nach lokalen Minima befassen.

Aus der Analysis kennen wir den Satz vom Minimum und Maximum, den wir hier in einer ein-fachen Form wiedergeben.

161

Page 168: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

-2

-1

0

1

2

3

4

5

6

7

-4 -2 0 2 4

×

Abbildung 8.1.: Funktion mit verschiedenenMinima. Durch ◦werden lokale isolierte Minimagekennzeichnet, durch× das globale (strikte)Minimumund der dick gekenn-zeichnete Bereich kennzeichnet ein nicht-isoliertes lokales Minimum. {fig:opt:minima}

Satz 8.2 (Satz vomMinimumundMaximum (imR)). Es sei [a,b] ein Intervall und f : [a,b]→ R

eine stetige Funktion. Dann ist f beschränkt und nimmt auf [a,b] das Minimum und Maximum an.D.h. es gibt zwei Werte xmin, xmax ∈ [a,b] mit

f(xmin) 6 f(x) 6 f(xmax) ∀x ∈ [a,b].

Beweis. (i) Wir nennen Y den Wertebereich von f. Dann existiert zu jeder Folge yk ∈ Y eineFolge xk ∈ [a,b] mit yk = f(xk). Da xk ∈ [a,b] beschränkt ist existiert eine Teilfolge diekonvergiert, xk ′ → x∗. Da [a,b] abgeschlossen ist gilt x∗ ∈ [a,b] und wegen der Stetigkeit vonf also y∗ := f(x∗) ∈M.

(ii)Wir zeigen nun, dass f (also Y) beschränkt sein muss. Angenommen, f ist nicht nach untenbeschränkt. Dann existiert eine divergente Folge yk ∈ Y. Es sei xk ∈ [a,b] die entsprechendeFolgemityk = f(xk). Dayk divergiert,muss auch jede Teilfolgeyk ′ divergieren. Dies ist jedochnach (i) ausgeschlossen, da [a,b] beschränkt ist. Also ist f nach unten beschränkt durch

−∞ < fmin := infx∈[a,b]

f(x).

Mit entsprechender Argumentation können wir die obere Schranke fmax <∞ herleiten.

(iii) Nun sei yk ∈ Y eine Folge, die gegen fmin konvergiert. Entsprechend ist xk ∈ [a,b] mityk = f(xk). Diese folge hat eine konvergente Teilfolge xk ′ → xmin und für den Grenzwert giltf(xk ′)→ fmin = f(xmin). Das Minimum wird also in xmin angenommen.

Dieser Beweis ist nicht konstruktiv.Wirwählenmehrfache Teilfolgen aus. Der Beweis lässt sichnicht in einem Algorithmus umsetzen. Auch sagt der Satz nichts über die Eindeutigkeit desMinimums voraus. Existieren zwei Punkte x, x ′, an denen jeweils f(x) = f(x ′) = fmin gilt, sosagt der Beweis nichts darüber, welcher dieser beiden Punkte mit der Folge erreicht wird. Es

162 ©2018 Thomas Richter

Page 169: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.1. Optimalitätsbedingungen

zeigt sich, dass die Aufgabe ein Minimum einer Funktion zu finden weitaus schwerer ist, alsz.B. die Aufgabe eine Nullstelle zu identifizieren.

DasMinimierungsproblem inDefinition 8.1 habenwir nicht nur für Funktionen über Interval-le [a,b] sonder im Mehrdimensionalen, d.h. für Funktionen f : X → R mit X ⊂ Rn definiert.Schauen wir uns den Beweis des Satzes vom Minimum und Maximum näher an, so identi-fizieren wir als zentrales Argument die Anwendung des Satzes von Bolzano-Weierstraß: Jedebeschränkte Folge im Rn besitzt eine konvergente Teilfolge. Wenn wir das Ergebnis vom Satz überdasMinimumundMaximum auf denRn übertragenwollen, somüssenwir nur voraussetzen,dass die Menge X beschränkt ist (denn dann ist jede mögliche Folge xk ∈ X beschränkt) unddass jeder Grenzwert einer Teilfolge xk ′ → x∗ in X liegt, also x∗ ∈ X. Die Menge X muss alsoabgeschlossen und beschränkt, somit kompakt sein.

Satz 8.3 (Satz vom Minimum und Maximum im Rn). Es sei X ∈ Rn eine nicht leere kompakteTeilmenge. f : X → R sei stetig. Dann nimmt f auf X sein Minimum und Maximum an, d.h. es gibt(mindestens) zwei Punkte xmin, xmax ∈ X mit

−∞ < f(xmin) 6 f(x) 6 f(xmax) <∞ ∀x ∈ X.

Oft werden restringierte Minimierungsprobleme untersucht. Dies sind Probleme mit einer Ne-benbedingung, also

minx∈X

f(x), so dass h(x) = 0,

mit einer Funktion h : Rn → Rm. Ein einfaches Beispiel ist die Suche von Extremwerten einerFunktion F : R2 → R entlang einer Kurve, z.B.

minx,y∈R

(3x2 + 2y2 − sin(πx)y2 − xy

), x2 + y2 = 1.

Für beide Probleme, restringiert und unrestringiert sind einfache Verfahren bekannt, die aufder Suche nach Nullstellen der Ableitung der zu minimierenden Funktion beruhen. Wir wer-den hier im Wesentlichen unrestringierte Minimierungsprobleme untersuchen.

8.1. Optimalitätsbedingungen

Wir werden zunächst Charakterisierungen von optimalen Lösungen, also Minima von Funk-tionen f : X → Rn kennenlernen. Dabei fordern wir neben der Stetigkeit von f auch dessenstetige Differenzierbarkeit. Diese Optimialtiätsbedingungen werden mit den einfachen Bedin-gungen übereinstimmen, wie wir sie von der Kurvendiskussion her kennen.

Satz 8.4 (Notwendige Optimalitätsbedingung erster Ordnung). Es sei f : X→ R stetig differen- {opt:satz:not1}zierbar auf der offenen Menge X ⊂ Rn und x ∈ X ein lokales Minimum von f. Dann gilt

∇f(x) = 0.

Beweis. Es sei y ∈ Rn. Dann gilt für ein ε > 0

f(x) 6 f(x+ hy) ∀|h| < ε.

[email protected] 163

Page 170: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.1. Optimalitätsbedingungen

Es folgt für

f(x+ hy) − f(x)

h> 0 für h > 0,

f(x+ hy) − f(x)

h6 0 für h < 0,

also bei h→ 0

limh→0

f(x+ hy) − f(x)

h= ∇f(x) · y = 0.

Der Grenzwert ist gerade der Gradient. Mit Taylor-Entwicklung gilt

limh→0

f(x+ hy) − f(x)

h=f(x) + h

∑ni=1

∂f(x)∂xi

+ o(h) − f(x)

h= ∇f(x).

Da y ∈ Rn beliebig ist folgt

∇f(x) · y = 0 ⇒ ∇f(x) = 0.

Definition 8.5 (Stationärer Punkt). Es sei f : X→ R auf der offenenMenge X ⊂ Rn differenzierbar.Dann heißt x ∈ X stationärer Punkt, falls ∇f(x) = 0 gilt.

Bei der Kurvendiskussion werden zunächst stationäre Punkte gesucht. Im Anschluss fällt dieUnterscheidung zwischen Minimum, Maximum und Sattelpunkt.

Definition 8.6 (Sattelpunkt). Ein stationärer Punkt, der weder Minimum noch Maximum ist, heißtSattelpunkt.

Es gilt:

Satz 8.7 (Notwendige Optimalitätsbedingung zweiter Ordnung). Es sei f : X → R eine auf deroffenen Menge X ⊂ Rn zweimal stetig differenzierbare Funktion. x ∈ X sei lokales Minimum von f.Dann ist x stationärer Punkt

∇f(x) = 0,

und die Hesse-Matrix∇2f(x) ist positiv semidefinit

〈∇2f(x)y,y〉 > 0 ∀y ∈ Rn.

Beweis. Es wurde bereits gezeigt, das x ∈ X stationärer Punkt ist. Nun sei wieder y ∈ Rnbeliebig und h < εmit einem ε > 0, so dass f auf Bε(x) ⊂ X zweimal stetig differenzierbar ist.Dann gilt mit Taylor-Entwicklung um x

f(x+ hy) = f(x) + h〈∇f(x),y〉+ h2

2〈∇2f(x)y,y〉+ ρ(h),

mit ρ(h) = o(h2). Hieraus folgt wegen f(x+ hy) > f(x) und ∇f(x) = 0, dass

0 6 f(x+ hy) − f(x) =h2

2(∇2f(x)y,y) + ρ(h),

also für h > 0 klein genug

〈∇2f(x)y,y〉 > −2ρ(h)

h2=o(h2)

h2→ 0 (h→ 0).

164 ©2018 Thomas Richter

Page 171: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.1. Optimalitätsbedingungen

Jedes lokale Minimum erfüllt wie gezeigt die beiden notwendigen Optimalitätskriterien. Ein-fache Beispiele wie

f(x) = x2k+1,

für k ∈ N zeigen jedoch bereits, dass die beiden Bedingungen nicht hinreichend sind. Es gilt:

Satz 8.8 (Hinreichende Optimalitätsbedingung zweiter Ordnung). Es sei f : X → R auf deroffenen Menge X ⊂ Rn zweimal stetig differenzierbar und x ∈ X ein stationärer Punkt in dem dieHessematrix positiv definit ist

(∇2f(x)y,y) > 0 ∀y ∈ Rn.

Dann ist x ein striktes lokales Minimum.

Beweis. Es existiert ein δ > 0, so dass

(∇2f(x)y,y) > δ‖y‖2 ∀y ∈ Rn.

Taylor-Entwicklung wie oben zeigt für y ∈ Rn mit ‖y‖ = 1,

f(x+ hy) − f(x) =h2

2(∇2f(x)y,y) + o(h2) >

δ

2h2 + o(h2).

Wegen o(h2)/h2 → 0 existiert ein ε > 0, so dass

f(x+ hy) − f(x) =h2

2(∇2f(x)y,y) + o(h2) >

δ

4h2 > 0.

Also ist x ein striktes lokales Minimum.

Die hinreichende Optimalitätsbedingung ist - wie der Name sagt - hinreichend, jedoch nichtnotwendig, wie das folgende einfache Beispiel zeigt:

f(x) = x2k+2,

für k ∈ N.

Die behandelten Optimalitätskriterien erfordern alle Differenzierbarkeit oder sogar zweimalstetigeDifferenzierbarkeit der untersuchten Funktion.Minima,MaximaundSattelpunkte kön-nen wir jedoch auch bei weniger Regularität sinnvoll erklären. Diese Lücke werden wir jedochhier nicht schließen können.

Beispiel 8.9. Wir betrachten die Funktion

f(x,y) = 4(x2 + y2) +x3y3

2+ x− y+ 1.

und suchen zunächst das Minimum von f auf dem Bereich

X = {(x,y) ∈ R2, x2 + y2 < 1}.

Wir bestimmen in einem ersten Schritt stationäre Punkte, also Nullstellen von

∇f(x) =(

8x+ 32x

2y3 + 18y+ 3

2x3y2 − 1.

)!= 0

[email protected] 165

Page 172: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.1. Optimalitätsbedingungen

Mit3

2x2y2 =

1 − 8y

x,

folgt8x+

1 − 8y

xy+ 1 = 0,

mit den beiden Lösungenx1(y) = −y, x2(y) = y−

1

8.

Einsetzen von x1(y) in ∂xf(x,y) = 0 und ∂yf(x,y) = 0 ergibt

−8y+3

2y5 + 1 = 0, 8y−

3

2y5 − 1 = 0,

also jeweils die identische Gleichung mit den reellen Nullstellen (numerisch bestimmt)

y1,1 ≈ 0.125, y1,2 ≈ 1.487, y1,3 ≈ −1.549.

Wir müssen nur y1,1 berücksichtigen, da die anderen nicht im Kreis liegen. Der erste Kandidat für einMinimum ist somit

{xm1 ,ym1 } ≈ {−0.125, 0.125}. (8.1){opt:bsp:kd:1}{opt:bsp:kd:1}

Wir setzen nun x2(y) in ∂xf(x,y) = 0 und ∂yf(x,y) = 0 ein und erhalten die Gleichungen

8y+3

2

(y−

1

8

)2

y2 = 0, 8y+3

2

(y−

1

8

)3

y2 − 1 = 0.

Diese beiden Gleichungen haben keine gemeinsame reelle Nullstelle.

Wir untersuchen nun, ob mit (8.1) ein Minimum vorliegt. Hierzu betrachten wir die Hessematrix

∇2f(x,y) =

(8 + 3xy3 9

2x2y2

92x

2y2 8 + 3x3y

).

Auf dem Quadrat [−1, 1]2, welches ganz X enthält gilt (elementweise)

∇2f(x,y) >

(5 9

292 5

).

Diese Matrix ist positiv definit, d.h. der gefundene stationäre Punkt ist das eindeutige isolierte Mini-mum der Funktion im Kreis X. Da X ⊂ [0, 1]2 wird auch kein Minimum auf dem Rand ∂X angenom-men. Für das gefundene Minimum gilt

f(xm1 ,ym1 ) ≈ 0.875.

Wir betrachten nun das Problem unter der Nebenbedingung

min{x,y}∈R2

f(x,y), so dass x2 + y2 = 1.

Für Punkte {xc,yc} auf dem Kreis gilt:

f(xc,yc) = 4 +x3cy

3c

2+ 1 + xc − yc.

166 ©2018 Thomas Richter

Page 173: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.1. Optimalitätsbedingungen

Auf den beiden Kreisbögen yc = ±√

1 − x2c lautet die Funktion

f1/2(x) = 5 + x±√

1 − x22 + x5 − x3

2x ∈ [−1, 1],

mit den Ableitungen

∂xf1/2(x) =2√

1 − x2 ± x(6x5 − 9x3 + 3x+ 2)

2√

1 − x2,

mit den Nullstellenx1/2 = ±

1√2

,

jeweils in den Teilen f1(x) und f2(x). Wir betrachten wieder die Hessematrix, hier also die zweite Ab-leitung

∂xxf1/2(x) =30x7 − 63x5 + 393 − 6x− 2

2(1 − x2)32

Es gilt:∂xxf1(x1) ≈ 4.23 > 0, ∂xxf2(x2) ≈ −1.33 < 0,

d.h., im Punktxm = −

1√2

, ym =√

1 − x2 =1√2

,

liegt das isolierte strikte Minimum auf der Kreislinie mit dem Wert

f(xm,ym) ≈ 3.523.

Ob ein Minimum ein globales ist, ist eng mit der Konvexität der Funktion f verknüpft. Wirdefinieren: {konvexe Menge}

Definition 8.10 (Konvexe Menge). Eine Menge X ⊂ Rn heißt konvex, falls für alle x,y ∈ X dieVerbindungslinie zwischen x und y komplett in X liegt, falls also

(1 − s)x+ sy ∈ X ∀s ∈ [0, 1].

Für Funktionen definieren wir weiter {konvexe Funktion}

Definition 8.11 (Konvexe Funktion). Es sei X ⊂ Rn eine konvexe Menge. Eine Funktion f : X→ R

heißt konvex falls für alle x,y ∈ X gilt

f((1 − s)x+ sy) 6 (1 − s)f(x) + sf(y) ∀s ∈ [0, 1].

Sie heißt streng oder strikt konvex, falls für alle x,y ∈ X mit x 6= y gilt

f((1 − s)x+ sy) < (1 − s)f(x) + sf(y) ∀s ∈ [0, 1].

Und sie heißt gleichmäßig konvex falls es ein µ > 0 gibt, so dass für alle x,y ∈ X

f((1 − s)x+ sy) + µs(1 − s)‖y− x‖2 6 (1 − s)f(x) + sf(y) ∀s ∈ [0, 1].

gilt.

[email protected] 167

Page 174: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.1. Optimalitätsbedingungen

Differenzierbare Funktionen erlauben die folgende Charakterisierung der verschiedenen Kon-vexitätsbegriffe: {opt:satz:kf}

Satz 8.12 (Konvexe, stetig differenzierbare Funktionen). Es sei f : X → R stetig differenzierbarauf der konvexen Menge X ⊂ Rn. Es gilt

1. Die Funktion f ist konvex genau dann, wenn für alle x,y ∈ X

(∇f(x),y− x) 6 f(y) − f(x).

2. Die Funktion f ist strikt konvex genau dann, wenn für alle x,y ∈ X

(∇f(x),y− x) < f(y) − f(x).

3. Die Funktion f ist gleichmäßig konvex genau dann, wenn es ein µ > 0 gibt, so dass für allex,y ∈ X

(∇f(x),y− x) + µ‖y− x‖2 < f(y) − f(x).

Beweis. Übung.

Für zweimal stetige Funktionen erhalten wir weiter{opt:satz:konv2}

Satz 8.13 (Konvexe, zweimal stetig differenzierbare Funktionen). Es sei f : X→ R zweimal stetigdifferenzierbar auf der konvexen Menge X ⊂ Rn. Dann gilt

1. Die Funktion f ist konvex genau dann, wenn die Hessematrix positiv semidefinit ist.

2. Die Funktion f ist strikt konvex, falls die Hessematrix positiv definit ist.

3. Die Funktion f ist gleichmäßig konvex genau dann, wenn es ein µ > 0 gibt, so dass die Hessema-trix gleichmäßig positiv definit ist, also

(∇2f(x)y,y) > µ‖y‖2 ∀x ∈ X, y ∈ Rn.

Beweis. Übung.

Die Konvexität erlaubt uns nun, die folgenden starken Aussagen zu treffen:{opt:satz:konvex}

Satz 8.14 (Minimum einer konvexen Funktion). Es sei f : X → R eine konvexe Funktion auf derkonvexen Menge X ⊂ Rn. Dann gilt:

1. Jedes lokale Minimum x ∈ X von f(·) ist auch globales Minimum.

2. Ist f strikt konvex, so besitzt f höchstens ein lokales Minimum. Dieses ist gleichzeitig das isolierteglobale Minimum.

3. Ist f stetig differenzierbar und x ∈ X ein stationärer Punkt, so ist x globales Minimum.

168 ©2018 Thomas Richter

Page 175: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

Beweis. (i) x sei lokales Minimum. Angenommen, ein y ∈ X existiert mit f(y) < f(x). Danngilt:

f((1 − s)x+ sy) 6 (1 − s)f(x) + sf(y) < (1 − s)f(x) + sf(x) = f(x).

Für s→ 0 zeigt sich ein Widerspruch zu der Annahme, dass x lokales Minimum ist.

(ii) x sei wieder lokales Minimum. Angenommen, y ∈ X mit y 6= x existiert mit f(x) = f(y).Dann gilt

f((1 − s)x+ sy) < (1 − s)f(x) + sf(y) = (1 − s)f(x) + sf(x) = f(x).

Dies ist bei s→ 0 wieder ein Widerspruch zur lokalen Minimaleigenschaft von x.

(iii) Jetzt sei x ∈ Xmit ∇f(x) = 0. Nach Satz 8.12, Teil 1 gilt für alle ymit y 6= x

f(y) − f(x) > (∇f(x),y− x) = 0,

also ist f(x) globales Minimum.

8.2. Abstiegsverfahren und das Gradientenverfahren

Wir leiten nun iterative Verfahren zur Minimierung einer Funktion f ∈ X ⊂ Rn für n ∈ Nher. Hierzu sei xk ∈ X eine Schätzung für denMinimalpunkt in Schritt k ∈ N. Wir bestimmenzunächst eine Abstiegsrichtung dk ∈ Rn und bestimmen die nächste Iteration als

xk+1 = xk + sdk,

so dassf(xk+1) < f(xk + sdk).

Zwei Aufgaben sind zu bewältigen: 1. dieAbstiegsrichtung dk bestimmen und 2. die Schrittweites ∈ R.

Ist eine Abstiegsrichtung dk ∈ Rn bekannt, so lässt sich die optimale Schrittweite als Lösungeines skalaren (also 1-dimensionalen) Optimierungsproblems bestimmen

sopt = arg mins∈R

f(xk + sdk),

dabei bezeichnet arg min das Argument des Minimums, also den gefundenen Wert s ∈ R. ImLaufe des Verfahrens zum Finden eines Minimums muss in jedem Schritt ein Minimum be-rechnet werden. Ob wohl dieses Problem nur 1-dimensional und nicht n-dimensional ist, istdieses Vorgehen nicht praktikabel. Stattdessen werden wir Methoden zur Schrittweitenbestim-mung kennenlernen, die eine gute Näherung für sopt auf einfacheWeise bestimmen. Zunächstbefassen wir uns jedoch mit der Suche nach einer möglichst guten Abstiegsrichtung dk ∈ Rn.

[email protected] 169

Page 176: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

8.2.1. Das Gradientenverfahren{def:opt:abstiegsrichtung}

Definition 8.15 (Abstiegsrichtung). Es sei f : X → R eine stetig differenzierbare Funktion. EinVektor d ∈ Rn heißt Abstiegsrichtung zu einem Punkt x ∈ X, falls

〈∇f(x),d〉 < 0

gilt.

Angenommen d sei zu x ∈ X eine Abstiegsrichtung, dann gilt:

f(x+ sd) − f(x)

s−−−→s→0

〈∇f(x),d〉 < 0,

d.h., in Richtung d ist die zu minimierende Funktion fmonoton fallend. Wir definieren

F(s; x,d) := f(x+ sd).

F(s) nimmt für s > 0 lokal ab, d.h. die Abstiegsrichtung ist wirklich eine gute Wahl zur Mini-mierung der Funktion.

Wir stellen uns nun der Aufgabe, in einem Punkt x ∈ X die optimale Abstiegsrichtung zufinden und suchen das Minimum von

mind∈Rd, ‖d‖=1

(∇f(x),d). (8.2){opt:3}{opt:3}

Die so gefundene Abstiegsrichtung nennen wir Richtung des steilsten Abstiegs. Es gilt:

Satz 8.16 (Optimale Abstiegsrichtung). Es sei f : X → R eine stetig differenzierbare Funktion. Seix ∈ X mit ∇f(x) 6= 0. Die Richtung des steilsten Abstiegs in x ist eindeutig gegeben als

d = −∇f(x)‖∇f(x)‖

.

Beweis. Es gilt für beliebige d ∈ Rn mit ‖d‖ = 1

〈∇f(x),d〉 > −‖∇f(x)‖ ‖d‖ = −‖∇f(x)‖.

Einzig im Fall d = −∇f(x)/‖∇f(x)‖ gilt Gleichheit:

〈∇f(x),d〉 = −‖∇f(x)‖.

Somit ist durch −∇f(x)/‖∇f(x)‖ die eindeutige normierte Richtung des steilsten Abstiegs ge-geben.

Mit dieser Abstiegsrichtung können wir nun das Gradientenverfahren als spezielle Variante desallgemeinen Abstiegsverfahrens definieren:

170 ©2018 Thomas Richter

Page 177: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

{algo:gradient}Algorithmus 8.1: Gradientenverfahren

1 def f(x): # die zu minimierende Zielfunktion

2 ...

3

4 def gradient(x): # Gradient der Zielfunktion an Stelle x

5 ...

6

7 def gradientenverfahren(x):

8 # x ist der Startwert

9

10 while ???: # Iteration. Abbruchskriterium?

11 d = −gradient(x) # Abstiegsrichtung

12 s = schrittweite(x,d) # Bestimme Schrittweite

13 x = x+s∗d # Optimierungsschritt

In diesem Algorithmus sind einige Bestandteile noch nicht ausformuliert. Zunächst fehlt unsein Algorithmus zur Bestimmung einer guten Schrittweite s ∈ R in Zeile 13. Weiter fehlt unsnoch ein Kriterium zumAbbruch der Iteration. Wir müssen davon ausgehen, dass wir nie dasgesuchte Minimum finden. Entweder geben wir uns eine Anzahl an Iterationen vor, oder aberwir benötigen eine Fehlerschätzung um die Genauigkeit zu ermitteln. Hier bietet sich das 1teOptimalitätskriterium an. Im Minimum xmin ∈ Rn gilt ∇f(xmin) = 0. Das Gradientenverfah-ren könnte folgendermaßen konkretisiert werden:

Algorithmus 8.2: Gradientenverfahren mit Abbruch1 def gradientenverfahren(x,tol):

2 d = −gradient(x)3

4 while np.linalg.norm(d,2)<tol: # eukl. Norm

5 s = schrittweite(x,d)

6 x = x+s∗d7 d = −gradient(x)

Die Toleranz tolwird als Parameter übergeben.

8.2.2. Schrittweitenwahl

Wir gehen nun davon aus, dass zu einer Iteration x ∈ X eine Abstiegsrichtung d ∈ Rn mit‖d‖ = 1 vorliegt. Dies kann z.B. die Richtung des steilsten Abstiegs des Gradientenverfahrenssein. Nun gilt es, die Schrittweite s ∈ R so zu bestimmen, dass

f(x+ sd) < f(x).

Wir betrachten hierzu ein Beispiel. Es sei

f(x) = 3x21 + 2x22 − sin(πx1)x22 − x1x2, ∇f(x) =

(6x1 − π cos(πx1)x

22 − x2

4x2 − 2 sin(πx1)x2 − x1

)

[email protected] 171

Page 178: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

Angenommen, x = (1/2, 0), dann ist die Richtung des steilsten Abstiegs gegeben durch

d = −∇f(0)‖∇f(0)‖

=1√37

(−61

),

bzw. durch Vielfache. Die optimale Schrittweite ergibt sich dann als Lösung des eindimensio-nalen Minimierungsproblems

minsF(s) = f

((120

)+ s

(−61

))= 3

(1

2− 6s

)2

+ 2s2 − sin

(1

2− 6s

))s2 −

(1

2− 6s

)s

(8.3){opt:5}{opt:5}

Die Lösung von diesem skalaren Optimierungsproblem ist nicht trivial und stellt einen erheb-lichen Aufwand dar.

Zur praktischen Bestimmung einer Schrittweite geht man üblicherweise iterativ vor. Ein sehreinfaches Verfahren ist die Line-SearchMethode. Ausgehen von x und der Richtung d testenwir,ob die neue Lösung

xs = x+ sd,

für die Werte s = 1, s = β, s = β2, ... z.B. für β = 1/2 eine Reduktion der Zielfunktion liefert.

1 # x ist alte Lösung

2 # d ist die Suchrichtung

3 # beta ist der Line−Search Parameter4 def linesearch(x0,d,beta)

5 res0 = f(x0) # Start−Residuum6 s = 1 # Schrittweite

7 x=x0+s∗d8

9 while f(x)>res0: # Reduktion erreicht?

10 s = s∗beta11 x = x0+s∗d12 return s

In Verbindung mit dem Gradienten als Suchrichtung kann garantiert werden, dass sich dieZielfunktion im Schritt xk 7→ xk+1 wirklich reduziert, das also f(xk+1) = f(xk + sdk) < f(xk)gilt. Wir können aber nicht garantieren, wie groß der Abfall in der Zielfunktion f(·) ist. In derAnwendung verwendet man im Allgemeinen eine Modifikation, die Armijo-Schrittweitenregel,bei welcher die Bedingung für den Abbruch verschärft wird zu

f(xk + sd)!< f(xk) + sγ〈∇f(xk),dk〉,

mit einem weiteren Parameter γ > 0. Wegen dk = −∇f(xk) gilt

sγ〈∇f(xk),dk〉 = −sγ‖∇f(xk)‖2 < 0,

die Bedingung ist also in der Tat schärfer undwir können einen gewissen Abstieg garantieren.

172 ©2018 Thomas Richter

Page 179: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

Algorithmus 8.3: Armijo-Regel1 # x ist alte Lösung

2 # d ist die Suchrichtung

3 # beta, gamma sind die Armijo−Parameter4 def armijo(x0,d,beta,gamma)

5 res0 = f(x0) # Start−Residuum6 s = 1 # Schrittweite

7 x=x0+s∗d8

9 dd = np.dot(gradient(x0),d) # Für die Abbruch−Bedingung10

11 while f(x)>res0 + s∗gamma∗dd:12 s = s∗beta13 x = x0+s∗d14 return s

Eine übliche Wahl für β ist z.B. β = 0.5. Der Parameter γ steuert, welches Minimierungszielzu erreichen ist.

Es stellt sich nun die Frage, ob die Armijo-Schrittweitenregel immer zum Erfolg führt, alsonach einer endlichen Zahl von Schritten abbricht. Es gilt: {opt:satz:armijo}

Satz 8.17 (Armijo-Schrittweitenregel). Es sei f : X → R auf der offenen Menge X ⊂ Rn stetigdifferenzierbar. Es sei γ ∈ (0, 1) und d ∈ Rn eine beliebige Abstiegsrichtung zu einem Punkt x ∈ Xnach Definition 8.15. Dann existiert ein k ∈ N, so dass

sk = βk, f(x+ skd) − f(x) 6 γsk〈∇f(x),d〉.

Beweis. Es gilt für γ ∈ (0, 1)

f(x+ sd) − f(x)

s− γ〈∇f(x),d〉 → (1 − γ)〈∇f(x),d〉 < 0 (s→ 0).

Für s klein genug folgt wegen der Stetigkeit von ∇f, dass es ein ε gibt, so dass für alle s < εgilt

f(x+ sd) − f(x)

s− γ〈∇f(x),d〉 6 0 ∀|s| < ε.

Für β ∈ (0, 1) findet sich ein minimales k ∈ N, so dass sk := βk < ε gilt.

Der Algorithmus zur Schrittweitenwahl terminiert also stets. Unter Umständenwerden jedochsehr viele Schritte innerhalb des Armijo-Verfahrens benötigt.

8.2.3. Konvergenz des Gradientenverfahrens

Wir analysieren nundieKonvergenzdesGradientenverfahrens ausAlgorithmus ??mitArmijo-Schrittweitensteuerung. Zunächst könnenwir allgemeineKonvergenz (jedochnoch keineKon-vergenzgeschwindigkeit) nachweisen:

[email protected] 173

Page 180: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

Satz 8.18 (Konvergenz des Gradientenverfahrens). Es sei f : Rn → R stetig differenzierbar, x0 ∈Rn ein beliebiger Startvektor. Dann erzeugt das Gradientenverfahren eine unendliche Folge xk ∈ Rnund bricht entweder mit einem stationären Punkt∇f(xk) = 0 ab, oder hat die Eigenschaft:

1. Es gilt f(xk+1) < f(xk)

2. Jeder Häufungspunkt von xk ist stationärer Punkt.

Beweis. (i)Wir betrachten nur den Fall, dass das Verfahren nichtmit einem exakten stationärenPunkt abbricht. Laut Satz 8.17 gilt für die Iterierten

f(xk+1) − f(xk) = f(xk + skdk) − f(xk) 6 −skγ‖∇f(xk)‖2 < 0.

Hieraus folgt, die strenge Monotonie von f(xk).

(ii)Die Folge xk hat inR∪{∞}∪{−∞} einenHäufungspunkt, wir nennen ihn x undmit xk ′ → x

bezeichnen wir eine Teilfolge, die gegen x konvergiert.

Die Folge fk := f(xk) ist monoton fallend und hat daher einen Grenzwert in R ∪ {−∞}. Wirbezeichnen diesen Grenzwert mit

f = limk→∞ f(xk).

Für die Teilfolge xk ′ gilt dann natürlich

f = limk ′→∞ f(xk ′).

Da die Funktion f(·) stetig ist folgtf = f(x),

und schließlich auchlimk→∞ f(xk) = f(x).

(iii) Wir verwenden die Armijo-Schrittweitenregel. Daher gilt:

f(x0) − f(x) =

∞∑k ′=0

(f(xk

′) − f(xk

′+1))> γ

∞∑k ′=0

sk ′‖∇f(xk′)‖2

Es folgtsk ′‖∇f(xk

′)‖2 → 0. (8.4){opt:grad:konv:1}{opt:grad:konv:1}

Angenommen, es ist∇f(x) 6= 0. Wegen der Stetigkeit von∇f(x) existiert ein k ′0 ∈ N, so dass

‖∇f(xk ′)‖ > ‖∇f(x)‖2

> 0 ∀k ′ > k ′0.

Wegen (8.4) muss dannsk ′ → 0,

d.h. es existiert ein k ′1 ∈ Nmit sk ′ 6 β für alle k ′ > k ′1. Es folgt

f(xk′+sk ′

βdk′) − f(xk

′) > −

γsk ′

β‖∇f(xk ′)‖2 ∀k ′ > k ′1. (8.5){opt:grad:konv:2}{opt:grad:konv:2}

174 ©2018 Thomas Richter

Page 181: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.2. Abstiegsverfahren und das Gradientenverfahren

Die Folge (β−1sk ′) ist eineNullfolge.NachdemMittelwertsatz existiert eine Folge τk ′ ∈ [0,β−1sk ′ ]mit

limk ′→∞ f(x

k ′ + β−1sk ′dk ′) − f(xk

′)

β−1sk ′= limk ′→∞ β

−1sk ′(∇f(xk′+ τk ′d

k),dk)

β−1sk ′= −‖∇f(x)‖2.

Dies ist mit (8.5) ein Widerspruch zu

(1 − γ)‖∇f(x)‖2 6 0.

Die Annahme ∇f(x) 6= 0 ist also falsch.

Beispiel 8.19 (Rosenbrock-Funktionen). Wir betrachten die Funktion

f(x,y) = α(y− x2)2 + (1 − x)2,

mit einem Parameter α > 0. Diese einfache Klasse von Funktionen erweist sich als schwieriger Test-fall für Optimierungsprobleme. Wir analysieren die Funktion zunächst durch exakte Rechnung. Fürstationäre Punkte gilt:

∇f(x,y) =(−4xα(y− x2) − 2(1 − x)

2α(y− x2)

)!= 0,

alsox = 1, y = 1, f(1, 1) = 0.

Weiter ist:∇2f(1, 1) = α

(8 + 2

α −4−4 2

),

mit den Eigenwertenλ1/2 = 1 + 5α±

√25α2 + 6α+ 1.

Diese Eigenwerte sind für alle α > 0 positiv. Es liegt also ein striktes Minimum vor.

Wir verwenden nun das Gradientenverfahren mit Armijo-Schrittweitenbedingung zum Lösen diesesMinimierungsproblems. In Abbildung ?? zeigen wir den Konvergenzverlauf von für zwei verschiedeneStartwerte

(x0,y0) = (−1, 1.5), (x0,y0) = (2, 2).

Es zeigt sich jeweils, dass die Approximation stark oszilliert. Die Suchrichtungen sind wieder paarweise(fast) orthogonal. Wir haben hierβ = 0.5 und γ = 0.1 gewählt. Der Einfluss dieser Parameter ist jedochgering.

Wir fassen in der folgenden Tabelle den Konvergenzverlauf zusammen:

k xk yk ‖∇f(xk)‖ f(xk)

0 1.5 6.5 3561 -1.212 1.3675 4.9958 9.55972 -1.0898 1.3940 4.7929 6.33823 -1.1373 1.3533 4.6039 1.95854 -1.0384 1.2768 4.5494 5.76005 -1.0836 1.2337 4.3770 1.9861

· · ·

k xk yk ‖∇f(xk)‖ f(xk)

· · ·100 1.0050 1.0100 2.55e-05 0.012493101 1.0048 1.0101 2.52e-05 0.012492102 1.0049 1.0099 2.48e-05 0.012491103 1.0047 1.0099 2.44e-05 0.012491104 1.0049 1.0097 2.41e-05 0.012490105 1.0046 1.0098 2.37e-05 0.012489

[email protected] 175

Page 182: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

8.3. Parameteridentifikation

Bei der Parameteridentifikation untersuchen wir die folgende Frage: durch f(x;q) : X×Q→ Rn

sein ein Modell gegeben, welches in Abhängigkeit von Parametern q ∈ Q für jedes x ∈ Xeine Ausgabe liefert. Ein einfaches Modell könnte z.B. der Zerfallsprozess eines radioaktivenStoffes sein, der gemäß

f(t; q) = q0 exp(−q1t)

abläuft, wobei q0 die Stoffmenge zum Zeitpunkt t = 0 ist und q1 die Zerfallsrate. Hier istQ = R2, genauer

Q = {(x,y) ∈ R2 | x > 0 y > 0}.

Wollen wir nun einen unbekannten Stoff identifizieren, so können wir mittels Messungen dervorhandenen Stoffmenge zu verschiedenen Zeiten, {(ti, fi), i = 1, . . . ,N} die Parameter q =(q0,q1) bestimmen.

In unserem Beispiel genügen hierzu zwei Werte, etwa

t 4.208 7.414f 0.1013 0.02517

Wir erhalten

f(4.208;q) := q0 exp(−q14.208) = 0.1013

f(7.414;q) := q0 exp(−q17.414) = 0.02517⇒ 0.1013

0.02517= exp (−q1(4.208 − 7.414)) ,

also

q1 ≈ln(

0.10130.02517

)7.414 − 4.208

= 0.4343,

undq0 ≈ 0.1013 exp (0.4343 · 4.208) ≈ 0.623.

Somit ermitteln wir das Zerfallsgesetz

f(t) = 0.623 exp (−0.4343t) (8.6){zerfallsgesetz}{zerfallsgesetz}

und könnten anhand der Zerfallskonstante −0.4343 Rückschlüsse auf den Stoff ziehen. EinProblem an diesem Vorgehen ist, dass wir bei der Verwendung von Messwerten von mögli-chen Messfehlern ausgehen müssen. Stellen wir uns vor, wir hätten einen dritten Messwertzur Verfügung

t 4.208 7.414 3.173f 0.1013 0.02517 0.188

Testen wir das bisherigeModell (8.6), so erhalten wir

f(3.173) = 0.623 exp (−0.4343 · 3.173) ≈ 0.157,

176 ©2018 Thomas Richter

Page 183: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

also einen relativen Fehler0.188 − 0.157

0.188≈ 0.16

von 16%. Wir können die zwei Unbekannten q0,q1 jedoch nicht unter Verwendung aller dreiBedingungen bestimmen um die Approximation zu verbessern.

Im Folgenden gehenwir davon aus, dassN ∈ NMesspaare (ti, fi) gegeben sind und dassN�dim(Q), also das die Anzahl der Messwerte die Dimension des Parameterraums übersteigt.Wir suchen nun die beste Lösung, die allen Messwerten möglichst nahe kommt.

Definition 8.20 (Kleinste Fehlerquadrate). Es sei f(x; q) : X ×Q → Rd ein parameterabhängigesModell, (xi, fi) ∈ X × Rd für i = 1, . . . ,N Messwerte. Eine Bestapproximation im Sinne derkleinsten Fehlerquadrate qopt ∈ Q, auch Least-Squares Lösung gennant, ist gegeben durch

N∑i=1

1

2‖fi − f(xi, qopt)‖2 6

N∑i=1

1

2‖fi − f(xi, q)‖2 ∀q ∈ Q.

Dabei ist ‖ · ‖ die euklidische Norm.

8.3.1. Gaußsche Ausgleichrechnung

Eine besondere Form derMethode der kleinsten Fehlerquadrate ist dieGaußsche Ausgleichrech-nung. Hier ist das zugrundeliegende Modell linear, d.h. für x ∈ X = Rm und q ∈ Q = Rm

ist

f(x;q) =

m∑j=1

qjxj.

Angenommen, (xi,yi) für i = 1, . . . ,N sind Messwerte, dann lässt sich die gesuchte Lösungschreiben als

y1 =

m∑j=1

(x1)jqj

...

yN =

m∑j=1

(xN)jqj,

oder aber mit x = (xi)i ∈ RN, y = (yi)i ∈ RN und q = (qj)j ∈ Rm als

Aq = x, (8.7) {ls:1}{ls:1}

mit der MatrixA = (aij)

nij=1, aij = (xi)j

Es istA ∈ RN×m und fürN� m (dies ist der Fall, der uns interessiert) ist das Gleichungssys-tem überbestimmt. Es existiert somit im Allgemeinen keine Lösung.

[email protected] 177

Page 184: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Satz 8.21 (Gaußsche Ausgleichrechnung). Es seiA = (aij) ∈ RN×m mitN > m und rang(A) =m, y = (yj) ∈ RN. Dann ist die Bestapproximation im Sinne der kleinsten Fehlerquadrate

N∑i=1

1

2|yi −

m∑j=1

aijqj|2 → min

eindeutig und bestimmt als Lösung des Normalgleichungssystems

ATAq = ATy.

Beweis. (i) Es sei

J(q) :=

N∑i=1

1

2|yi −

m∑j=1

aijqj|2 =

1

2〈y −Aq, y −Aq〉 = 1

2‖y −Aq‖2.

Wir untersuchen J(·) auf stationäre Punkte und betrachten hierzu zunächst die ersten Ablei-tungen

∂J(q)

∂qk= −

N∑i=1

(yi −

m∑j=1

aijqj)aik, k = 1, . . . ,m

welche den Gradienten ergeben

∇J(q) = AT (y −Aq). (8.8){ls:2}{ls:2}

Die zweiten Ableitungen

∂2J(q)

∂qk∂ql=

N∑i=1

ailaik, k, l = 1, . . . ,m

ergeben die Hessematrix∇2J(q) = ATA. (8.9){ls:3}{ls:3}

(ii) Aus (8.8) ergibt sich die Gleichung

ATAq = ATy (8.10){ls:4}{ls:4}

als Bedingung für den stationären Punkt. Die Hessematrix ist positiv semidefinit definit, da

〈ATAq, q〉 = ‖Aq‖2 > 0

Da der Rang von Amaximal ist folgt darüber hinaus die positive Definitheit

〈ATAq, q〉 = ‖Aq‖2 = 0 ⇒ q = 0.

Gleichung (8.10) hat somit eine eindeutige Lösung, den stationären Punkt qstat.

Aus Satz 8.13 folgt die strikte Konvexität von J(q) undmit Satz 8.14 folgt nun die Eindeutigkeitdes globalen Minimums qopt = qstat.

Zum Lösen des Normalgleichungssystems ATAq = ATy werden in der Numerischen Mathe-matik geeignete Verfahren entwickelt, z.B. die QR-Zerlegung, die eine effiziente und robusteLösung erlaubt, siehe z.B. [11]. Ein Aufstellen der Matrix ATA ist aufgrund der schlechtenKonditionierung nicht sinnvoll. Im schlimmsten Fall gilt

cond(ATA) ≈ cond(A)2.

178 ©2018 Thomas Richter

Page 185: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

8.3.2. Allgemeine Parameterschätzungsprobleme

Wir betrachten nun das allgemeine Least-Squares Problem

J(q) :=1

2

N∑i=1

|yi − f(xi; q)|2 → min

und wählen hierzu das Gradientenverfahren. Der Gradient berechnet sich als

∂J(q)

∂qk= −

N∑i=1

(yi − f(xi; q))∂f(xi; q)

∂qk. (8.11) {ls:6}{ls:6}

Mit demGradientenverfahren kann das Problem in Python einfach umgesetzt werden. Hierzudefinieren wir uns zunächst die Funktion f(q), die Zielfunktion J(q) sowie deren Gradienten

Algorithmus 8.4: Least-Squares I: Zielfunktion1 ### Das Modell: Auswertung und Gradient

2 def f(x,q):

3 return q[0]∗np.exp(−q[1]∗x)4

5 def gradient_f(x,q):

6 return np.array( [np.exp(−q[1]∗x), −q[0]∗x∗np.exp(−q[1]∗x)] )7

8 ### Die Zielfunktion zur Minimierung und ihr Gradient

9 def J(X,Y,q):

10 Z = Y−f(X,q)11 return 0.5∗np.dot(Z,Z) # ’dot’ ist Skalarprodukt

12

13 def gradient_J(X,Y,q):

14 grad = gradient_f(X,q)

15 res = Y−f(X,q)16 return −grad@res

Unter Verwendung von numpy kann die eigentlich skalar definierte Funktion def f(x,q): auchfür ganze array’s verwendet werden. Die Zielfunktion berechnen wir mittels des Skalarpro-dukts np.dot(..,..). Der Funktionsaufruf gradient_f(X,q) liefert eine Matrix der Größe 2 ×N,daher kann zur Gradientenberechnung gemäß (8.11) die Matrix-Vektor Multiplikation @ ver-wendet werden.

Als nächstes geben wir das Gradientenverfahren für die Least-Squares Lösung an

Algorithmus 8.5: Least-Square II: Gradientenverfahren1 def gradientenverfahren(q,Xt,Yt,tol):

2 print(’J(q_0)=%f’ % J(Xt,Yt,q))

3 g = −gradient_J(Xt,Yt,q)4 step = 0

5 while np.linalg.norm(g,2)>tol:

6 s = armijo(Xt,Yt,q,g)

[email protected] 179

Page 186: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

7 q = q + s∗g8 g = −gradient_J(Xt,Yt,q)9 step = step+1

10 assert step<100,’Zu viele Schritte!’

11 print(’%d Schritte. J_min=%f’ % (step,J(Xt,Yt,q)))

12 return q

In maximal 100 Schritten (siehe die Abfrage in Zeile 10) versuchen wir den stationären Punktmit dem Residuum ‖∇J(q)‖2 < tol zu erreichen. Es fehlt noch die Schrittweitensteuerung mitdem Armijo-Verfahren:

Algorithmus 8.6: Least-Square III: Schrittweitensteuerung1 def armijo(Xt,Yt,q0,g):

2 beta = 0.5

3 gamma = 0.1

4

5 f0 = J(Xt,Yt,q0)

6 s = 1

7 q = q0+s∗g8

9 dd = −np.dot(g,g)10 while J(Xt,Yt,q)>f0 + s∗gamma∗dd:11 s=s∗beta12 q=q0+s∗g13 return s

Schließlich kann das Problem mit folgendem Hauptprogramm umgesetzt werden. Hier be-rechnen wir noch zu gegebenen Parametern q ∈ R2 Testdaten, zu N zufälligen Punkten xi ∈[0, 10]. Die Daten yi selbst sind auch zufällig gestört.

Algorithmus 8.7: Least-Square IV: Hauptprogramm1 # Erzeugt N Testdaten zu vorgegebenen Parametern q

2 # Die Daten sind zufaellig gestoert

3 def testdaten(q,sigma,N):

4 T = np.random.random(N)∗10 # N Zufallszahlen zwischen 0 und 10

5 Z = f(T,q)∗(1.0+np.random.randn(N)∗sigma)6 return [T,Z]

7

8 # Hauptprogramm.

9 [Xt,Yt] = testdaten(np.array( [1.0,0.5] ),0.1,100)

10 q = gradientenverfahren(np.array( [1.0,1.0] ),Xt,Yt,1.e−4)11

12 # Ausgabe der Ergebnisse

13 plt.plot(Xt,Yt,’∗’)14 T = np.linspace(0,10,100)

15 plt.plot(T,f(T,q))

16 plt.show()

180 ©2018 Thomas Richter

Page 187: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

10 20 30 40

50

60

70

80

km/h

dB

10 20 30 40

50

60

70

80

km/h

dBAbbildung 8.2.: Klassifikation von Verkehrsteilnehmern in Autos (rote Kreuze) und Fahrräder

(grüne Kreise). Rechts: Die Datenmenge kann durch eine einfache Linie un-terteilt werden. {fig:autos}

8.3.3. Klassifikation

Geschlossene analytische Modelle wie das Zerfallsgesetz

f(t; q) = q0 exp(− q1t

),

oder ein Modell für die Auslenkung eines Federpendels

f(t; q) = q0 sin(q2t)+ q1 cos

(q2t)

sind vor allem für grundlegende physikalische oder chemische Prozesse bekannt. Oft ist dasgenaue Modell, oder die Anzahl und Rolle der Parameter q ∈ Q jedoch unklar.

Wir betrachten ein einfaches Beispiel: an einer Straße beobachten wir die Geschwindigkeit vund den Lärm L, den ein Fahrzeug macht. Hieraus wollen wir schließen, ob es sich um einAuto oder um Fahrrad handelt. Wir gehen davon aus, das es nur diese beiden Typen von Ver-kehrsmitteln an der Straße gibt. Um hierfür ein Modell zu erstellen, z.B.

f(xv, xL) =

{1 v ist Auto0 v ist Fahrrad

beobachten wir zunächst für eine Weile den Verkehr, messen für N Fahrzeuge jeweils Ge-schwindigkeit und erzeugten Lärm und notieren, um welches Fahrzeug es sich handelt, d.h.(vi,Li, fi) für i = 1, . . . ,N. Wir zeigen mögliche Werte und deren Einordnung in Autos undFahrräder in Abbildung 8.2.

Unser Ziel ist es, dieMenge der Punkte durch eine einfache Vorschrift in die Autos und Fahrrä-der zuunterlegen, im einfachsten Fall durch eine Linie (im allgemeinen Fall vonn-dimensionalenDaten eine n− 1-dimensionale Hyperebene), wie sie rechts in der Abbildung dargestellt ist.

[email protected] 181

Page 188: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

−5 0 50

0.5

1 σ(s)

−5 0 50

0.1

0.2σ ′(s)

Abbildung 8.3.: Die Sigmoid-Funktion σ(s) = exp(s)(1 + exp(s)

)−1 als Approximation an dieHeaviside-Funktion und ihre Abbildung σ ′(s) (rechts).{fig:sigmoid}

Alle Werte oberhalb der Linie sind Autos, alle Werte unterhalb der Linie sind Fahrräder. Wirdenken direkt an den allgemeinen Fall mit d-dimensionalen Datenpunkten x ∈ Rd. Hier wol-len wir die Daten anhand einer Hyperebene, also einer d−1-dimensionalen Fläche charakteri-sieren. ImRd lässt sich eineHyperebene einfach durch einenNormalvektorw ∈ Rd und einenAufpunkt b ∈ Rd beschreiben. Für einen gegebenen Punkt x ∈ Rd gibt dann das Vorzeichenvon

s(x) = 〈x− b,w〉 = 〈x,w〉− 〈b,w〉

an, auf welcher Seite der Ebene sich der Datenpunkt x befindet. Zur Vereinfachung führen wirdie Größe

b = −〈b,w〉 ∈ R

ein, den sogenannten Bias. Um eine Hyperebene zu beschreiben sind also die n + 1 Wertew = (w1, . . . ,wn)undbnotwendig. Kennenwir diese, so steht unserModell zurKlassifikationvon Fahrzeugen in Autos und Fahrräder

f(x;b,w) = Θ(b+ 〈x,w〉), Θ(s) =

{1 falls s > 0

0 falls s < 0(8.12){ml:modell1}{ml:modell1}

wobei 1 für ein Auto und 0 für ein Fahrrad steht. Θ(s) wird Heaviside-Funktion genannt.

Andererseits können wir das allgemeine Modell (8.12) mit noch unbekannten Parametern b ∈R und w ∈ Rd nutzen, um im Rahmen der Parameteridentifikation zu gegebenen Daten dieWerte b und w zu bestimmen. Hierzu betrachten wir das Least-Squares Problem

J(b,w) =1

N

N∑i=1

1

2|fi − f(xi;b,w)|2, (8.13){ml:modell2}{ml:modell2}

wobei (xi, fi) für i = 1, . . . ,N die gegebenen Testdaten sind. Die Zielfunktion J ist jedochnicht differenzierbar, da die Heaviside-Funktion Θ nicht differenzierbar ist. Wir ersetzen dieHeaviside Funktion daher durch eine glatteApproximation, zumBeispiel die Sigmoid-Funktion

σ(s) =es

1 + es(8.14){ml:sigmoid}{ml:sigmoid}

welche in Abbildung 8.3 gezeigt wird.

Es gilt

182 ©2018 Thomas Richter

Page 189: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

−5 0 50

0.5

1

−5 0 50

0.5

1

−5 0 50

0.5

1

Abbildung 8.4.: Die Sigmoid-Funktionσ(s), verschobenσ(s−3)und skaliert sowie verschobenσ(5s+ 15) = σ

(5(s+ 3)

). {fig:sigmoid2}

{satz:sigmoid}

Satz 8.22 (Sigmoid-Funktion). Die Sigmoid-Funktion hat die Darstellungen

σ(s) =es

1 + es=

1

1 + e−s=

1

2

(1 + tanh

(s2

)).

Es giltσ(−s) = 1 − σ(s).

Die Ableitung hat die Darstellungen

σ ′(s) =es

(1 + e2)2= σ(s)σ(−s) = σ(s) (1 − σ(s))

und ihre Umkehrfunktion hat auf (0, 1) die Darstellung

σ−1(y) = ln

(y

1 − y

)

Beweis. Übung

Der Wechsel von 0 zu 1 kann in der Sigmoid-Funktion kann einfach verschoben werden, hier-für führen wir den Bias b ∈ R ein und betrachten σ(x + b). Ebenso kann die Steigung derSigmoid-Funktion durch Einführen eines Gewichtes ω ∈ R verändert werden σ(ωx + b). InAbbildung 8.4 zeigen wir die Auswirkung dieser beiden Parameter.

Hiermitmodifizierenwir die Zielfunktion (8.13) unterVerwendungder glatten Sigmoid-Funktionσ(s)

J(b,w) =1

N

N∑i=1

1

2|fi − f(xi;b,w)|2, f(x;b,w) = σ (b+ 〈w, x〉) . (8.15) {ml:modell3}{ml:modell3}

Zur Anwendung des Gradientenverfahrens müssen wir zunächst die Ableitungen der Ziel-funktion J(b,w) berechnen.

Satz 8.23. Es gilt∂J(b,w)

∂b= −

1

N

N∑i=1

(fi − f(xi;b,w))∂f(xi;b,w)

∂b

∂J(b,w)

∂wk= −

1

N

N∑i=1

(fi − f(xi;b,w))∂f(xi;b,w)

∂wk,

(8.16) {ml:modell4}{ml:modell4}

[email protected] 183

Page 190: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

mit∂f(x;b,w)

∂b= σ ′(b+ 〈w, x〉)

∂f(x;b,w)

∂wk= σ ′(b+ 〈w, x〉)xk

Beweis. Übung.

Zur Berechnung der Ableitung kann im Rahmen des Gradientenverfahrens auf den Zusam-menhang

σ ′(s) = σ(s) (1 − σ(s))

zurückgegriffen werden. In Python lassen sich Zielfunktion J(q) und Gradient ∇J(q) folgen-dermaßen einfach darstellen:

1 def sigmoid(x):

2 return np.exp(x)/(1+np.exp(x))

3

4 def Dsigmoid(x):

5 s = sigmoid(x)

6 return s∗(1−s)7

8 def J(T,q):

9 N = len(T) # Anzahl Daten

10 lin = q[0]+T[:,0:2]@q[1:3] # Linearkombination und Bias

11 return 0.5/N ∗ np.sum((T[:,2] − sigmoid(lin))∗∗2)12

13 def gradient_J(T,q):

14 N = len(T) # Anzahl Daten

15 lin = q[0]+T[:,0:2]@q[1:3] # Linearkombination und Bias

16 # Aussere Ableitung ∗ Dsigma17 g = −1/N∗(T[:,2]−sigmoid(lin))∗Dsigmoid(lin)18 grad = np.zeros(len(q)) # Innere Ableitung ...

19 grad[0] = np.sum(g) # ... nach Bias (konstant)

20 grad[1] = np.sum(g@T[:,0]) # ... nach Gewichten

21 grad[2] = np.sum(g@T[:,1]) # ... nach Gewichten

22 return grad

Wir gehen davon aus, dass T ein array der GrößeN× 3 ist und in jeder derN Zeilen die Werte(xi,yi, fi) speichert. Es ist also durch T[:,2] der Vektor f = (fi)i und durch T[:,0:2] der Vektorx = (xi,yi)i gegeben ist. Zur Berechnung derAbleitung der Sigmoid-Funktion verwendenwirSatz 8.22.

Wir nehmen an, dass wir keine nähere Kenntnis von dem Ergebnis haben und überlassendie Lösung des Parameteridentifikationsproblems dem Gradientenverfahren. Als Startwerte

184 ©2018 Thomas Richter

Page 191: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

1020

3040

50 4050

6070

8090

0

0.5

1

km/h dB

Abbildung 8.5.: Oben: die Datenpunkte und das mittels Gradientenverfahren identifizierteModell q ≈ (1.4723,−0.514, 1.817) (bezogen auf die bereinigten und in denMittelpunkt verschobenen Daten), d.h. wir zeigen f(x − xM, q) sowie (xi, fi).Unten: derKonvergenzverlauf desGradientenverfahrens.Wir zeigen denWertdes Zielfunktionals J(qi) über die Anzahl der Gradientenschritte in halb-logarithmischer Darstellung.{fig:ml1:results}

wählen wir einfach zufällige Werte für q = (b,w), z.B. mittels q = np.random.randn(3) drei nor-malverteilte Zufallszahlen.1 Ein Problem der Sigmoid-Funktion ist das sehr flache Auslaufenmit σ ′(s) ≈ 0 wenn |s|� 0 ist, so gilt

σ ′(5) ≈ 7 · 10−3 σ ′(10) ≈ 5 · 10−5, σ ′(20) ≈ 2 · 10−9.

Falls die Datenpunkte (xi, fi) so ungünstig liegen, dass |b+ 〈x,w〉|� 0 ist, so gilt näherungs-weise ∇J(q) ≈ 0 und das Gradientenverfahren wird nicht konvergieren. Daher ist es oft not-wendig, die Daten zunächst zu transformieren. Wir können die Daten z.B. in die Nähe des

1Dies ist ein Begriff aus der Stochastik. Zufallszahlen sind normalverteilt, oder auch Gauß-verteilt, wenn ihreWahr-scheinlichkeitsdichte die Gestalt ρ(s) = 1√

2πexp(− s2

2) besitzt. Grob gesprochen bedeutet dies: die Wahrschein-

lichkeit eine Zahl s ∈ [a,b] zu erreichen entspricht dem Wert des Integrals∫baρ(s)ds. Mehr hierzu in der

Drittsemestervorlesung zur Stochastik.

[email protected] 185

Page 192: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Mittelpunktes verschieben

xavg :=1

N

N∑i=1

xi, xi := xi − xavg.

Weiter könnte man die Datenpunkte skalieren, so dass alle Werte in einem festen Intervall umden Nullpunkt liegen. In Abbildung 8.5 zeigen wir das Ergebnis der Parameterschätzung. Ingut 3500 Schritten konnte das Zielfunktional J(q) von J(q0) ≈ 0.43 auf J(q3543) ≈ 0.000033 re-duziert werden. In der Abbildung zeigenwir einerseits den Verlauf des Gradientenverfahrens,also den Wert des Zielfunktionals J(q) über die Anzahl der Schritte in halb-logarithmischerDarstellung. Weiter zeigen wir das resultierende Modell als Funktion. Im Ergebnis erhaltenwir

q = (b,w) ≈ (0.975,−0.640, 2.227),

also das Modellf(x) ≈ σ

(0.975 − 0.64(x− xavg) + 2.227(y− yavg)

),

mit dem Mittelwert der Datenpunkte

xavg ≈ (22.64, 60.57).

8.3.4. Künstliche neuronale Netze

Das letzte Beispiel markiert die Schwelle zwischen klassischer modellbasierter Parameteridenti-fikation und dem maschinellen Lernen. Wir haben aufbauend auf der sehr groben Idee Autossind schneller und lauter als Fahrräder ein sehr einfaches Modell entwickelt. Wir können diesenAnsatz aber auch unter anderer Perspektive betrachten: wir verwenden ein universelles Modell,welches basierend auf n ∈ N Eingabe-Größen x1, . . . , xn die Antwort 0 oder 1 liefert, beschrie-ben durch

N(w,b; x) := Θ( n∑j=1

wjxj + b),

wobei Θ die Heaviside-Funktion ist und mit Gewichten w = (wj)j ∈ Rn und dem Bias b ∈R. Wie beschrieben kann durch Approximation der Heaviside-Funktion durch die Sigmoid-Funktion ein differenzierbares Modell erreicht werden. Wir nennen dieses ZuammenhangN(w,b; x) ein künstliches Neuron und stellen es graphisch dar in Abbildung 8.6

Diese Art der Modellierung ist nicht neu, entsprechende Mechanismen wurden bereits 1943diskutiert. Das Grundprinzip eines künstlichen Neurons ist das Trennen des X := Rn durchdie Hyperebene 〈x,w〉 − b = 0. Liegt x ∈ X auf der einen Seite der Ebene mit 〈x,w〉 − b > 0,so feuert das künstliche Neuron und liefert das Ergebnis 1. Ansonsten liefert es 0. Es ist klar,dass durch ein einzelnes künstliches Neuron nur eine sehr geringe Vielzahl von Aufgabenbeschrieben werden kann. Einfache Beispiele sind die logischen Verknüpfungen or, and, not.Ordnen wir demWert False die Zahl 0 und demWert True den Wert 1 zu, so erreichen wir dieNegation not durch ein künstliches Neuron mit einer Eingabe

Nnot(x) = Θ(−1 · x+ 1

2),

186 ©2018 Thomas Richter

Page 193: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

w, b N(w, b;x)

x2

x3

x1

xn

Abbildung 8.6.: Ein künstliches Neuron mit n Eingaben und einer Ausgabe. In Abhängigkeitvon den Parameter w ∈ Rn und b ∈ R liefert es für ein x ∈ Rn die AussgabeN(w,b; x) := σ(wTx−b), oder, in der nicht-glatten FormN(w,b; x) := Θ(wTx−b){fig:knn1}

N1

x1

x4

x2

x3 f2

f1

N2

Abbildung 8.7.: Ein künstliches neuronales Netz mit 4 Eingaben x ∈ R4 und 2 Ausgaben. Diebeiden Neuronen Ni sind jeweils durch den Bias bi ∈ R sowie die Gewichtewi ∈ R4 bestimmt. {fig:knn2}

die Konjunktion ist ein künstliches Neuron mit zwei Eingaben

Nand(x) = Θ(x1 + x2 −3

2),

und die Disjunktion ist gegeben durch

Nor(x) = Θ(x1 + x2 −1

2).

Wir verfolgen hier aber einen anderen Ansatz und nehmen künstliche Neuronen als zunächstgenerische Bestandteile eines komplexeren Modells, welches erst bei Identifikation der kor-rekten Parameter w und b seine Aufgabe erfüllt. In der Theorie der neuronalen Netze verknüpftman nunmehrere künstlicheNeuronen zu einemGesamtkonstrukt. Angenommenwir sucheneinen funktionellen Zusammenhang mit n Eingabegrößen x ∈ Rn und m Ausgaben {0, 1}m.Dann verbinden wir im einfachsten Fall die n Eingaben, den sogenannten Input-Layer mit mkünstlichen Neuronen der sogennanten Ausgabe-Schicht oder dem Output-Layer, siehe Abbil-dung 8.7.

Jedes der m künstlichen Neuronen N1, . . . ,Nm ist parametrisiert durch Bias b(i) ∈ R undGewichten w(i) ∈ Rn. Das Gesamtmodell ist beschrieben durch

fi(w(i),b(i); x) = σ(〈w(i), x〉+ b(i)), i = 1, . . . ,m

[email protected] 187

Page 194: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Zur Vereinfachung der Schreibweise wollen wir die gesamte Schicht aus künstlichen Neuro-nen als einen Vektor schreiben und definieren für ein z = (zi)i ∈ Rm

σ(z)i = σ(zi),

also als die komponentenweise Auswertung der Sigmoid-Funktion. Hiermit können wir dasModell kompakt schreiben als

f(W, b; x) = σ(Wx+ b),

mit einer Matrix W ∈ Rm×n und dem Vektor b ∈ Rm

W =

w

(1)1 w

(1)2 · · · w

(1)n

w(2)1 w

(2)2

. . . w(2)n

... . . . . . . ...w

(m)1 w

(m)2 · · · w

(m)n

, b =

b(1)

b(2)

...b(m)

Wir werden im folgenden kurz W = (wij)ij und b = bi für i = 1, . . . ,m und j = 1, . . . ,nschreiben. Sind die Parameter W ∈ Rm×n und b ∈ Rm bekannt, so kann das künstlicheneuronale Netz für einen Eingabevektor x ∈ Rn einfach ausgewertet werden

1 def sigmoid(x):

2 return 1.0/(1.0+np.exp(−x))3

4 def knn(W,b,x):

5 return sigmoid(W@x+b)

Es gilt{satz:knn:grad1}

Satz 8.24 (Gradient des einschichtigen neuronalen Netzes). Sei W ∈ Rm×n, b ∈ Rm. Für denfunktionalen Zusammenhang

f(W,b; x) = σ(Wx+ b)

gilt:∇bf(W,b; x) = σ ′(Wx+ b)

∇Wf(W,b; x) = σ ′(Wx+ b)xT,

wobei für z = (zi)i ∈ Rm jeweils die Notation

σ ′(z) = σ ′(zi)

verwendet wird und die Gradienten Funktionen im Sinne

∇bf : (Rm×n ×Rm)×Rn → Rm, ∇Wf : (Rm×n ×Rm)×Rn → Rm×n

sind.

Beweis. Wir berechnen exemplarisch für die RichtungW alle partiellen Ableitungen für i,k =1, . . . ,m und l = 1, . . . ,n

∂Wklfi(W,b; x) =

∂Wklσ([Wx+ b]i

)=

∂Wklσ( n∑j=1

Wijxj + bi)

188 ©2018 Thomas Richter

Page 195: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Nur für k = i gibt es einen Beitrag und auch dann bleibt in der Summe nur der Eintrag xjbestehen, d.h.:

∂Wklfi(W, b; x) = δkiσ

(Wx+ b

)ixj.

Es handelt sich bei der Ableitung eigentlich um einen Tensor dritter Stufe (mit drei Indizesi,k, l) wir lassen die Terme für i 6= k jedoch unmittelbar weg und ordnen die verbleibendenAbleitungen in einer Matrix an

∂f

∂W=

σ ′(Wx+ b)1x1 σ ′(Wx+ b)1x2 · · · σ ′(Wx+ b)1xn

σ ′(Wx+ b)2x1. . . . . . ...

... . . . . . . ...σ ′(Wx+ b)mx1 σ ′(Wx+ b)mx2 · · · σ ′(Wx+ b)mxn

,

welches wir unter Ausnutzung des dyadischen Produkts (es folgt den Regeln der Matrix-MatrixMultiplikation) schreiben können als

∂f

∂W= σ ′

(Wx+ b

)xT .

Die Ableitungen in Richtung b können entsprechend ausgewertet werden.

Das Gradientenverfahren lässt sich wieder direkt zur Minimierung des Least-Squares Funk-tional für einen Satz aus N Daten

X ∈ RN×n, Y ∈ RN×m

anwenden. Dabei seiX = (xi)imit denNZeilenvektoren xi ∈ Rn und entsprechendY = (yi)imit den Ergebnissen yi ∈ Rm, jeweils für i = 1, . . . ,N. Wir betrachten das Funktional

J(W,b;X) =1

2Nm

N∑i=1

|f(W,b; xi) − yi|22,

bzw. wir definieren für die komplette Matrix der Testdaten die Formulierung

f(W,b;X) = σ(WXT + b), σ(WXT + b)ij := σ(〈wi, xj〉+ bi), i = 1, . . . ,N, j = 1, . . . ,m

und erhalten kurzJ(W,b;X) =

1

2Nm‖f(W,b;X) −Y‖2F, (8.17) {knn:JX}{knn:JX}

mit der Frobeniusnorm

A = (aij)ij ∈ Rm×n : ‖A‖F :=

m∑i=1

n∑j=1

|aij|2

12

.

Die Frobeniusnorm ist eine Matrixnorm, d.h. submultiplikativ ‖AB‖F 6 ‖A‖F‖B‖F, und sieist mit der euklidischen Norm verträglich, d.h. ‖Ax‖2 6 ‖A‖F‖x‖2. Sie ist jedoch von keinerVektornorm induziert. Dies sieht man z.B. an ‖I‖F =

√n für die n× n Einheitsmatrix I. Siehe

auch Kapitel 6.1 (für induzierte Normen muss immer ‖I‖ = 1 gelten).

[email protected] 189

Page 196: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Aufbauend auf Satz 8.24 können wir die Gradienten von J(·) in der folgenden Form schreiben:

∇bJ(W, b;X) =1

Nm

N∑i=1

(f(W,b; xi) − yi) ∗ ∇bf(W,b; xi)

∇WJ(W, b;X) =1

Nm

N∑i=1

(f(W,b; xi) − yi) ∗ ∇Wf(W, b; xi),

wobei wir für den Vektor z := f(W,b; xi) − yi ∈ Rm und den Vektor q := ∇bf(W,b; xi) ∈ Rmund die Matrix A := ∇Wf(W,b; xi) ∈ Rm×n die Notation

z ∗ q =

z1q1z2q2...

zmqm

, z ∗A =

z1A11 z1A12 · · · z1A1n

z2A21 z2A22 · · · z2A2n... . . . . . . ...

zmAm1 zmAm2 · · · zmAmn

(8.18){knn:produkt}{knn:produkt}

verwenden.1 def J(X,Y,W,b):

2 s = sigmoid([email protected](X)+b) − np.transpose(Y)

3 return 0.5/len(T)∗np.sum(s∗s)4

5 def gradJ(X,Y,W,b):

6 lin = [email protected](X)+b

7 IN = (sigmoid(lin)−np.transpose(Y))∗Dsigmoid(lin)8 Gb = np.sum(IN,1).reshape(len(b),1)

9 GW = IN@X

10 return [Gb,GW]

Das bisher betrachtete und inAbbildung 8.7 visualisierte neuronaleNetz hat nebendesEingabe-Layers nur eine weitere Stufe, die direkt derAusgabe-Layer ist. Die volle Leistungsfähigkeit ent-falten künstliche Neuronale Netze erst bei Verschachtelung mehrerer Stufen.

Wir zeigen inAbbildung 8.8 ein solchesmehrschichtiges künstlichesNeuronales Netz.Wir ha-ben einen Eingabe-Layermit 2 Eingaben. Es folgt eine Schicht mit 2 künstlichen Neuronen, eineSchicht mit 3 Neuronen und schließlich eine Ausgabeschicht mit einem künstlichen Neuron.Die mittleren beiden Schichten werden Hidden-Layer, also Verborgene Schicht genannt, da sievon Außen nicht als Eingabe oder Ausgabe zu erkennen sind. Je nach Sprechweise bezeichnetman künstliche Netzwerke mit einemHidden-Layer als deep neural networks, das entsprechendeAntrainieren als Deep Learning. Andere Definitionen setzen eine große Anzahl von verborge-nen Schichten voraus, um das Prädikat deep zu rechtfertigen.

Wir präzisieren die Notation: das gesamte Netz kann als ein Funktionaler Zusammenhang f :R2 → {0, 1}, bzw. mit der glatten Sigmoid-Funktion als Approximation f : R2 → R verstandenwerden. Die drei Schichten beschreiben wir funktionell als

N(k) : Ri(k) → Ro

(k),

mit jeweils i(1) = 2, i(2) = 2 und i(3) = 3 Eingaben und o(1) = 3, o(2) = 2 und o(3) = 1Ausgaben. Jede Schicht hat dann die Gestalt

N(k) = σ(W(k)x(k−1) + b(k)

)

190 ©2018 Thomas Richter

Page 197: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

f1

x1

x2

N(1)2

N(1)1

N(2)1

N(2)2

N(2)3

N(3)1

Abbildung 8.8.: Künstliches neuronales Netz mit einer Eingabeschicht (2 Eingaben), 2 Verbor-genen Schichten und einer Ausgabeschicht (eine Ausgabe).{fig:knn3}

mit den ParameternW(k) ∈ Ro(k)×i(k) , b(k) ∈ Ro(k)

.

Insgesamt schreiben wir also das Netz in der Form

f : R2 → R, f = N(3) ◦N(2) ◦N(1),

oder konkret als

f(x) = σ(W(3)σ

(W(2)σ

(W(1)x+ b(1)

)+ b(2)

)+ b(3)

). (8.19) {knn3:1}{knn3:1}

Wir fassen die Gewichte zusammen als W = (W(1),W(2),W(3)) und die Bias-Vektoren alsb = (b(1),b(2),b(3)).

Prinzipiell läuft das TrainierendesNetzeswie gehabt. Zu gegebenenTestdaten (X, Y) = (xi, yi)ifür i = 1, . . . ,N} und mit xi ∈ R2 und yi ∈ {0, 1}minimieren wir das Funktional

J(W, b; X, Y) :=1

4N‖f(W, b; X) − Y‖2F.

Das Auswerten des Funktionals J und die Berechnung der Ableitung sind entsprechend auf-wändiger.

Bemerkung 8.25 (Netzwerk-Architektur: feedforward). Das bisher vorgestellte Netzwerk ist ein so-genanntes feedforward-Netz. Jede Schicht hängt direkt und nur von der vorherigen Schicht ab. DieAuswertung eines künstlichen neuronalen feedforward-Netzes erfolgt nach dem folgenden Schema:

{algo:knn}Algorithmus 8.8: Auswerten eines feedforward-Netzes

1 # gegeben Netz W=[W1,W2,...,WL] b=[b1,b2,...,bL] mit L Schichten

2

3 def feedforward(W,b,x): # Auswerten des Netzes

4 L = len(W)

5 for k in range(len(L)):

6 x = sigmoid(W[k]@x+b[k])

7 return x

Diese Funktion kann auch auf einen gesamten Satz von Testdaten X angewendet werden.

[email protected] 191

Page 198: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Berechnung des Gradienten Wir betrachten nun ein feedforward-Netz N = (W,b)mit L Schichten, welches gemäß 8.19 dargestellt werden kann und insgesamt den Zusammen-hang

f : Ri(1) → Ro

(L)

beschreibt. Gegeben seien weiter Datenpunkte (X, Y) = (xi, yi) für i = 1, . . . ,N. Wir suchenein Minimum des Least-Squares Funktional

J(N) :=1

2No(L)

N∑j=1

‖f(N; xj) − yj‖2. (8.20){knn3:LS}{knn3:LS}

Zur Anwendung des Gradientenverfahrens benötigen wir die Ableitung in Richtung der Pa-rameter W = (W(1), . . . ,W(L)) und b = (b(1), . . . ,b(L)). Wir berechnen zunächst die äußereAbleitung als

∇NJ(N) =1

No(L)

N∑j=1

⟨f(N; xj) − yj,∇Nf(N; xj)

⟩. (8.21){knn:grad:aussen}{knn:grad:aussen}

Das Argument f(N; xj)− yj ∈ Ro(L) ist ein Vektor, der Gradient∇Nf(N; xj)muss als koponen-

tenweise Berechnung des Gradienten verstanden werden, d.h.:

f : Ri(1) → Ro

(L): ∇Nf(N; xj) =

∇Nf1(N; xj)∇Nf2(N; xj)

...∇Nfo(L)(N; xj)

,

jeder Eintrag ist entweder einVektor∇b(k)fi ∈ Ro(k) oder aber eineMatrix∇W(k)fi ∈ Ro

(k)×i(k) ,je nachdem, ob wir die Ableitung in Richtung eines Bias b(1), . . . ,b(L) oder in Richtung einerGewichtsmatrix W(1), . . . ,W(L) berechnen. Damit ist (8.21) zu verstehen als

∇b(k)J(N) =1

No(L)

N∑j=1

o(k)∑i=1

(fi(N; xj) − [yj]i

)∇b(k)fi(N; xj) ∈ Ro

(k)

∇W(k)J(N) =1

No(L)

N∑j=1

o(k)∑i=1

(fi(N; xj) − [yj]i

)∇W(k)fi(N; xj) ∈ Ro

(k)×i(k) .

(8.22){knn:g0}{knn:g0}

Es folgt nun die Berechnung der inneren Ableitungen ∇Nfi(N; xj). Für das Folgende wählenwir für einen festen Datenpunkt xj die Bezeichung

x(0) := xj, x(k) := σ(W(k)x(k−1) + b(k)

)k = 1, . . . ,L, (8.23){knn3:defxt}{knn3:defxt}

so dass x(L) = f(N; xj) gilt. Wir beginnen mit dem Bias. Für die r-te Komponente gilt

∂fi(N; xj)

∂b(k)r

=∂x

(L)i

∂b(k)r

=

o(k)∑t=1

∂x(L)i

∂x(k)t

∂x(k)t

∂b(k)r

, (8.24){knn:g6}{knn:g6}

192 ©2018 Thomas Richter

Page 199: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

d.h., der Gradient setzt sich aus zwei Teilen zusammen, der Ableitung von x(k) nach b(k),wie bereits in Satz 8.24 berechnet und der Ableitung der L-ten Ausgabeschicht nach der k-tenAusgabe. Hier gilt komponentenweise

∂x(L)i

∂x(k)t

=

ok+1∑s=1

∂x(L)i

∂x(k+1)s

∂x(k+1)s

∂x(k)t

(8.25){knn:g7}{knn:g7}

mit der inneren Ableitung

∂x(k+1)s

x(k)t

=∂

∂x(k)t

σ([W(k+1)x(k) + b(k+1)]s

)= σ ′

([W(k+1)x(k) + b(k+1)]s

)W

(k+1)st .

Wir führen entsprechend zu (8.23) die folgende weitere Notation ein

y(k) := σ ′(W(k)x(k−1) + b(k)

)∈ Ro(k)

Z(k) := y(k) ∗W(k) ∈ Ro(k)×i(k) = Ro(k)×o(k−1)

(8.26) {knn3:defyt}{knn3:defyt}

entsprechend zur Definition (8.18). Mehrfache Anwendung der Kettenregel in (8.25) liefert

∂x(L)i

∂x(k)t

= [Z(L)Z(L−1) · · ·Z(k+1)]it =: ZL,k+1it ∈ Ro(L)×o(k)

.

Den zweiten Faktor in (8.24) berechnen entsprechend als

∂x(k)t

∂b(k)r

=∂

∂b(k)r

σ([W(k)x(k−1) + b(k)]t

)= σ ′

([W(k)x(k−1) + b(k)]t

)︸ ︷︷ ︸=y

(k)t

δtr

und erhalten nur für t = r einen Beitrag. Somit verkürzt sich die Summe in (8.24) und wirerhalten

∂fi(N; xj)

∂b(k)r

=

o(k)∑t=1

∂x(L)i

∂x(k)t

∂x(k)t

∂b(k)r

= Z(L,k+1)ir y

(k)r . (8.27) {knn:g8.5}{knn:g8.5}

Der Gradient in Richtung der Gewichte kann ähnlich berechnet werden, es ändert sich nur dieinnere Ableitung

∂x(k)t

∂W(k)rs

=∂

∂W(k)rs

σ([W(k)x(k−1) + b(k)]t

)= σ ′

([W(k)x(k−1) + b(k)]t

)︸ ︷︷ ︸=y

(k)t

x(k−1)s δtr

und wir erhalten für t = r

∂fi(N; xj)

∂W(k)rs

=

o(k)∑t=1

∂x(L)i

∂x(k)t

∂x(k)t

∂W(k)rs

= Z(L,k+1)ir y

(k)r x

(k−1)s (8.28) {knn:g9}{knn:g9}

Mit diesen beiden Ergebnissen, (8.27) und (8.28), gehen wir in (8.22) und fassen zusammen

∇b(k)rJ(N) =

1

No(L)

N∑j=1

o(k)∑i=1

(fi(N; xj) − [yj]i

)Z(L,k+1)j,ir y

(k)j,r

∇W

(k)rsJ(N) =

1

No(L)

N∑j=1

o(k)∑i=1

(fi(N; xj) − [yj]i

)Z(L,k+1)j,ir y

(k)j,r [xj]

(k−1)s .

[email protected] 193

Page 200: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Wir haben nun wieder den Index j für die Indizierung der Testdaten hinzugefügt. Die innereSumme über i kann in Form einer Matrix-Vektor Multiplikation mit der Transponierten vonZ(k+1) geschrieben werden

o(k)∑i=1

(fi(N; xj) − [yj]i

)Z(L,k+1)j,ir =

[Z(L,k+1),Tj

(f(N; xj) − yj

)]r

und wir erhalten für die Gradienten von J(N) in Richtung der Bias-Vektoren und Gewichts-Matrizen die Darstellung

∇b(k)J(N) =1

No(L)

N∑j=1

[Z(L,k+1),Tj

(f(N; xj) − yj

)]∗ y(k)j

∇W(k)J(N) =1

No(L)

N∑j=1

[Z(L,k+1),Tj

(f(N; xj) − yj

)]∗([x

(k−1)j ]Ty

(k)j

).

(8.29){knn:g10}{knn:g10}

Wir fassen die aufwändige Herleitung zusammen.

Satz 8.26 (Gadientenberechnung). Es seiN ein künstliches neuronales feedforwardNetzmitL Schich-ten, (X, Y) ein Satz aus N ∈ N Testdaten. Es sei

x(0)j := xj, x

(k)j := σ

(W(k)x

(k−1)j + b(k)

)für k = 1, . . . ,L, f(N; xj) := x

(L)j , (8.30){knn3:bg1}{knn3:bg1}

sowiey(k)j := σ ′

(W(k)x

(k−1)j + b(k)

)für k = 1, . . . ,L (8.31){knn3:bg2}{knn3:bg2}

undZ(k)j := y

(k)j ∗W(k) für k = 1, . . . ,L (8.32){knn3:bg3}{knn3:bg3}

sowie schließlichZ(L,k)j := Z

(L)j Z

(L−1)j · · ·Z(k)

j für k = 1, . . . ,L. (8.33){knn3:bg4}{knn3:bg4}

Dann sind die Gradienten von J(N, X, Y) bei k = 1, . . . ,L gegeben als

∇b(k)J(N) =1

No(L)

N∑j=1

[Z(L,k+1),Tj

(f(N; xj) − yj

)]∗ y(k)j

∇W(k)J(N) =1

No(L)

N∑j=1

[Z(L,k+1),Tj

(f(N; xj) − yj

)]∗([x

(k−1)j ]Ty

(k)j

).

(8.34){knn3:bg5}{knn3:bg5}

Bemerkung 8.27 (Backpropagation). DieseMethode zur Berechnung des Gradientenwird backpro-pagation genannt. Um die Ableitung zu berechnen müssen Hilfsgrößen (8.33), die Matrizen Z

(L,k+1)j

von der hinteren Schicht L bis hin zur aktuellen Schicht k = 1 berechnet werden. Die Hilfsvekto-ren (8.31) können bereits im Laufe der Vorwärtsauswertung des Netzes bestimmt werden.

194 ©2018 Thomas Richter

Page 201: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

{algo:knn3}

Algorithmus 8.9: Auswertung eine Netzes und des Gradienten1 ### Testdaten TX,TY, # Feld der Groesse n ∗ N bzw. m ∗ N2

3 ### Parameter W,b des L−schichtigen Netzes, W[k] Matrizen , b[k] Vektoren4

5 ### Berechnet Least−Squares Funktional6 # Eingabe: Netz W,b, Ausgabe Netz F und Test−Ergebnis TY7 def J(W,b,F,TY):

8 return 0.5/TY.shape[0]/TY.shape[1]∗np.sum((F−TY)∗(F−TY))9

10 ### Berechnet Netz−Ausgabe und bereitet Gradienten vor11 # Eingabe: Netz und Daten. Ausgabe: Ergebnis und Hilfsgroessen

12 def feedforward(W,b,X):

13 L = len(W)

14 y = [[]]∗L # Hilfsvektoren fuer Gradientenberechnung

15 x = [[]]∗(L+1) # Hilfsvektoren fuer Gradientenberechnung

16 x[0] = X

17 for k in range(L):

18 x[k+1] = sigmoid(W[k]@x[k]+b[k])

19 y[k] = x[k+1]∗(1.0−x[k+1]) # ableitung

20 return [x[L],x,y]

21

22 ### Gradient der Zielfunktion

23 # Eingabe: Netz sowie Hilfsgroessen. Ausgabe: Gradienten

24 def gradientJ(W,b,F,TX,TY,x,y):

25 L = len(W) # Anzahl der Schichten

26 gW = [[]]∗L27 gb = [[]]∗L28 for k in range(L):

29 gW[k] = np.zeros( (W[k].shape[0],W[k].shape[1]) )

30 gb[k] = np.zeros( (b[k].shape[0],b[k].shape[1]) )

31

32 res = F−TY # Residuum der Netz−Auswertung33

34 n = TY.shape[0] # Dimension der Netz−Ausgabe35 N = TY.shape[1] # Anzahl der Datenpunkte

36

37 for j in range(N): # ueber alle Daten laufen

38 Z = np.eye(n) # Hilfsmatrix initializieren als Einheitsmat.

39 for k in reversed(range(L)): # Netz rueckwarts durchlaufen

40 gb[k]=gb[k]+np.transpose(Z)@res[:,j:j+1]∗y[k][:,j:j+1]/n/N41 gW[k]=gW[k]+np.transpose(Z)@res[:,j:j+1]∗(np.transpose(x[k][:,j:j

↪→ +1])∗y[k][:,j:j+1])/n/N42 Z = Z@(y[k][:,j:j+1]∗W[k])43

44 return [gW,gb]

[email protected] 195

Page 202: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Abbildung 8.9.: Verlauf des Gradientenverfahrens in logarithmischer Darstellung. Relativ inBezug auf die den Startfehler zeigen wir den Verlauf des Funktionals J(q) so-wie den Gradienten∇J(q).{fig:knn3:verlauf}

Numerische Beispiel - Trainieren des Netzes Wir versuchen nun, das in Abbil-dung 8.8 gezeigte Netz zu trainieren. Wir wählen hierzu N = 100 zufällig gewählte Punktexi = (xxi , xyi ) (normalverteilt mit Standardabweichung 1 und Erwartungswert 1) und bestim-men das entsprechende Testergebnis als

yi =

{1 falls |xxi − 0.25|2 + |yyi |

2 6 0.52

0 falls |xxi − 0.25|2 + |yyi |2 < 0.52,

d.h. wir identifizieren alle Punkte innerhalb des Kreises um den Punkt (0.25, 0) mit Radius0.5. Wir lassen das Gradientenverfahren mit zufälligen Startwerten für Gewichte W und Biasb laufen, bis der Gradient des Zielfunktionals einen Schwellenwert unterschreitet

|∇J(q)| < 10−8.

In Abbildung 8.9 zeigenwir denVerlauf des Gradientenverfahrens und zeichnen das Zielfunk-tional und den Gradienten gegenüber der Anzahl der Iterationen.

Zu Beginn des Verfahrens, d.h. bei zufällige gewählten Parametern werden fälschlicherweisealle Punkte in die Kategorie 0, d.h. ausßerhalb des Kreises bestimmt. 15 Punkte, die eigentlichinnerhalb des Kreises liegen werden fehlerhaft klassifiziert. Das Gradientenverfahren benötigt40 164 Schritte, um das Zielresiduum (im Gradienten) zu erreichen und im Ergebnis wird nunnur noch 1 Punkt fehlerhaft klassifiziert. Die Armijo-Schrittweitenregel erzwingt monotoneKonvergenz im Zielfunktional J(q). Die Gradientennorm, d.h. die Suche nach einem statio-nären Punkt konvergiert jedoch nicht monoton.

In Abbildung 8.10 zeigen wir die Klassifizierung des Netzes vor und nach dem Gradienten-verfahren. Das künstliche neuronale Netz liefert aufgrund der Sigmoid-Funktion Ergebnisse

196 ©2018 Thomas Richter

Page 203: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Abbildung 8.10.: Klassifikation vor (links) und (nach) Trainieren des Netzes. Nach Trainierenwerden 99% der Testdaten korrekt klassifiziert.{fig:knn3:vornach}

im Intervall (0, 1). Wir ordnen diese den binären Werten {0, 1} nach der folgenden Vorschriftzu:

f(W, b; xi) > 0.5 ⇒ f(xi) = 1, f(xi) = 0 sonst.

Es werden nun 99 Prozent der Punkte korrekt klassifiziert.

Dieses Beispiel zeigt jedoch auch gleiche eine Schwäche von neuronalen Netzen als allgemei-nes Modell. Wir haben in - sehr vielen - Gradientenschritten erreicht, dass das Netz unsereTestdaten imwesentlichen, also zu 99%, korrekt klassifiziert. Wir haben in unserem Verfahrenbeim Trainieren nirgends die Kenntnis ausgenutzt, das wir eigentlich versuchen einen Kreiszu identifizieren.

In derAnwendungwürdenwir das nun trainierteNetz als funktionellenZusammenhang auchfür weitere Daten nutzen, d.h. zur Vorhersage von Ergebnissen für andere Daten verwenden.In Abbildung 8.11 zeigen wir die Ergebnise für zwei weitere Datensätze aus N = 100 undN = 200 Testdaten. Der Erfolg ist ernüchternd, die korrekte Klassifikation beträgt lediglich87% bzw. 86%. Das Netz ist sehr gut einen speziellen Datensatz trainiert, nicht aber zur Erfül-lung der allgemeinen Aufgabe, die wir jedoch auch nicht in nicht beim Trainieren verwendethaben. Wir stellen schließlich in Abbildung 8.12 noch das Netz als Funktion über gleichmäßigverteilte Punkte in der x/y Ebene dar. Hier zeigt sich, dass unser Netz wirklich nicht einenKreis darstellt.

[email protected] 197

Page 204: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Abbildung 8.11.: Anwenden des trainierten Netzes auf zwei weitere Datensätze mit N = 100und N = 200 Punkten. Es werden nur 87% bzw. 86% der Punkte korrektklassifiziert. {fig:knn3:andere}

Abbildung 8.12.: Plot der Funktion f(W, b; x). {fig:knn3:funktion}

198 ©2018 Thomas Richter

Page 205: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

N(2)2

x1

x2

N(3)1 f1

N(1)1

N(1)2

N(1)3

N(1)4

N(2)1

Abbildung 8.13.: Künstliches neuronales Netz mit einer Eingabeschicht (2 Eingaben), 2Verbor-genen Schichten und einer Ausgabeschicht (eine Ausgabe). {fig:knn4}

Wahl des Netzes Das Test-Netzwerk aus Abbildung 8.8 habenwir ohne tieferen Sinn ge-wählt. Wir versuchen nun, die Aufgabe mit einemmodifizierten Netzwerk, in Abbildung 8.13gezeigt, zu lösen. Die naive Idee ist hier: jedes der vier künstlichen Neuronen in der erstenSchicht legt eine Hyperebene an die Kugel und stellt so eine erste Approximation an den Kreisim Sinne eines Quadrats dar. Die weiteren Schichten erledigen das weitere. Auch wenn dieseSichtweise aller Voraussicht nach nicht durch das Trainieren realisiert wird, so versichert sieuns immerhin, dass das Netz prinzipiell zu einer groben Erfassung der Geometrie geeignetist.

In der Tat zeigt Abbildung 8.14, dass die Fehlerquote von 17% bei den gewählten Testdaten auf0% reduziert werden konnte. Alle Punkte werden korrekt identifiziert. In dieser Abbildungzeigen wir auch die Ergebnisse für zwei weitere Testdatensätze von N = 100 und N = 200Punkten.

Das Gradientenverfahren verläuft bei diesem Netz schneller und die Toleranz 10−8 konntenach 17 514 Schritten erreicht werden. Wir zeigen in Abbildung 8.15 einerseits den Konver-genzverlauf, dann auch die Ausgabes des trainierten Netzes als Funktion f(W,b; x) in derEbene.

Rolle der Testdaten Das Trainieren des künstlichen Netzes erlernt aus den Testdateneinen Zusammenhang. Dieser soll später auch auf anderen Daten eine Vorhersagekraft entwi-ckeln. Es ist somit zu klar, dass dieWahl von größerenDatensätzen dieQualität der Vorhersagestärkt. Selbstwenn eineNetzwerkarchitektur prinzipiell sehr gut geeignet ist um einenZusam-menhang darzustellen, so müssen die Testdaten hinreichend umfangreich sein. Wir trainierendas Netz nun mit Sätzen aus N = 250 und N = 500 Punkten, die jeweils konzentrierter amzu identifizierenden Kreis liegen und stellen die Funktion f(W,b; x) über der x/y-Ebene fürbeide Datensätze dar. In Abbildung 8.16 zeigen wir das jeweilige Ergebnis.

[email protected] 199

Page 206: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Abbildung 8.14.: Oben: Klassifikation vor (links) und (nach) Trainieren des Netzes. Es könnenalle Datenpunkte des Testdatensatzes korrekt klassifiziert werden.Unten: Anwendung desNetzes auf zweiweitere DatensätzemitN = 100 undN = 200 Punkten. Hier können 96% (links), bzw. 94.5% (rechts) der Punktekorrekt klassifiziert werden. {fig:knn4:vornach}

200 ©2018 Thomas Richter

Page 207: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

8.3. Parameteridentifikation

Abbildung 8.15.: Links: Verlauf des Gradientenverfahrens. Rechts: Trainiertes Netz als Funk-tion in der Ebene. {fig:knn4:verlauf}

Abbildung 8.16.: Training mit N = 250 Datenpunkten (links) und N = 500 Datenpunkten(rechts). Jeweils Angabe der Funktion f(W,b; x) zu den gelernten Parame-tern. {fig:knn4:viele}

[email protected] 201

Page 208: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude
Page 209: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Bibliography

[1] U. Becciani et al. “Solving a very large-scale sparse linear system with a parallel algo-rithm in the Gaia mission”. In: 2014 International Conference on High Performance Compu-ting Simulation (HPCS). 2014, pp. 104–111. doi: 10.1109/HPCSim.2014.6903675.

[2] R. Diestel.Graphentheorie. 5. Auflage. http://diestel-graph-theory.com/german/. Sprin-ger Spectrum, 2017.

[3] G. Fischer. Lineare Algebra. Vieweg + Teubner, 2010.[4] P. Gries, J. Campbell, and J. Montojo. Practical Programming. An Introduction to Computer

ScienceUsing Python 3. Ed. by L. Beighley. 2nd edition. The Pragmatic Programmers. Dal-las, Texas. Raleigh, North Carolina: Pragmatic Bookshelf, 2013. url: http://pragprog.com.

[5] S. Hougardy and J. Vygen. Algorithmische Mathematik. 2. Auflage. Springer Spektrum,2018.

[6] MarkusHuber et al. “Resilience forMassively Parallel Multigrid Solvers”. In: SIAM Jour-nal on Scientific Computing 38.5 (2016), S217–S239. doi: 10 . 1137 / 15M1026122. eprint:http://dx.doi.org/10.1137/15M1026122. url: http://dx.doi.org/10.1137/15M1026122.

[7] K. Königsberger. Analysis 1. 6th ed. Springer, 2004.[8] B. Korte and J. Vygen. Kombinatorische Optimierung. Deutsche Übersetzung der 6. Aufla-

ge. Springer, 2018.[9] M. Markert et al. Das Python3.3-Tutorial auf Deutsch. Release 3.3. 2017. url: https://py-

tutorial-de.readthedocs.io/de/python-3.3/.[10] T. Rauber and G. Rünger. Parallele Programmierung. 2nd ed. Springer, 2007.[11] T. Richter and T. Wick. Einführung in die Numerische Mathematik. Begriffe, Konzepte und

zahlreiche Anwendungsbeispiele. Springer, 2017.[12] A. Schrijver. Combinatorial Optimization. Polyhedra and Efficiency. Springer, 2003.[13] J. Schüle. Paralleles Rechnen. de Gruyter, 2010.[14] G. van Rossum, B. Warsaw, and N. Coghlan. Style Guide for Python Code. url: https:

//www.python.org/dev/peps/pep-0008/.[15] D. Werner. Funktionalanalysis. Springer, 2004.

203

Page 210: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Bibliography

204 ©2018 Thomas Richter

Page 211: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Verzeichnis der Algorithmen

1.1. Einfache Berechnung der Fakultät . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2. Berechnung der Fakultät mit for-Schleife . . . . . . . . . . . . . . . . . . . . . . 91.3. Funktion zur Berechnung der Fakultät . . . . . . . . . . . . . . . . . . . . . . . 101.4. Rekursive Berechnung der Fibonacci-Zahlen . . . . . . . . . . . . . . . . . . . 111.5. Rekursive Berechnung der Fakultät . . . . . . . . . . . . . . . . . . . . . . . . . 111.6. Test auf Tautologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.1. Selection SortGegeben Liste L sowie eine (partielle) Ordnung . . . . . . . . . . . . . . . . . . . 21

2.2. Test auf Sortiertheit (totale Ordnung)Gegeben Liste L mit n Elementen und totaler Ordnung 6 . . . . . . . . . . . . . 26

2.3. Sequentielle SucheGegeben sei eine Liste L=[s1 ,..., sn] mit n ∈ N Einträgen. Gesucht ist die Positioneines ihrer Einträge l. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

2.4. Insertion SortGegeben eine Liste L mit n Elementen und eine (partielle) Ordnung �. . . . . . 29

2.5. Min-Sort; Selection Sort bei totaler OrdnungGegeben Liste L und totale Ordnung . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.6. Zusammenfügen sortierter ListenGegeben, zwei sortierte Listen L,R . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

2.7. Merge SortGegeben, Liste L mit n ∈ N Elementen und totaler Ordnung 6 . . . . . . . . . . 33

2.8. Quicksort Eingabe von Liste L mit n ∈ N Elementen sowie zwei Indizes0 6 l, r < n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2.9. Partitioniere Eingabe einer Liste L mit n ∈ N Elementen sowie von zweiIndizes 0 6 l < r < n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2.10. Sortieren mit Bucket-Sort nach Ziffer l . . . . . . . . . . . . . . . . . . . . . . . 442.11. Sortieren mit Counting-Sort nach Ziffer l . . . . . . . . . . . . . . . . . . . . . 45

3.1. GraphdurchmusterungGegeben ungerichteter Graph G als Adjazenzliste (doppelte Liste) mit n=len(G↪→ ) Knoten sowie ausgezeichneter Knoten x ∈ {0, . . . ,n − 1}. Ausgabe: ListeK aller Knoten, die von x aus erreichbar sind sowie die Adjazenzliste Z einesaufspannenden Baumes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

3.2. Tiefensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653.3. Breitensuche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663.4. Darstellung eines gewichteten Graphen . . . . . . . . . . . . . . . . . . . . . . 703.5. Dijkstra’s Algorithmus

Gegeben ein gewichteter Graph G = (V,E, fW) sowie ein Knoten x ∈ V . . . . . 73

205

Page 212: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Verzeichnis der Algorithmen

6.1. RückwärtseinsetzenEs sei R ∈ Rn×n eine reguläre rechte obere Dreiecksmatrix, d.h. rii 6= 0. DieLösung x ∈ Rn von Rx = b ist gegeben durch: . . . . . . . . . . . . . . . . . . . 110

6.2. Lösen von linearen Gleichungssystemen mit der LR-ZerlegungEs sei A ∈ Rn×n eine reguläre Matrix, für welche die LR-Zerlegung existiert. . 115

6.3. LR-Zerlegung einer Matrix A ohne ZusatzspeicherEs sei A = (aij)ij ∈ Rn×n eine reguläre Matrix, deren LR-Zerlegung existiert . 115

6.4. Direkte Berechnung der Cholesky-ZerlegungGegeben sei eine symmetrisch positiv definiteMatrixA ∈ Rn×n. Dann sind dieEinträge lij, j 6 i der Cholesky-Zerlegung bestimmt durch die Vorschrift: . . . 118

7.1. Funktions-Plotter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1387.2. Intervallschachtelung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1407.3. Newton-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1467.4. Newton-Verfahren als Defektkorrektur

Gegeben sei f ∈ C2[a,b]: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1527.5. Vereinfachtes Newton-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . 1557.6. Approximiertes Newton-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . 156

8.1. Gradientenverfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1718.2. Gradientenverfahren mit Abbruch . . . . . . . . . . . . . . . . . . . . . . . . . 1718.3. Armijo-Regel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1738.4. Least-Squares I: Zielfunktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1798.5. Least-Square II: Gradientenverfahren . . . . . . . . . . . . . . . . . . . . . . . . 1798.6. Least-Square III: Schrittweitensteuerung . . . . . . . . . . . . . . . . . . . . . . 1808.7. Least-Square IV: Hauptprogramm . . . . . . . . . . . . . . . . . . . . . . . . . . 1808.8. Auswerten eines feedforward-Netzes . . . . . . . . . . . . . . . . . . . . . . . . . 1918.9. Auswertung eine Netzes und des Gradienten . . . . . . . . . . . . . . . . . . . . 195

206 ©2018 Thomas Richter

Page 213: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Index

l1-Norm, 99p/q-Formel, 143Äpfel und Birnen, 20Äquivalenz, 13assert, 111

AbbruchkriteriumIntervallschachtelung, 146

abgeschlossene Menge, 163Abstiegsrichtung, 169, 170adjazent, 49Adjazenzliste, 58, 59Adjazenzmatrix, 57Algorithmus, 1Arboreszenz, 73Armijo-Schrittweitenregel, 172Aufwand, 25Ausgabe, 1Aussage, 12

erfüllbar, 14unerfüllbar, 14

Aussagenlogik, 12

Backpropagation, 194Banach’scher Fixpunktsatz, 126Bandbreiten-Problem, 56Bandmatrix, 56, 120Basis, 98Baum, 60benachbarte Knoten, 49beschränkte Menge, 163Besetzungsmuster, 119Bias, 182Bit, 85Branching, 73Breitensuche, 63, 66Bucket Sort, 32Byte, 81

Call by Reference, 22, 116Call by Value, 22

Cauchy-Schwarz-Ungleichung, 100Cholesky-Zerlegung, 117cpu time, 25

DämpfungsparameterNewton-Verfahren, 152

dünn besetzte Matrix, 56Darstellungsfehler, 86Datentyp, 2Deep Learning, 190Defekt, 106, 125, 152

eines linearen Gleichungssystems, 125Defektkorrektur

des Newton-Verfahrens, 152Determinante, 102Dimensionssatz, 106direktes Verfahren, 97, 143Disjunktion, 13, 187divide and conquer, 32doppelte Nullstelle, 143dyadisches Produkt, 189

Eigenvektor, 102Eigenwert, 102Eigenwerte

Inverse Iteration, 93Eingabe, 1Eingabe und Ausgabe, 5Einrücken, 3elementare Aussage, 13elementare Formal, 13Endknoten, 49euklidische Norm, 99euklidische Norm, 161euklidischer Raum, 100euklidisches Skalarprodukt, 99, 161Exponent, 86

Färbeproblem, 51Fakultät, 1feedforward Netz, 191

207

Page 214: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Index

Fibonacci-Zahlen, 10fill-ins, 122Fixpunkt, 126

abstoßender, 159anziehender, 159

Fließkommazahlen, 79FLOPS, 123Frobenius-Matrix, 112Frobenius-Norm, 104Frobeniusnorm, 189Funktionen, 9

Gauß-Seidel-Verfahren, 130Gaußsche Ausgleichrechnung, 177globales Minimum, 161Gradientenverfahren, 170Graph, 47

Bandbreite, 56gerichtet, 48gewichtet, 53ungerichtet, 48vollständig, 48

Graphdurchmusterung, 61Graphen

Durchmusterung, 60Graphpartitionierung, 55

Heaviside-Funktion, 182Heuristiken, 56Hidden-Layer, 190Hilbert-Raum, 100

IEEE 754, 86immutable, 24Implikation, 13Indizenzmatrix, 58Induktionsbeweis, 6Induzierte Ordnung, 31Input-Layer, 187Insertion Sort, 29Intervallschachtelung, 140, 144Inverse Iteration, 93inzident, 49isoliertes Minimum, 161iterativ, 11iterative Verfahren, 97

Jacobi-Verfahren, 129Junktor, 13

Königsberger Brückenproblem, 55Kante, 47Kantengewicht, 53Kantenzug, 50

geschlossen, 50Knoten, 47Kommentare, 4kompakte Menge, 163Komplexität, 47

average-case, 29best-case, 29worst-case, 29

Konditionszahleiner Matrix, 107Matrix, 109

Konjunktion, 13, 187Konvergenz

lineare, 158superlineare, 158iterativer Verfahren, 158

Konvergenzordnung, 158Konvergenzrate, 128Kreis, 50kunstliches Neuron, 186Kunstliches neuronales Netz

feedforward, 191

Laufzeit, 12lexikographische Ordnung, 41lexikographische Ordnung, 20LGS, 97Line-Search, 172lineare Abbildung, 106lineare Konvergenz, 158lineares Gleichungssystem, 97Logik, 12logische Verknüpfungen, 3lokales Minimum, 161

Mantisse, 86maschinelles Lernen, 186Maschinengenauigkeit, 87Matrix

Bandmatrix, 56dünn besetzt, 56dünn besetzte, 119

Matrixnorm, 104induzierte, 104

208 ©2018 Thomas Richter

Page 215: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Index

verträgliche, 104Maximierungsproblem, 161Maximumsnorm, 99Merge Sort, 32Minimierung, 161

restringiert, 163Minimum

globales, 161isoliert, 161lokales, 161strikt, 161

Modell, 176Modellmatrix, 120mutable, 24, 116

Negation, 13, 186neuronales Netz, 187Newton-Verfahren, 146

1D, 146Abbruchkriterium, 149Dämpfungsparameter, 152Defektkorrektur, 152

Norm, 98l1, 99euklidische, 99

Normäquivalenz, 99normierter Raum, 99notwendige Optimalitätsbedingung, 163NP-schwer, 56NP-vollständig, 56Nullstelle, 142

doppelte, 143mehrfache, 142

Optimalitätsbedingung ersterOrdnung, 163Optimierungsproblem, 161Ordnung, 19

Konvergenz, 158induziert, 31lexikographisch, 20, 41

orthogonal, 101Orthogonalbasis, 101Orthonormalbasis, 101Output-Layer, 187

paralleles Rechnen, 56Parallelisierung, 56Parallelogrammidentität, 100Parameteridentifikation, 176

Pivot-Element, 116Pivotisierung, 116Prä-Hilbert-Raum, 100Problem des Handlungsreisenden, 54Python

elif, 7else, 7for, 8if, 7range, 8Einrücken, 3Funktionen, 9Graphen, 58I/O, 5import, 24Kommentare, 4Liste, 8Queue, 65random, 24Stacks, 64time, 24

Queue, 63Quick Sort, 32

Rückwärtseinsetzen, 97Radix-Sort, 41Raum

normierter, 99Rekursion, 10, 15Residuum, 95, 152restringierte Minimierung, 163Richardson-Iteration, 94

Sattelpunkt, 164Satz von Vieta, 88Schleifen, 2Schrittweite, 169Sekantenmethode, 157Selection Sort

totale Ordnung, 30Sigmoid-Funktion, 182Skalarprodukt, 99

euklidisches, 99Sortieren, 19

stabil, 41Sortieren durch Einfügen, 29sparsity pattern, 119Speicherbedarf, 12

[email protected] 209

Page 216: AlgorithmischeMathematikrichter/SS19/am2/am.pdf · AlgorithmischeMathematik ThomasRichter∗ 30.Juni2019 ∗Institut für Analysis und Numerik, Universität Magdeburg.Raum 16b, Gebäude

Index

Spektralnorm, 91, 105Spektralradius, 102Spektrum, 102stabiles Sortieren, 41Stack, 63stationärer Punkt, 164steilster Abstieg, 170striktes Minimum, 161superlineare Konvergenz, 158surjektiv, 138

Tautologie, 14Terminierung, 7Tiefensuche, 63Transitivität, 15Traveling Salesman, 54Tridiagonalmatrix, 119

unitärer Raum, 100Update, 152

Variable, 2vergleichsbasiertes Sortieren, 40Verknüpfungen, 3

Wald, 60wall time, 25Weg, 50Word, 81

Zeitmessung, 24Zielfunktion, 161Zufallszahlen, 24zulässiger Bereich, 161zulässiger Punkt, 161Zusammenhangskomponente, 60Zuweisung, 2

210 ©2018 Thomas Richter


Recommended