Algorithmenentwurf

Werbung
Beispiele des Algorithmenentwurfs
Daniel Graf, Tobias Pröger
22. September 2016
Erklärung: Diese Mitschrift ist als Ergänzung zur Vorlesung gedacht. Wir erheben keinen
Anspruch auf Vollständigkeit und Korrektheit. Wir sind froh über Hinweise zu Fehlern oder
Ungenauigkeiten. Bitte senden Sie diese an [email protected].
1
Multiplikation ganzer Zahlen
Bereits in der Primarschule haben wir einen einfachen Algorithmus kennengelernt,
nämlich denjenigen zur Multiplikation zweier Zahlen. Gegeben seien dabei zwei Zahlen z1 und z2 in Dezimaldarstellung, und gesucht ist das Produkt z1 ·z2 dieser beiden
Zahlen (ebenfalls in Dezimaldarstellung). Dabei multiplizieren wir jede Ziffer der
einen Zahl mit jeder Ziffer der anderen Zahl, und summieren die (entsprechend nach
links verschobenen) Teilprodukte auf, um das Endergebnis zu erhalten. Abbildung 1
zeigt beispielhaft die Multiplikation der Zahlen 62 und 37 nach dieser Methode.
Multiplikation:
Primarschulmethode
Abb. 1 Multiplikation von 62 und 37 nach der Primarschulmethode.
Algorithmus von Karatsuba und Ofman Die Primarschulmethode benötigt zur
Multiplikation zweier zweistelliger Zahlen also 2 · 2 = 4 Multiplikationen von Ziffern.
Es ist leicht zu sehen, dass die Methode zur Multiplikation zweier n-stelliger Zahlen
n2 einstellige Multiplikationen benötigt. Karatsuba und Ofman schlugen 1962 ein
verbessertes Verfahren vor, das mit weniger einstelligen Multiplikationen auskommt.
Die Kosten für die Additionen ignorieren wir für den Moment.
Um nun mit weniger Multiplikationen auszukommen, beobachten wir, dass für
zwei zweistellige Zahlen z1 = 10a + b und z2 = 10c + d
(10a + b) · (10c + d) = 100a · c + 10a · c + 10b · d + b · d + 10(a − b) · (d − c)
gilt (nachrechnen!). Schaut man diesen Ausdruck genau an, wird man feststellen,
dass hier nur noch drei verschiedene Produkte zweier Ziffern vorhanden sind, nämlich
a · c, b · d, und (a − b) · (d − c). Ein kritischer Leser wird nun möglicherweise einwenden, dass auch die Multiplikation mit 10 oder 100 eine Multiplikation ist. Das stimmt
natürlich, wir zählen Multiplikationen mit Zehnerpotenzen aber dennoch nicht, da
sie verhältnismässig leicht realisiert werden können: Wird eine Zahl z mit 10k multipliziert, müssen an die Dezimaldarstellung von z lediglich k Nullen angehängt
1
Anzahl
einstelliger
Multiplikationen
Verbesserung
werden. Wir haben also eine Methode gefunden, zwei zweistellige Zahlen mit lediglich drei einstelligen Multiplikationen auszurechnen. Abbildung 2 zeigt erneut die
Multiplikation der Zahlen 62 und 37, diesmal nach der verbesserten Methode.
Abb. 2 Multiplikation von 62 und 37 nach der Methode von Karatsuba und Ofman. Das
oberste Teilprodukt entspricht b · d (und ist daher nicht nach links verschoben), die mittleren
Teilprodukte entsprechen 10(b · d), 10(a − b) · (d − c) und 10a · c (und sind daher um eine
Stelle nach links verschoben), das unterste entspricht 100a · c (und ist daher um zwei Stellen
nach links verschoben).
Grössere
Zahlen
Induktives
Prinzip
Verallgemeinerung
In der Informatik, z.B. in der Kryptographie, braucht man heute häufig sehr
grosse Zahlen. Es stellt sich die Frage, ob die obige Methode auch zur Multiplikation
zweier Zahlen mit mehr als zwei Ziffern benutzt werden kann. Betrachten wir zum
Beispiel das Produkt 6237·5898. Wir beobachten nun, dass wir die Faktoren als zwei
zweistellige Zahlen mit den “Ziffern” 62, 37, 58, 98 auffassen und dann rekursiv bzw.
induktiv dieselbe Methode anwenden können. In diesem Beispiel würde unsere neue
Methode 9 einstellige Multiplikationen benötigen, während die Schulmethode 16(=
4 · 4) benötigt. Dieses Prinzip der induktiven Anwendung kommt in der Algorithmik
sehr häufig vor.
Haben wir allgemein zwei n-stellige Zahlen (wobei wir vereinfachend annehmen
wollen, dass n = 2k eine Zweierpotenz ist), dann können wir diese als 10n/2 a + b
bzw. 10n/2 c + d schreiben. Wie früher beobachten wir nun, dass
(10n/2 a + b) · (10n/2 c + d)
= 10n a · c + 10n/2 a · c + 10n/2 b · d + b · d + 10n/2 (a − b) · (d − c)
Analyse
Teleskopieren
gilt. Die Produkte a · c, b · d und (a − b) · (d − c) berechnen wir dann rekursiv.
Wir analysieren nun das Verfahren genauer, um zu untersuchen, wie viele einstellige
Multiplikationen es ausführt. Dazu definieren wir M (n) als die Anzahl einstelliger
Multiplikationen bei zwei Zahlen mit je n = 2k Ziffern mit unserer neuen Methode.
Wir haben gesehen, dass wir zwei einstellige Zahlen mit einer elementaren Multiplikation multiplizieren können, und zwei zweistellige Zahlen mit drei elementaren
Multiplikationen. Allgemein erhalten wir
(
1
falls k = 0 ist
k
M (2 ) =
(1)
k−1
3 · M (2 ) falls k > 0 ist.
Um nun die Rekursionsgleichung (1) aufzulösen, teleskopieren wir, d.h., wir setzen
die Rekursionsformel einige Male ein, bis wir eine Vermutung für die explizite Formel
erhalten:
!
M (2k ) = 3 · M (2k−1 ) = 3 · 3 · M (2k−2 ) = 32 · M (2k−2 ) = · · · = 3k · M (20 ) = 3k .
Wir vermuten also, dass M (2k ) = 3k gilt. Dies beweisen wir nun mittels vollständiger
Induktion:
2
Induktionsvermutung: Wir vermuten, dass M (2k ) = 3k gilt.
Induktionsbeweis
Induktionsanfang (k = 0): Es ist M (20 ) = 30 = 1, also ist die Induktionsvermutung
für k = 0 korrekt.
Def.
I.V.
Induktionsschritt (k → k + 1): Für k > 1 gilt M (2k+1 ) = 3M (2k ) = 3 · 3k = 3k+1
(Hinweis: I.V. steht hier abkürzend für Induktionsvermutung). Damit ist die
Aussage für alle k korrekt.
Wir hatten früher argumentiert, dass die Primarschulmethode zur Multiplikation
zweier n-stelliger Zahlen n2 einstellige Multiplikationen ausführt. Um zu sehen, wie
viele solche Operationen die Methode von Karatsuba und Ofman benötigt, ersetzen
wir in der eben berechneten Formel 2k durch n (und k durch log2 (n)) und erhalten
log2 n
M (n) = 3log2 n = 2log2 3
= 2(log2 3)(log2 n) = nlog2 3 ≈ n1.58 ,
was bedeutend besser als die Primarschulmethode ist. Für grosse Zahlen ist der
Algorithmus von Karatsuba und Ofman also schnell um ein Vielfaches schneller als
die Primarschulmethode. Als konkretes Beispiel: Für zwei tausendstellige Zahlen ist
10002
unser neues Verfahren 1000
1.58 ≈ 18 Mal schneller als die Primarschulmethode.
Im Idealfall möchte man zusätzlich häufig gerne noch eine theoretische untere
Schranke finden, um zu zeigen, dass es gar nicht schneller gehen kann. Man kann sich
die Frage stellen, wie viele einstellige Multiplikationen mindestens notwendig sind,
um zwei n-stellige Zahlen zu multiplizieren. Diese Frage ist noch nicht endgültig
geklärt. Man weiss jedoch, dass es mindestens n elementare Multiplikationen sein
müssen. Ein nicht ganz präzises Argument dafür: Würden wir weniger als n2 einstellige Multiplikationen durchführen, so könnten wir erst gar nicht alle Ziffern der
Eingabe anschauen.
2
Verbesserung
Untere
Schranke
Star finden
Wie im vorigem Abschnitt gesehen gehen Algorithmenentwurf und dessen Analyse
Hand in Hand. Wäre eine Übungsaufgabe gewesen “Finde ein schnelleres Verfahren
für die Multiplikation zweier Zahlen”, wäre es schwierig gewesen, die Methode von
Karatsuba einfach so zu finden. Häufiger ist der Algorithmenentwurf aber eine sehr
systematische, nachvollziehbare Sache. Dazu betrachten wir ein weiteres Beispiel.
Gegeben sei ein Raum mit n Personen. Gesucht ist ein Star. Ein Star ist eine
Person, den alle im Raum kennen, und der selber niemanden anders kennt. Wir
erlauben nur eine einzige elementare Operation, nämlich eine Frage an eine beliebige
Person A, ob sie eine andere Person B kennt. Als mögliche Antworten sind nur
“Ja” und “Nein” erlaubt. Andere Fragen sind nicht erlaubt. Wir möchten nun mit
möglichst wenigen Fragen ermitteln, ob sich im Raum ein Star befindet.
Bevor wir uns überlegen, wie das gehen könnte, überlegen wir zunächst, welche
Eigenschaften das Problem hat. Wir beobachten:
• Es kann sein, dass es keinen Star gibt (z.B. wenn jeder jeden anderen kennt).
• Es kann sein, dass es genau einen Star gibt (z.B. wenn George Clooney in den
Raum käme).
• Es kann nicht mehr als einen Star geben. Angenommen, es gäbe zwei Stars S1
und S2 . Nun es gibt es zwei Möglichkeiten: Entweder, S1 kennt S2 , oder nicht.
Im ersten Fall wäre S1 kein Star, ansonsten wäre S2 kein Star.
3
Problembeschreibung
Problemeigenschaften
1
2
3
1
-
Ja
Nein
2
Nein
-
Nein
3
Ja
Ja
-
Abb. 3 Beispiel für eine Situation, in der ein Star existiert, nämlich 2.
Naive Lösung
Algorithmus 1 (Naiv) Eine naive Strategie zur Lösung des Problems besteht darin, jeden über jeden anderen auszufragen. Wir erzeugen eine Tabelle mit n Zeilen
und n Spalten, und tragen in dem Eintrag in Zeile A und Spalte B genau dann “Ja”
ein, wenn die Person A die Person B kennt, und “Nein” sonst. Die Diagonalelemente
können wir ignorieren, da wir annehmen, dass jeder Mensch sich selbst kennt. Wie
finden wir nun den Star in dieser Tabelle? Wir suchen eine Person, sodass ihre Spalte
nur “Ja” enthält (alle kennen sie) und ihre Zeile nur aus “Nein” besteht (sie kennt
niemanden). Abbildung 3 zeigt ein Beispiel für eine solche Situation: Person 2 ist
ein Star.
Anzahl
gestellter
Fragen
Ein Nachteil dieses naiven Verfahrens ist, dass sehr viele Fragen gestellt werden,
nämlich n · (n − 1) (also alle möglichen). Bei der Multiplikation zuvor haben wir
argumentiert, dass es nicht besser gehen kann, als jede Ziffer mindestens einmal
anzuschauen. Hier ist das ein bisschen anders: Es ist nicht ausgeschlossen, dass wir
den Star finden können oder mit Sicherheit sagen können, dass es keinen Star gibt,
ohne jede mögliche Frage zu stellen.
Induktive
Lösung
Algorithmus 2a (Induktiv) Im vorigen Abschnitt hat es uns geholfen, das Problem
in kleinere Teile zu zerlegen, d.h., es induktiv zu lösen. Wenn es im Raum n = 2
Personen gibt, dann können wir immer einen Star mit F (2) = 2 Fragen finden.
Gibt es im Raum n > 2 Person, dann könnten wir wie folgt vorgehen: Wir schicken
eine Person nach draussen, bestimmen rekursiv den potentiellen Star unter den
verbleibenden Personen und holen die abwesende Person wieder in den Raum. Für
diese Person müssen wir prüfen, ob sie der Star ist, was 2(n − 1) Fragen kosten
kann. Damit werden im schlimmsten Fall insgesamt F (n) = 2(n − 1) + F (n − 1) =
2(n − 1) + 2(n − 2) + · · · + 2 = n(n − 1) viele Fragen gestellt, was leider noch keine
Verbesserung gegenüber dem naiven Verfahren darstellt.
Verbesserte
Lösung
Algorithmus 2b (Verbesserung) Wieso sparen wir keine Fragen? Das Problem
besteht darin, dass die herausgeschickte Person genau der Star sein kann. Dann
nämlich brauchen wir viele Fragen, wenn er den Raum wieder betritt. Wir müssten
also irgendwie garantieren, dass wir nicht den Star aus dem Raum schicken. Dies ist
aber einfach machbar: Wir fragen eine beliebige Person A im Raum, ob sie eine beliebige andere Person B im Raum kennt. Falls ja, dann ist A kein Star, ansonsten ist
B kein Star. Wenn die zuvor herausgeschickte Person nun den Raum wieder betritt,
dann reichen zwei weitere Fragen um herauszufinden, ob der ggf. im Raum gefundene potentielle Star wirklich ein Star ist. Für die Anzahl der maximal gestellten
Fragen ergibt sich also
Analyse
(
2
F (n) =
1 + F (n − 1) + 2
4
für n = 2
für n > 2.
Wie zuvor teleskopieren wir und erhalten
F (n) = 3 + F (n − 1) = 3 + 3 + F (n − 2) = · · · = 3(n − 2) + 2 = 3n − 4,
was nun noch mit vollständiger Induktion über n bewiesen werden muss (Übung!).
Wir sehen, dass in unserem neuen Verfahren deutlich weniger Fragen als im naiven
Verfahren gestellt werden.
5
Herunterladen