Unterlagen zur Vorlesung Algorithmik II – SS 07 – Semester 3 Studiengang Bachelor LV-Nr. R. Rüdiger Fachbereich Informatik FH Braunschweig/Wolfenbüttel Wolfenbüttel, im Februar 2007 Inhaltsverzeichnis 1 Grundlegende Konzepte 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung . . . 1.2 Worst-Case und Average-Case . . . . . . . . . . . . 1.3 Wiederholung: asymptotische Notationen . . . . . . 1.4 Rekursionsgleichungen . . . . . . . . . . . . . . . . 1.5 Amortisationsanalyse . . . . . . . . . . . . . . . . . 1.6 Uniformes Komplexitätsmaß und Bit-Komplexität . 1.7 Probabilistische Algorithmen und Datenstrukturen 1.8 Pseudozufallszahlen . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 10 14 15 16 19 20 24 2 Datenkompression 2.1 Bemerkungen zur Informationstheorie . . . . . . . . . . . . . . . . . 2.2 Huffman-Codierung . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Lempel-Ziv-Welch Algorithmus . . . . . . . . . . . . . . . . . . . . 26 26 27 29 3 Polynome und die FFT 3.1 Operationen mit großen Zahlen . . . . . . . . . . . . . . . . . . . . 3.2 Schnelle Matrixmultiplikation nach Strassen . . . . . . . . . . . . . 3.3 Polynommultiplikation und die FFT . . . . . . . . . . . . . . . . . 32 32 34 36 4 Algorithmen für die Kryptologie 4.1 Grundkonzepte der Kryptologie . . . . . . . . 4.2 RSA-Verfahren: Übersicht und Zahlenbeispiel 4.3 Begriffe zum Verständnis des RSA-Verfahrens 4.4 Grundlagen . . . . . . . . . . . . . . . . . . . 4.5 Größter gemeinsamer Teiler. Algorithmen . . . 4.6 Modulare Exponentiation . . . . . . . . . . . 4.7 Primzahltesten . . . . . . . . . . . . . . . . . 42 42 46 48 49 51 56 56 R. Rüdiger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Algorithmik II — 1. März 2007 — Literaturverzeichnis [CLRS01] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms. MIT Press, Cambridge, Massachusetts, London, England, 2001. [Sch01] Uwe Schöning. Algorithmik. Spektrum Akademischer Verlag, 2001. [Wä04] D. Wätjen. Kryptographie. Spektrum Verlag, 2004. Algorithmik II R. Rüdiger — 1. März 2007 — Kapitel 1 Grundlegende Konzepte Literatur: [Sch01, S. 17] 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung Ereignisse und Wahrscheinlichkeitsmaße Ein Anlaß zur Einführung der Wahrscheinlichkeitstheorie ist die mangelnde Kenntnis über ein System (zum Beispiel beim Werfen eines Würfels). ) naiver Versuch: Definition der Wahrscheinlichkeit durch p = limN →∞ n(N . N N = Anzahl Versuche, n = Anzahl günstiger“ Ausgänge ” Der Versuch führt nicht zum Ziel! ) Warum? der lim existiert nicht in einem normalen Sinn, denn: 0 ≤ n(N ≤ 1. Jeder N Wert ist möglich; große Abweichungen von p = 16 sind nur unwahrscheinlich“ (nicht ” aber unmöglich). Was unwahrscheinlich“ hier bedeuten soll, ist aber unklar, denn ” der Begriff Wahrscheinlichkeit soll ja gerade erst definiert werden. Andererseits stabilisieren sich empirisch gewonnene Werte für p bei großen N außerordentlich stark. Beispiel: 106 Münzwürfe: 6 P #Kopf = 106 = (1/2)10 = 10−300 000 P [#Kopf > 510 000] = 10−88 heutige Formulierung: mittels Mengen und sog. Maße auf Mengen (Kolmogorov, 1933) Beispiel: Werfen eines einzelnen Würfels: mögliche Versuchsausgänge zusammengefaßt in Ω = {x | x = 1, 2, 3, 4, 5, 6} = {1, 2, 3, 4, 5, 6} Algorithmik II R. Rüdiger — 1. März 2007 — 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung 4 Ω heißt Ereignisraum (= Stichprobenraum); Teilmengen A, B, C, . . . ⊂ Ω heißen Ereignisse (Anzahl = 26 = 64); einelementige Teilmengen {ω} ⊂ Ω heißen Elementarereignisse (Anzahl = 6) explizit im Detail: alle Ereignisse für 4-seitigen (tetraederförmigen) Würfel (Ω = {x | x = 1, 2, 3, 4}): 0-elementige Teilmenge: ∅ = {} 1-elementigen Teilmengen: {1} {2} {3} {4} 2-elementigen Teilmengen: {1, 2} {1, 3} {1, 4} {2, 3} {2, 4} {3, 4} 3-elementigen Teilmengen: {1, 2, 3} {1, 2, 4} {1, 3, 4} {2, 3, 4} gesamtes Ω: Ω = {1, 2, 3, 4} Beispiele für Ereignisse: • Augenzahl ≥ 2 ({2, 3, 4}) • Augenzahl durch 2 teilbar ({2, 4}) • Augenzahl ≤ 7 ({1, 2, 3, 4} = Ω) • Augenzahl ≥ 5 (∅) Alle Teilmengen einer festen gegebenen Menge Ω bilden die sog. Potenzmenge über Ω: 1.1.1 Definition Sei Ω eine (fest vorgegebene) Menge. Dann heißt die Menge P(Ω) = {A | A ⊆ Ω} = 2Ω die Potenzmenge über Ω. 2 Algorithmik II R. Rüdiger — 1. März 2007 — 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung 5 x2 W 6 · · · · · · 5 · · · · · · 4 · · · · · · · · · · · · · · · · · · · · · · 1 4 5 6 3 2 1 · 2 · 3 Elementarereignisse x1 Abbildung 1.1: Zweimaliges Werfen eines Würfels 1.1.2 Satz Es gilt |P(Ω)| = 2|Ω| . 2 Weiteres Beispiel: zweimaliges Werfen eines Würfels Ω = {(x1 , x2 )|x1 , x2 ∈ {1, 2, . . . , 6}} = {(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), . . . , (6, 6)} also: |Ω| = 36 Bedeutung: beim ersten Wurf: Augenzahl x1 , beim zweiten Wurf: x2 (Abbildung 1.1) z.B.: A = {(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (3, 1)} ⊂ Ω ist Ereignis, daß geworfene Augensumme ≤ 4 ist. Tabelle mit Begriffsbildungen beim Zusammensetzen von Ereignissen (also: Teilmengen von Ω: Algorithmik II R. Rüdiger — 1. März 2007 — 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung 6 A tritt ein und B tritt ein AÌW BÌW W A A tritt ein, aber nicht B Abbildung 1.2: Zusammensetzen von Ereignissen Ereignissprache A tritt ein B tritt ein A tritt ein und B tritt ein A tritt ein oder B tritt ein A tritt ein, aber nicht B A tritt nicht ein Entweder tritt A ein oder B, nicht aber beide das sichere Ereignis das unmögliche Ereignis A zieht B nach sich A und B sind unvereinbar Mengensprache A B A∩B A∪B A\B Ac = Ω \ A A∆B = (A ∩ B c ) ∪ (Ac ∩ B) (symmetrische Differenz) Ω ∅ A⊆B A∩B =∅ (Abbildung 1.2) Einführung der Wahrscheinlichkeit: Man möchte den Ereignissen A ⊆ Ω eine Wahrscheinlichkeit P [A] zuordnen, also: • Ω = Grundraum, der alle möglichen Ereignisse des Zufallsexperiments als Teilmengen enthält • A = Menge von Ereignissen = System von Teilmengen von Ω (A ⊆ P(Ω), eventuell alle: A = P(Ω)? In allgemeineren Situationen als den hier behandelten führt das allerdings auf Probleme.) • P = Funktion, die jeder Menge A ∈ A eine Wahrscheinlichkeit P [A] zuordnet P sollte zumindestens folgende von den relativen Häufigkeiten übernommene Eigenschaften haben: Algorithmik II R. Rüdiger — 1. März 2007 — 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung 1. P [A] ≥ 0 für jedes Ereignis A ⊆ Ω 2. P [Ω] = 1 3. P [A ∪ B ] = P [A] + P [B ] , wenn A ∩ B = ∅ 7 Für jedes endliche oder abzählbar unendliche Ω reichen diese Axiome aus. Alle Teilmengen von Ω paßt i.a. nicht zu den Axiomen für P, wenn man auch noch verlangt: P [{x}] = 0 für x ∈ Ω, wenn Ω über abzählbar ist, also z.B. für x ∈ R (spielt in der Vorlesung keine Rolle). 1.1.3 Definition Ein Wahrscheinlichkeitsraum ist ein Tripel (Ω, A, P), bestehend aus einer Menge Ω, einem System von Teilmengen A über Ω und einem Wahrscheinlichkeitsmaß P über A. 2 Konkret verwendet wird hier das größtmögliche A, also A = P(Ω). Einige Eigenschaften von Wahrscheinlichkeitsmaßen: 1.1.4 Satz Ist P ein Wahrscheinlichkeitsmaß auf A, so gilt: 1. P [∅] = 0 2. Für paarweise unvereinbare Ereignisse Ai , d.h. Ai ∩ Aj = ∅ für 1 ≤ i, j ≤ n, i 6= j gilt " P n [ i=1 # Ai = n X P [Ai ] i=1 3. insbesondere: A ∩ B = ∅ =⇒ P [A ∪ B ] = P [A] + P [B ] 4. Für alle A ∈ A =⇒ P [Ac ] = 1 − P [A] 5. Wenn A, B ∈ A mit A ⊆ B, dann folgt P [B \ A] = P [B ] − P [A] 6. Wenn A, B ∈ A mit A ⊆ B, dann folgt P [A] ≤ P [B ] 7. Für beliebige A, B ∈ A gilt: : P [A ∪ B ] = P [A] + P [B ] − P [A ∩ B ] 2 Es gibt eine Verallgemeinerung des letzten Ausdrucks: das ist die sog. Siebformel von Poincaré - Sylvester. Algorithmik II R. Rüdiger — 1. März 2007 — 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung 8 Speziell für n = 3 lautet sie: P [A ∪ B ∪ C ] = P [A] + P [B ] + P [C ] − P [A ∩ B ] − P [A ∩ C ] − P [B ∩ C ] + P [A ∩ B ∩ C ] Laplace-Experimente Ein Laplace-Experiment ist ein Zufallsexperiment mit den (endlich vielen) möglichen Ausgängen ω1 , ω2 , . . . , ωn , die alle gleichwahrscheinlich seien, genauer: Sei Ω = {ω1 , ω2 , . . . , ωn }. Das Wahrscheinlichkeitsmaß wird festgelegt durch die Forderung P [{ω1 }] = P [{ω2 }] = . . . = P [{ωn }] =: p. Dann gilt für ein beliebiges Ereignis A: P [A] = X P [{ω}] = ω∈A |A| Anzahl der für A günstigen“ Ausgänge ” = |Ω| Anzahl der möglichen Ausgänge Begründung: Es gilt Ω= n [ {ωi }, n = |Ω|, {ωi } ∩ {ωj } = ∅ für i 6= j i=1 also " 1 = P [Ω] = P n [ i=1 # {ωi } = n X P [{ωi }] = np, i=1 Es folgt p = 1/n = 1/|Ω|. Daher: X |A| P [A] = P [{ω}] = p|A| = |Ω| ω∈A Damit ist eine Bestimmung der Funktion P [A] zurückgeführt auf ein Problem der Kombinatorik. Tatsächlich wird in mathematischen Einführungen zur Wahrscheinlichkeitstheorie in dem hier beschrieben Rahmen, also für endliche Wahrscheinlichkeiträume, hauptsächlich die Kombinatorik behandelt. Beispiel: Binomialverteilung Man führe N Experimente durch mit jeweils zwei möglichen Ausgängen, z.B. Kopf“ ” und Zahl“ beim zufälligen Münzwurf. Die Wahrscheinlichkeit für das Auftreten ” eines der beiden Ereignisse (z.B. Kopf) sei p. Wie groß ist die Wahrscheinlichkeit f (k; N, p) dafür, daß dieses Ereignis insgesamt genau k mal eintritt (0 ≤ k ≤ N ). Algorithmik II R. Rüdiger — 1. März 2007 — 1.1 Wahrscheinlichkeitsrechnung - Kurzeinführung 1 · 2 3 4 · · 5 6 7 ¼ · 9 N-1 N · · Experiment-Nr. k mal Abbildung 1.3: Zur Binomialverteilung (s. Abbildung 1.3) pk q N −k bei vorgegebenen Nummern insgesamt: mal Anzahl der k-elementigen Teilmengen einer N -elementigen Menge: N k N −k p q k Endgültige Formel für Binomialverteilung: N k N −k f (k; N, p) = p q mit 0 ≤ k ≤ N , p + q = 1, 0 ≤ p, q ≤ 1 k Diese Formel wird in der Vorlesung Algorithmik II eine gewisse Rolle spielen. Zufallsvariablen, Wahrscheinlichkeitsverteilungen, Erwartungswert Betrachte Zufallsexperiment mit Ausgang ω ∈ Ω und davon abhängiges Merkmal X(ω) ∈ R, Ω = Stichprobenraum, X : Ω → R Beispiel: Werfen von drei Würfeln und Beobachten (Messen) der gewürfelten Augensumme: formalisiert: Ω = {(1, 1, 1), (1, 1, 2), (1, 1, 3), . . . , (1, 2, 1), (1, 2, 2), . . . , (6, 6, 6)} ⊂ N3 also: |Ω| = 63 = 216 mögliche Ausgänge sind X(ω) = x1 + x2 + x2 P [{ω | X(ω) = k}] =: P [X = k ] = Wahrscheinlichkeit, dass X den Wert k hat rechte Seite: vereinfachte Schreibweise in der Praxis Wertetabelle: Algorithmik II R. Rüdiger — 1. März 2007 — 1.2 Worst-Case und Average-Case 10 k P [X = k ] 3 1/216 4 3/216 5 6/216 .. .. . . 17 18 3/216 1/216 Begründung: k P [X = k ] = pk 3 =1+1+1 (1, 1, 1) 1/216 4 =1+1+2 (2, 1, 1), (1, 2, 1), (1, 1, 2) 3/216 5 = 1 + 1 + 3 = 1 + 2 + 2 (3, 1, 1), (1, 3, 1), (1, 1, 3), (1, 2, 2), (2, 1, 2), (2, 2, 1) 6/216 6 = 1 + 1 + 4 = 1 + 2 + 3 ... =2+2+2 ... 7 =1+3+3=1+2+4 = 2 + 2 + 3 = 3 + 3 + 1 ... .. . 17 = 6 + 6 + 5 18 = 6 + 6 + 6 (5, 6, 6), (6, 5, 6), (6, 6, 5) (6, 6, 6) 3/216 1/216 Erwartungswert (entspricht Mittelwert, gewichtetes Mittel) einer Zufallsvariablen X mit möglichen Werten k ∈ N: ! ∞ ∞ X X kpk k P [X = k ] = X̄ = E [X ] = k=1 k=1 rechts: wahrscheinlich vertrautere Schreibweise, etwas besser wäre: alle möglichen Werte von k 1.2 Worst-Case und Average-Case [Sch01, S. 42] . Jeder Algorithmus wird stets mit einer Eingabe gestartet: Eingabe sei x Länge der Eingabe x: n = |x| ∈ N. z.B.: Sortieralgorithmus, Eingabe x = a1 a2 . . . an . Algorithmik II R. Rüdiger — 1. März 2007 — 1.2 Worst-Case und Average-Case 11 . worst-case-Komplexität worst-case-timeA (n) = max timeA (x) x:|x|=n = Maximum bei gegebener Länge n von x timeA (x) = Laufzeit des Algorithmus A mit Eingabe x g(n) ≤ worst-case-time ≤ f (n) . Bedeutung: – rechte Seite: A macht bei jeder Eingabe höchstens f (n) Schritte (= Laufzeit) – linke Seite: Es gibt Eingaben x der Länge n, für die der Algorithmus mindestens die Laufzeit g(n) hat. . average-case-Komplexität Annahme: Gleichverteilung1 auf allen Eingaben der Länge n Laufzeit: Zufallsvariable TA,n : average-timeA (n) = E [TA,n ] (gemittelt über Eingaben) oder explizit: X average-timeA (n) = timeA (x) x:|x|=n Anzahl aller Eingaben (formal gebildet wie Mittelwert) Anzahl aller Eingaben (der Länge n) = |{x : |x| = n}| . Frage: was ist mehr, was weniger realistisch? Bewertung: – average-case eher realistisch; ist schwieriger durchzuführen, aber Annahme der Gleichverteilung evtl. unrealistisch (z.B. Sortieren) – worst-case: häufig interessant (unter Aspekt der Sicherheit, Realzeitsy” stem“), aber vielfach zu pessimistisch (und daher auch nicht nützlich) (Diskussion) 1 Damit bewegen wir uns in dem Rahmen der Stochastik. Algorithmik II R. Rüdiger — 1. März 2007 — 1.2 Worst-Case und Average-Case 12 . Beispiel: Maximum bestimmen Programm: Array a[1..n], n ≥ 1, n Eingabelänge 1 max ← a[1] 2 for i ← 2 to n 3 do if a[i] > max 4 then max ← a[i] Aufwand: c1 : Ausführung von (1) c2 : Aufwand für jeden einzelnen Schleifendurchlauf in (2) und (3) c3 : Aufwand für (4): Zuweisung daraus: worst-case-timeA (n) = c1 + (n − 1)(c2 + c3 ) Hier wird unterstellt: In jedem Durchlauf wird die Zuweisung in Zeile 4 ausgeführt, wie z.B. bei 1 2 3 4 5. entsprechendes Resultat für average case? Beispiel: In einem Array a seien n verschiedene Zahlen 1, . . . , n zufällig verteilt, wobei alle n! Permutationen gleichwahrscheinlich seien. Dann gilt P [aj > max(a1 , a2 , . . . , aj−1 )] = 1/j für j = 2, . . . , n. also konkret: P [a2 > a1 ] P [a3 > max(a1 , a2 )] ... P [aj > max(a1 , a2 , . . . , aj−1 )] ... P [an > max(a1 , a2 , . . . , an−1 )] = 1/2 = 1/3 = 1/j für j = 2, . . . , n = 1/n Algorithmik II R. Rüdiger — 1. März 2007 — 1.2 Worst-Case und Average-Case 13 1. Zu berechnen ist daraus die average-time nach der Formel average-time = c1 + c2 (n − 1) + c3 n X E [Xj ] j=2 Xj = 1 im Arrayabschnitt zu den Indizes 1 . . . j ist aj das Maximum 0 sonst den Erwartungswert E [Xj ]. Das Ergebnis kann ausgedrückt werden durch die sog. harmonische Reihe Hn = n X 1 j=1 . j 2. Für die Hn gilt die Schachtelung ln(n + 1) ≤ Hn ≤ ln n + 1 gültig ist. Hinweis: Die Rechnung benutzt Hyperbeln ho (x) sowie hu (x), die die Funktion 1/n jeweils von oben bzw. unten beschränken. Lösung zu dem Beispiel: 1. Ausgangsgleichung: average-time = c1 + c2 (n − 1) + c3 n X E [Xj ] j=2 Was ist E [Xj ] = . . .? n X 1 k E [Xj ] = k=2 n X δjk = δjk 1 j 1 = 1 für j ≥ 2 j k=2 also: average-time = c1 + c2 (n − 1) + c3 n X 1 j=2 j ausgdrückt durch die harmonische Reihe: average-time = c1 + c2 (n − 1) + c3 (Hn − 1) ≈ c1 + c2 (n − 1) + c3 ln n Algorithmik II R. Rüdiger — 1. März 2007 — 1.3 Wiederholung: asymptotische Notationen 2. Es gilt Z n 0 1 dx ≤ Hn ≤ 1+x Z 1 n 14 1 dx + 1 x Man kann sich das am einfachsten graphisch klarmachen. Werte für die Funktionen hu und ho : hu (0) = 1 hu (1) = hu (2) = hu (3) = hu (4) = .. . hu (x) = ho (0) = undef. 1 2 1 3 1 4 1 5 ho (1) = 1 ho (2) = ho (3) = ho (4) = 1 1+x ho (x) = 1 2 1 3 1 4 1 x daher: ln(1 + x)|n0 = ln(1 + n) ≤ Hn ≤ ln n + 1 genauer: Hn ≈ ln n + 1 +γ 2n wobei γ = Eulersche Konstante ≈ 0.57721 . . . 1.3 Wiederholung: asymptotische Notationen . g(n) = O(f (n)): Für hinreichend große n ist g von oben durch f beschränkt präziser: g(n) ≤ Cf (n) für n ≥ n0 mit geeigneten n0 und C . g(n) = Ω(f (n)): analog: g ist von unten durch f beschränkt . g(n) = Θ(f (n)): g ist von oben und von unten durch f beschränkt: C1 f (n) ≤ g(n) ≤ C2 f (n) Algorithmik II R. Rüdiger — 1. März 2007 — 1.4 Rekursionsgleichungen 15 . g(n) = o(f (n)): g(n) lim =0 n→∞ f (n) . g(n) = ω(f (n)): f (n) lim =0 n→∞ g(n) . g(n) ∼ f (n): g(n) lim =1 n→∞ f (n) 1.4 Rekursionsgleichungen [Sch01, S. 51] . Rekursionsgleichungen Beispiele und einige Erläuterungen 1. Türme von Hanoi (Algorithmik I) 2. Divide and Conquer (Algorithmik I) formal z.B.: f (n) = 2f (n/2) + cn + d bei gegebenen Konstanten c und d. Die Frage: Wie verhält sich f (n) für große n? 3. Merge-Sort (als Aufgabe) . Muß man die Abschätzungen jedesmal neu berechnen? NEIN: es gibt einen (einigermaßen) allgemeinen Satz, der viele Fälle direkt erledigt. Algorithmik II R. Rüdiger — 1. März 2007 — 1.5 Amortisationsanalyse 16 . Master-Theorem: Gegeben sei eine Rekursionsgleichung der Form T (n) = m X T (αi n) + Θ(nk ), i=1 wobei 0 < αi < 1, m ≥ 1, k ≥ 0. Dann kann T (n) asymptotisch wie k falls Θ(n ), Θ(nk log n), falls T (n) = Θ(nc ), falls Hierbei ist c Lösung der Gleichung alle i gilt c = −(ln m)/ ln α. folgt abgeschätzt werden: Pm k i=1 αi < 1 Pm k i=1 αi = 1 Pm k i=1 αi > 1 Pm i=1 αi c = 1; insbesondere für αi = α für . Beispiele dazu T (n) = 8T (n/3) + n2 (αi = 13 , m = 8, k = 2) T (n) = 9T (n/3) + n2 (αi = 13 , m = 9, k = 2) T (n) = 10T (n/3) + n2 (αi = 13 , m = 10, k = 2) Lösungen dazu sind: da P8 T (n) = Θ(n2 log n), da P9 T (n) = Θ(nc ), P10 T (n) = Θ(n2 ), da i=1 i=1 i=1 1 2 3 1 2 3 1 2 3 = 8 9 <1 = 9 9 =1 = 10 9 >1 ln 10 ≈ 2.096. ln(1/3) Ergänzung: Der Spezialfall αi = α für alle i: Pm c c c i=1 α = 1 ⇒ mα = 1 ⇒ α = 1/m ⇒ c ln α = − ln m, mit c = − also c = − ln m/ ln α 1.5 Amortisationsanalyse [Sch01, S. 59] Algorithmik II R. Rüdiger — 1. März 2007 — 1.5 Amortisationsanalyse 17 . Betrachte einen Algorithmus mit n Grundoperationen: Worst-Case-Analyse kann z. B. so durchgeführt werden, dass für jede dieser n Operationen ein Auftreten des ungünstigsten Falls unterstellt wird . Die Analyse kann aber unter Umständen verbessert werden, wenn man weiß, dass der ungünstigste Fall nicht jedesmal auftreten kann . Eine Analyse auf solcher Basis heißt Amortisationsanalyse . daraus folgt eine verbesserte Abschätzung T (n) für die worst-case Gesamtkomplexität . Ergebnis ist die sog. amortisierte Komplexität: T (n)/n (ist nicht dasselbe wie die average-case Komplexität: hier keine Wahrscheinlichkeitsbetrachtung!) . Beispiel Binärzähler: – Grundoperation: Hochzählen – Komplexität: Anzahl der Bits, die in einem Schritt geändert werden – n Zähloperationen, Bitzähler mit dlog2 ne bits ist erforderlich Anmerkung: z.B.: 3 < log2 14 = log2 1110 < 4, da (23 < 14 < 24 ) – zunächst eine worst-case Analyse: Annahme: Überträge gehen (jedesmal) bis in erste Stelle Daraus ergibt sich die Gesamtkomplexität = O(n log n) Begründung: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ............... n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ............... {z } | log n Worst-case-Komplexität ist daher O(n log n). Algorithmik II R. Rüdiger — 1. März 2007 — 1.5 Amortisationsanalyse 18 – bessere Analyse (Komplexität = Anzahl der geänderten Stellen): Zähler Komplexität also 00000 00001 1 1 00010 2 1+1 00011 1 1 00100 3 1+1+1 1 00101 1 00110 2 1+1 00111 1 1 01000 4 1+1+1+1 01001 1 1 .. .. . . n + n + n + n + ... 2 4 8 (Änderungen sind unterstrichen) – also: n Schritte, jedes 2. Mal eine 1 extra, jedes 4. Mal noch eine 1 extra, usw. daraus: n n n T (n) ≤ n + + + + . . . = 2n = O(n) 2 4 8 ist also eine verbesserte Abschätzung gegenüber O(n log n) – Formel: N X xk = k=0 1 − xN +1 1−x – hier: T (n) ≤ n ∞ k X 1 k=0 2 =n 1 1− 1 2 = 2n – amortisierte Komplexität“ einer einzelnen Zählaktion: ” T (n)/n ≤ 2 – zum Vergleich: Tworst-case (n)/n ≤ log n . anschauliche Betrachtungsweise: Bankkontomethode – Laufzeiten t1 , t2 , . . . , tn entsprechen Geldbeträgen Algorithmik II R. Rüdiger — 1. März 2007 — 1.6 Uniformes Komplexitätsmaß und Bit-Komplexität 19 – Gesamtbetrag: T (n) = t1 + t2 + . . . + tn – pro Einzeloperation: T (n)/n – mit Gehaltszahlung“ G: ” T (n)/n ≤ G (für Einzeloperation) . Beispiel: Anwendung Bankkontomethode auf Binärzählerbeispiel – Gehaltszahlung erfolgt stets unmittelbar vor Ausführung einer Operation – Gehalt G = 2: 1 für Setzen auf 1, 1 für Zurücksetzen – amortisierte Komplexität einer einzelnen Zählaktion ≤ 2 Übersichtstabelle: Zähler Gehalts- Kosten Gutschrift / aktueller zahlung Abbuchung Kontostand 00000 0 +2 −1 +1 1 00001 00010 +2 −2 ±0 1 00011 +2 −1 +1 2 00100 +2 −3 −1 1 00101 +2 −1 +1 2 00110 +2 −2 ±0 2 00111 +2 −1 +1 3 01000 +2 −4 −2 1 +2 −1 +1 2 01001 .. .. .. .. . . . . 1.6 fiktiv G = 1: Kontostand 0 0 −1 geht nicht Uniformes Komplexitätsmaß und Bit-Komplexität [Sch01, S. 62] verschiedene Komplexitätsmaße: . uniformes Komplexitätsmaß Annahme: jede Elementaroperation erfordert konstanten Aufwand ist sinnvoll, wenn alle Zahlen in jeweils einer Speicherzelle untergebracht werden können. Algorithmik II R. Rüdiger — 1. März 2007 — 1.7 Probabilistische Algorithmen und Datenstrukturen 20 . Bit-Komplexitätsmaß obige Annahme ist nicht sinnvoll, wenn die Eingabe z. B. nur eine, aber eine sehr große Zahl ist Beispiel: Frage: ist eine (sehr große) Zahl eine Primzahl? In dem Zusammenhang wird das sog. Bit-Komplexitätsmaß verwendet bei Zahlen ∈ Z: Länge der Binärdarstellung ((entspricht Komplexitätsbegriff auf Turing-Maschinen)) 1.7 Probabilistische Algorithmen und Datenstrukturen [Sch01, S. 63] . probabilistische = stochastische Algorithmen: verwenden Zufallszahlen Formulierung: RANDOM x IN M oder auch x ∈R M d.h.: aus der Menge M wird zufällig (1) unter Gleichverteilung und (2) unabhängig ein Wert gezogen, der x zugewiesen wird. . Einschub: Es gibt zwei Sorten von probabilistischen Algorithmen: 1. Las Vegas-Algorithmen 2. Monte Carlo-Algorithmen Erläuterungen und Beispiele: 1. Las Vegas-Algorithmen: die Laufzeit ist eine Zufallsvariable, die Algorithmen produzieren keine falschen Ausgaben, allenfalls Misserfolg (etwa bei vorgegebener Laufzeitschranke) 2. Monte Carlo-Algorithmen: können fehlerhafte Ausgaben produzieren (ein- und zweiseitiger Fehler) Algorithmik II R. Rüdiger — 1. März 2007 — 1.7 Probabilistische Algorithmen und Datenstrukturen 21 Übersicht Las Vegas Algorithmen: Antwort: Ja Falls diese Antwort gegeben wird, so ist sie auch korrekt. Nein Falls diese Antwort gegeben wird, so ist sie auch korrekt. Misserfolg Algorithmus konnte Problem in gegebener Zeit nicht lösen Monte Carlo-Algorithmen: Ja Bei Monte Carlo-Algorithmen können entweder – beide Antworten falsch sein (zweiseitiger Fehler) oder – eine der beiden Antworten ist definitiv richtig, die andere möglicherweise falsch. Antwort: Nein . Beispiel für probabilistischen Algorithmus mit Fehler (also ein Monte CarloAlgorithmus) Zahlen: (Frage: gleich als Multimenge?) (1) 255322 ≡ 523225 also {{2, 5, 5, 3, 2, 2}} ≡ {{5, 2, 3, 2, 2, 5}} dagegen (2) 255322 6≡ 523525 (1) eine Möglichkeit: sortieren: Θ(n log n) (2) mit probabilistischem Algorithmus: Θ(n) im Detail: definiere Polynome pA (x) = n n Y Y (x − A[i]) und pB (x) = (x − B[i]) i=1 i=1 A ≡ B genau dann wenn q := pA − pB = 0 (das Nullpolynom) q hat höchstens n Nullstellen. wähle x aus einer (endl.) Menge S mit |S| n eine mögliche Wahl von S: S = {1, 2, . . . , dn/εe} Wahrscheinlichkeit, mit x ∈R S Nullstelle von q zu treffen ist n/|S| = n d nε e ≈ε Algorithmik II R. Rüdiger — 1. März 2007 — 1.7 Probabilistische Algorithmen und Datenstrukturen 22 obiges 1. Beispiel: pA (x) = (x − 2)3 (x − 5)2 (x − 3) pB (x) = (x − 2)3 (x − 5)2 (x − 3) obiges 2. Beispiel: pA (x) = (x − 2)3 (x − 5)2 (x − 3) pB (x) = (x − 2)2 (x − 5)3 (x − 3) q(x) = pA (x) − pB (x) = 3(x − 2)2 (x − 5)2 (x − 3) Frage: pA = pB ? Wähle x ∈R S: Wenn q(x) = 0 ⇒ Wenn q(x) 6= 0 ⇒ sehr wahrscheinlich A ≡ B, ausgenommen eine Nullstelle wurde getroffen mit Sicherheit A 6≡ B Algorithmus zur Feststellung der Gleichheit von Multimengen: CheckArrays(A, B, ε) 1 n ← length[A] precondition: length[A] = length[B] 2 draw random x ∈R S, where S = {1, 2, . . . , dn/εe} 3 a←1 4 b←1 5 for i ← 1 to n 6 do a ← a · (x − A[i]) 7 b ← b · (x − B[i]) 8 if a = b 9 then “A ≡ B” very likely 10 else “A 6≡ B” definitely mittlere Laufzeit = Θ(n) Rechenzeit hängt nicht ab von der Wahl von x ein Problem dabei: Die Variablen im Algorithmus können sehr groß werden. Folgendes ist daher praktisch besser: Man wähle p = Primzahl, p > |S|, A[i], B[i] und führe die Rechnung in Z∗p aus, also alles mod p. Algorithmik II R. Rüdiger — 1. März 2007 — 1.7 Probabilistische Algorithmen und Datenstrukturen 23 eine weitere Verbesserung: |S| relativ klein wählen, z.B. |S| = 2n und die Anzahl t an Wiederholungen statt dessen groß zu machen Erhöhung |S| wirkt linear auf Fehler Erhöhung von t wirkt exponentiell auf Fehler . Fragen: – Ist probabilistischer Algorithmus, der Fehler liefern kann, überhaupt akzeptabel? – Was ist mit dem Fall, dass beide Ergebnisse eines Algorithmus fehlerhaft sein können wie bei Monte Carlo? (Majoritätsvotum) – Wieviele Schritte im Mittel führen bei Las Vegas zum Erfolg? Formel für Las Vegas: 1/(1 − ε) . probabilistische (stochastische) Datenstrukturen Beispiel: Skipliste, dazu siehe Abb. 1.4 1 4 7 20 21 30 36 37 45 60 Abbildung 1.4: Perfekte Skipliste ist eine Struktur in der Art einer sortierten linearen Liste Einfügen eines Blocks mit Zeigern, deren Anzahl zufällig gewählt wird Block mit k Zeigern: Wahrscheinlichkeit (1/2)k (idealisiert) Programmcode dazu: Verteilung für Skip-Liste: DrawValue 1 k←0 2 repeat k ← k + 1 3 draw random x ∈R {0, 1} 4 until x = 0 5 Erzeuge Datenblock mit k Zeigern Algorithmik II R. Rüdiger — 1. März 2007 — 1.8 Pseudozufallszahlen 24 Ziehen einer Zahl aus Verteilung 1 k 2 Erwartungswert: E [ Höhe Block ] = P∞ k=1 k · 2−k = 2 (Begründung!) Regel für Skipliste: Der i-te Zeiger eines Datenblocks für ein Datenelement e zeigt auf dasjenige nachfolgende Datenelement, das als erstes ebenfalls einen i-ten Zeiger besitzt Bemerkung: Skip list: alternative to balanced binary trees, CLRS, p. 301, [251]: Pugh, 1990 Suchen: startet im Anfangsblock und dort mit höchstem vorhandenen Zeiger Analyse mittlere Suchzeit: O(log n) mittlere Höhe: auch O(log n) 1.8 Pseudozufallszahlen [Sch01, S. 70] . sind nicht wirklich zufällig, sondern sehen nur so aus“ ” . lineare Kongruenzmethode (Iteration): zn+1 = (azn + b) mod c (oder auch Polynom oder auch modulare Exponentialfunktion (s. Seite 56) anstelle der linearen Funktion) Problem: a, b, c geschickt wählen, insbesondere c möglichst groß . Schreibweise für Aufruf: RANDOM x IN M , wobei M = {m0 , m1 , . . . , mk−1 } |M | = k anders formuliert: Zufallszahlen nach Schöning: Menge M = {m0 , m1 , . . . , mk−1 } Random(M ) 1 k ← |M | 2 z ← (az + b) mod c 3 j ← z mod k 4 return mj 0≤z<c 0≤j<k Algorithmik II R. Rüdiger — 1. März 2007 — 1.8 Pseudozufallszahlen 25 Voraussetzung: k c, um Periodizität zu vermeiden – setze: x := mj , wobei j = zi mod k, 0 ≤ j ≤ k − 1 – Anzahl der verwendeten Zufallszahlen < Periode – Periode p: kleinste Wert > 0 mit zi = zi+p . bei Pseudozufallszahlen nach Kongruenzmethode: Periode ≤ c . Satz: Bei einem Pseudozufallszahlengenerator nach der Linearen Kongruenzmethode wird die maximale Periodenlänge c genau dann erreicht, wenn – gcd(b, c) = 1 (also teilerfremd) – a mod q = 1 für alle Primfaktoren q von c – a mod 4 = 1, sofern c ein Vielfaches von 4 ist. Beispiel: – c = 2n – a = 2k + 1 mit 2 ≤ k < n – b=1 – Dann folgt nach dem Satz: maximale Periode c Prüfen der Voraussetzungen: gcd(b, c) = gcd(1, 2n ) = 1 a = 2k + 1, 2 ≤ k < 2n : q = 2 : a mod 2 = 1 a mod 4 = 1, da k ≥ 2, c Vielfaches von 4; n ≥ 2 Formel: zn+1 = ((2k + 1)zn + 1) mod 2n , 2≤k<n Vorteil: nur shift-Operationen und Additionen . Alternative: Schieberegister Flop-Flop . χ2 -Test (Laboraufgabe 1) Algorithmik II R. Rüdiger — 1. März 2007 — Kapitel 2 Datenkompression Literatur: [Sch01, S. 249] 2.1 Bemerkungen zur Informationstheorie Informatik-Handbuch, S. 165 Sender (Komprimierer) Empfänger (Dekomprimierer) Modell Codierer Quelle Modell Kanal Decodierer Senke Abbildung 2.1: Informationstheorie - Grundmodell . Datenkompression: gängige Methoden für Texte (weniger geeignet für Bilder) – Huffman-Codierung – Arithmetische Codierung (wird hier nicht behandelt) – Lempel-Ziv-Welch-Algorithmus (LZW-Algorithmus) . weitere Methode: z. B. für Audio-Signale DFT für Bild- und Sprachverarbeitung als Methode der Datenkompression Algorithmik II R. Rüdiger — 1. März 2007 — 2.2 Huffman-Codierung 2.2 27 Huffman-Codierung [Sch01, S. 249] vgl. CLRS, p. 385 . Die Zeichen aus der Quelle kommen typischerweise unterschiedlich häufig vor. daher: Verwendung von Codewörtern unterschiedlicher Länge: – häufige Zeichen (große Wahrscheinlichkeit): kurze Codewörter – seltene Zeichen: lange Codewörter Alphabet Σ = {a1 , a2 , . . . , an }, darauf eine Wahrscheinlichkeitsverteilung p(ai ) . Präfixcode: ist eine Abbildung c : Σ → {0, 1}∗ = Menge aller Wörter (Strings) aus 0en und 1en, so dass kein Codewort c(ai ) Anfangsstück (= Präfix) eines anderen Codewortes a(cj ) ist für i 6= j. Ein Präfixcode ist somit also ein Code variabler Länge. Beispiel zur Abbildung: c(a1 ) = 00110 ∈ {0, 1}∗ . Ein Präfixcode heißt optimal, wenn er die mittlere Codewortlänge n X pi · |c(ai )| i=1 minimiert. . Beispiel: Σ = {a, b, c, d, e, f } Wahrscheinlichkeiten: p(a) = 0.45 p(d) = 0.16 p(b) = 0.13 p(e) = 0.09 p(c) = 0.12 p(f ) = 0.05 Summe = 1 . ein möglicher Präfixcode (stellt sich nachher als optimal heraus): a → 0 b → 101 c → 100 d → 111 e → 1101 f → 1100 Algorithmik II R. Rüdiger — 1. März 2007 — 2.2 Huffman-Codierung 28 . mittlere Codewortlänge: 0.45 | {z · 3} + 0.12 | {z · 3} + 0.09 | {z · 4} = 2.24 | {z · 1} + 0.13 | {z · 3} + 0.16 | {z · 4} + 0.05 a c b e d f . Codebaum, siehe Abb.2.2 0 1 a 1 0 0 1 0 b c 0 1 d 1 e f Abbildung 2.2: Huffman-Kodierung Präfixcode ist eindeutig entzifferbar . Beispiel: 0 |{z} 0 1101 111 |{z} 0 |{z} 0 1100 111 |{z} 0 |{z} 0 |{z} 0 |{z} |{z} |{z} |{z} |{z} a a e d a a f d a a a . Algorithmus nach Huffman: konstruiert einen solchen optimalen Präfixcode . konkreter Ablauf anhand von Beispiel . Sortieren ist nicht erforderlich, statt dessen: Verwendung von Priority Queue . insgesamt Komplexität: O(n log n) . formalisierte Darstellung des Algorithmus: ((Formulierung nach CLRS, p. 388)) Algorithmik II R. Rüdiger — 1. März 2007 — 2.3 Lempel-Ziv-Welch Algorithmus 29 Huffman(Σ) 1 n ← |Σ| 2 Q←Σ 3 for i ← 1 to n − 1 4 do allocate a new node z 5 left[z] ← x ← Extract-Min(Q) 6 right[z] ← y ← Extract-Min(Q) 7 f [z] ← f [x] + f [y] 8 Insert(Q, z) 9 return Extract-Min(Q) Return the root of the tree Σ = set of n characters f [c] = frequency of c ∈ Σ (= p(c)) first: |Σ| leaves min-prio-queue Q 2.3 Lempel-Ziv-Welch Algorithmus [Sch01, S. 260] . Idee: für häufig wiederkehrende Textteile werden Abkürzungen eingeführt . Es wird unterstellt, dass bestimmte Textteile immer wieder auftreten (als implizite Modellannahme) . Algorithmus erzeugt (im Prinzip) in einem Durchlauf die komprimierte Datei und . verwendet dabei adaptiv ein sog. dictionary“ (Wörterbuch) (realisiert z.B. ” als Baum) . das dictionary“ wird zu Beginn mit den Zeichen des betrachteten Alphabets ” Σ initialisiert . in der Praxis: alle Zeichen des ASCII-Codes 0 . . . 255 Beispiel, siehe Abb.2.3: . Algorithmen im Pseudocode.: LZW-Compression Algorithmik II R. Rüdiger — 1. März 2007 — 2.3 Lempel-Ziv-Welch Algorithmus 30 0−a 3−n 5−a 6−s 1−n 2−s 4−a 7−a 8−n Abbildung 2.3: Beispiel zur LZW-Kompression LZW-Compression(s, D) 1 source s, dictionary D 2 initialize dictionary D with characters of alphabet 3 w←ε empty word 4 k ← read first character 5 while k is not terminating character 6 do if wk ∈ D 7 then w ← wk 8 else output code for w 9 add wk to D 10 w←k 11 k ← read next character 12 output w Algorithmik II R. Rüdiger — 1. März 2007 — 2.3 Lempel-Ziv-Welch Algorithmus 31 LZW-Decode(codestream) 1 initialize dictionary with alphabet 2 c ← codestream[0] 3 w ← Find(c, dict) find dictionary entry for c 4 a ← first character in w index 0 5 charstream[0] ← w 6 wold ← w 7 i←1 8 while more code available 9 do c ← codestream[i] 10 w ← Find(c, dict) find dictionary entry for c 11 if w is empty may be empty 12 then w ← wold + a 13 charstream[i] ← w 14 a ← first character in w 15 Add(wold + a, dict) wold and a concatenated 16 wold ← w 17 i←i+1 18 return charstream Algorithmik II R. Rüdiger — 1. März 2007 — Kapitel 3 Polynome und die FFT Literatur: [Sch01, S. 267],[CLRS01, p. 822] 3.1 Operationen mit großen Zahlen [Sch01, S. 267] . Standard- (Schul-) Methode der Multiplikation: Komplexität: Θ(n2 ) . Frage: Ist eine Verbesserung möglich? . Verwendung einer klassischen divide-and-conquer-Methode: . Zerlegung der Faktoren, siehe Abb.3.1 x: 12 x1 34 x0 y: 56 y1 78 y0 Abbildung 3.1: Multiplikation: Zerlegung der Faktoren allgemein: x = x1 bn/2 + x0 , y = y1 bn/2 + y0 b = Basis (10 oder 2) R. Rüdiger Algorithmik II — 1. März 2007 — 3.1 Operationen mit großen Zahlen 33 . ausmultiplizieren: x · y = x1 y1 · bn + (x1 y0 + x0 y1 ) · bn/2 + x0 y0 . jetzt: 4 Multiplikationen von (n/2)-stelligen Zahlen, siehe Abb. 3.2 12 56 x1y1 x bn + 12 78 x1y0 + 34 56 x0y1 x b n/2 34 78 x0y0 + x b0 xy Abbildung 3.2: Multiplikation von (n/2)-stelligen Zahlen . Komplexität T (n) aus T (n) = 4T (n/2) + Θ(n) (4 Multiplikationen von Zahlen der Länge n/2, Θ(n) Additionen) daraus mit Master-Theorem: T (n) = Θ(nlog2 4 ) = Θ(n2 ) nichts gewonnen? . Trick: man schreibe x1 y0 + x0 y1 = x1 y1 + x0 y0 − (x0 − x1 )(y0 − y1 ) daher: 4 durch 3 rekursive Aufrufe ersetzen, siehe Abb. 3.3 . Komplexität ist jetzt: T (n) = 3T (n/2) + Θ(n) Algorithmik II R. Rüdiger — 1. März 2007 — 3.2 Schnelle Matrixmultiplikation nach Strassen 34 x bn x1y1 + x0y0 + x1y1 + (x1−x0 ) (y0−y1 ) + x b n/2 x b0 x0y0 xy Abbildung 3.3: Multiplikation (n/2)-stelliger Zahlen: der Trick . daher: T (n) = Θ(nlog2 3 ) = Θ(n1.6 ) . also: Verbesserung gegenüber der Schulmethode“ ” Das kann verwendet werden bei der Polynommultiplikation, siehe Seite 37. 3.2 Schnelle Matrixmultiplikation nach Strassen [Sch01, S. 269], [CLRS01, p. 735] . Standard-Matrixmultiplikation: cij = n X aik bkj k=1 . Anzahl Einzel-Multiplikationen: n3 Anzahl Einzel-Additionen: n2 (n − 1) i, j: n2 ; k n-mal gibt n3 i, j: n2 ; k (n − 1)-mal gibt n2 (n − 1) . speziell für n = 2: 23 = 8 Multiplikationen 22 · 1 = 4 Additionen Algorithmik II R. Rüdiger — 1. März 2007 — 3.2 Schnelle Matrixmultiplikation nach Strassen 35 . geht auch mit 7 Multiplikationen und 18 Additionen jetzt allgemeine n × n-Matrizen, wobei n = Zweierpotenz . Zerlegung der Matrizen in 2 · (n/2) × 2 · (n/2)-Matrizen gemäß: A11 A12 A21 A22 C11 C12 B11 B12 = · C21 C22 B21 B22 . rekursive Prozedur, Strassen-Algorithmus: Strassen-Multiplication(n, A, B) 1 if n = 1 2 then return (AB) 3 else 4 berechne I, II, . . . , VII, C11 , C12 , C21 , C22 5 dann: 7 rekursive Aufrufe von Strassen-Multiplication(n/2, . . .) C11 C12 6 return C21 C22 im Detail: MatProd(n, A, B) 1 if n = 1 2 then return AB 3 else I ← MatProd(n/2, A12 − A22 , B21 + B22 ) 4 II ← MatProd(n/2, A11 + A22 , B11 + B22 ) 5 III ← MatProd(n/2, A11 − A21 , B11 + B12 ) 6 IV ← MatProd(n/2, A11 + A12 , B22 ) 7 V ← MatProd(n/2, A11 , B12 − B22 ) 8 VI ← MatProd(n/2, A22 , B21 − B11 ) 9 VII ← MatProd(n/2, A21 + A22 , B11 ) 10 C11 ← I + II − IV + VI 11 C12 ← IV + V 12 C21 ← VI + VII 13 C22 ← II − III +V − VII C11 C12 14 return C21 C22 Algorithmik II R. Rüdiger — 1. März 2007 — 3.3 Polynommultiplikation und die FFT 36 . daraus Komplexität: Zu vergleichen ist T (n) = 8T (n/2) + Θ(n2 ) mit T (n) = 7T (n/2) + Θ(n2 ), Ergebnis: T (n) = O(n2.8 ) gegenüber n3 nach der Schulmethode (dazu: Aufgabe) 3.3 Polynommultiplikation und die FFT [Sch01, S. 273] . Aufgabe: Polynome multiplizieren . Standard: A(x) = n−1 X aj x j B(x) = n−1 X j=0 bj x j j=0 . äquivalent als Tupel: (a0 , a1 , . . . , an−1 ) und (b0 , b1 , . . . , bn−1 ) außerdem speziell: n = Zweierpotenz = 2m eventuell mit Nullen auffüllen . Produkt: C(x) = A(x)B(x) = 2n−2 X ci xi 2n − 1 Koeffizienten ci i=0 wobei . ci = X aj bk j,k:j+k=i Diese Operation heißt Faltung. R. Rüdiger Algorithmik II — 1. März 2007 — 3.3 Polynommultiplikation und die FFT 37 . Beispiel: Koeffizientenschema für n = 4: c0 c1 c2 c3 c4 c5 c6 = = = = = = = a0 b0 a0 b1 + a1 b0 a0 b2 + a1 b1 + a2 b0 a0 b3 + a1 b2 + a2 b1 + a3 b0 a1 b3 + a2 b2 + a3 b1 a2 b3 + a3 b2 a3 b 3 . Komplexität: 2n − 1 Koeffizienten bestimmen, für jeden ist eine Faltung zu berechnen: insgesamt: O(n2 ) . effizientere Implementierung (1. Möglichkeit) verwende die Idee schnelle Multiplikation ganzer Zahlen Komplexität: O nlog2 3 = O(nld 3 ) (Details wie bei Zahlen) . ein weiterer Weg (2. Möglichkeit) sog. Punkt-Wert-Darstellung“: Auswertung des Polynoms an Stützstellen, ” Anzahl = 2er-Potenz . bei Auswertung an beliebigen Stellen: kein Effizienzgewinn . aber: Eine Reduktion der Komplexität erreicht man durch die geschickte Ausnutzung der Wahl der Stützstellen . Trick: Anwendung der Diskreten Fouriertransformation (Discrete Fourier Transform, DFT) . Annahme: n =Anzahl der Koeffizienten = Anzahl der Stützstellen . jetzt: wähle als Stützstellen die n-ten Einheitswurzeln im Komplexen = Lösungen der Gleichung xn = 1 . Lösungen sind: xk,n = e wobei ωn = e 2πi ·k n 2πi n = ωn k mit k = 0, 1, 2, . . . , n − 1 . Algorithmik II R. Rüdiger — 1. März 2007 — 3.3 Polynommultiplikation und die FFT 38 . einige Details zu komplexen Zahlen . . . . nachrechnen: xnk,n = 1 für alle k . also: Alle n-ten Einheitswurzeln sind Potenzen von z := x1,n = e2πi/n . außerdem gilt: (xk,n )2 = xk,n/2 für k = 0, 1, 2, . . . , (n/2) − 1 . Definition: Zu gegebenem Koeffizientenvektor a = (a0 , a1 , . . . , an−1 ) (der gegebenenfalls ein Polynom repräsentiert) bezeichnet der Vektor y = (y0 , y1 , . . . , yn−1 ) mit yk = A(xk,n ) n−1 X aj ωn k·j = j=0 die diskrete Fourier-Transformierte (DFT) von a. . Schreibweise: y = DFTn (a) . Die Frage, um die es jetzt geht: Wie kann man Polynome effizient mittels der DFT multiplizieren? zunächst in Form eines Beispiels: A(x) = a0 x0 + a1 x1 + a2 x2 + a3 x3 + a4 x4 + a5 x5 + a6 x6 + a7 x7 n ist Zweierpotenz, hier also n = 8. Aufteilung: Aeven (x) = a0 x0 + a2 x1 + a4 x2 + a6 x3 Aodd (x) = a1 x0 + a3 x1 + a5 x2 + a7 x3 Es gilt dann A(x) = Aeven (x2 ) + x · Aodd (x2 ) = a0 x0 + a2 x2 + a4 x4 + a6 x6 + a1 x1 + a3 x3 + a5 x5 + a7 x7 Algorithmik II R. Rüdiger — 1. März 2007 — 3.3 Polynommultiplikation und die FFT 39 allgemein: (n/2)−1 (n/2)−1 A even (x) = X a2k x k A odd (x) = X a2k+1 xk k=0 k=0 Es gilt dann allgemein: A(x) = Aeven (x2 ) + x · Aodd (x2 ) . zunächst: informelle Beschreibung des Algorithmus FFT Rec-FFT(a) a = (a0 , a1 , . . . , an−1 ) 1 n ← length[a] n is a power of 2 2 if n = 1 3 then return (a0 ) 4 ... 5 y even ← Rec-FFT(aeven ) 6 y odd ← Rec-FFT(aodd ) 7 ... 8 daraus y = (y0 , y1 , . . . , yn−1 ) entsprechend den Formeln 9 return y . dann formal im Detail (in CLRS-Notation, CLRS, p. 835): Recursive-FFT Recursive-FFT((a0 , a1 , . . . , an−1 )) 1 n ← length[a] n is a power of 2 2 if n = 1 3 then return (a0 ) 4 ωn ← e2πi/n 5 ω←1 6 aeven ← (a0 , a2 , . . . , an−2 ) 7 aodd ← (a1 , a3 , . . . , an−1 ) 8 y even ← Recursive-FFT(aeven ) 9 y odd ← Recursive-FFT(aodd ) 10 for k ← 0 to n/2 − 1 11 do yk ← ykeven + ωykodd 12 yk+(n/2) ← ykeven − ωykodd 13 ω ← ωωn 14 return (y0 , y1 , . . . , yn−1 ) Algorithmik II R. Rüdiger — 1. März 2007 — 3.3 Polynommultiplikation und die FFT 40 . Komplexität? Rekursionsgleichung: T (n) = 2T (n/2) + Θ(n) . daraus mit Master-Theorem: T (n) = Θ(n log n) Begründung: m = 2, αi = 12 , k = 1, P2 1 k i=1 αi = 2 · 2 = 1, T (n) = Θ(nk log n) = Θ(n log n) . aber, bezogen auf m mit n = 2m , m = Anzahl der bits: T (m) = Θ(m2m ) . zum Vergleich: Quanten-FT Θ(m2 ), m = Anzahl der qubits . eine mögliche explizite Darstellung der DFT durch die sog. Vandermondesche Matrix: . in Beispielform (n = 4, ω := ω4 = e(2πi)/4 = eiπ/2 = i): 1 1 1 1 y0 a0 y1 1 ω ω 2 ω 3 a1 y2 = 1 ω 2 ω 4 ω 6 a2 y3 a3 1 ω3 ω6 ω9 . Die inverse DFT ist gegeben durch: n−1 n−1 1 X − 2πi j·k 1 X −j·k n ak = · yj e = ωn n j=0 n j=0 verifizieren: Übungsaufgabe . jetzt wieder Polynommultiplikation, Anwendung der DFT: . Theorem (Faltungstheorem): [CLRS01, p. 837] Für zwei Vektoren a und b der Länge n, n = Zweierpotenz, gilt: c = a ⊗ b = DFT−1 2n (DFT2n (a) • DFT2n (b)), | {z } | {z } y y0 wobei die Vektoren a und b bis zur Länge 2n mit Nullen aufgefüllt werden. • bedeutet (hier) das komponentenweise Produkt zweier 2n-elementiger Vektoren. R. Rüdiger Algorithmik II — 1. März 2007 — 3.3 Polynommultiplikation und die FFT 41 CLRS, p. 841: Iterative-FFT Iterative-FFT(a) 1 Bit-Reverse-Copy(a, A) 2 n ← length[a] n is a power of 2 3 for s ← 1 to lg n 4 do m ← 2s 5 ωm ← e2πi/m 6 for k ← 0 to n − 1 by m 7 do ω ← 1 8 for j ← 0 to m/2 − 1 9 do t ← ωA[k + j + m/2] 10 u ← A[k + j] 11 A[k + j] ← u + t 12 A[k + j + m/2] ← u − t 13 ω ← ωωm 14 return A 15 (see CLRS, p. 841) CLRS, p. 842: Bit-Reverse-Copy Bit-Reverse-Copy(a, A) 1 n ← length[a] 2 for k ← 0 to n − 1 3 do A[rev(k)] ← ak 4 (see CLRS, p. 842) Algorithmik II R. Rüdiger — 1. März 2007 — Kapitel 4 Algorithmen für die Kryptologie Literatur: [CLRS01, p. 849], [Wä04] 4.1 Grundkonzepte der Kryptologie Bestandteile eines Kryptosystems. Begriffe . Kryptologie: Untersuchung von Systemen für die geheime Kommunikation Kryptographie: Entwicklung solcher Systeme Kryptoanalyse: Untersuchung von Methoden für die Entschlüsselung . Kryptosystem: Ver- und Entschlüsselungssystem . Absender sendet Botschaft (Klartext) an Empfänger . Die geheime Form heißt Chiffretext. . kryptographischer Algorithmus: Ver-/Entschlüsselungsmethode: hängt ab von Schlüsselparametern . Es wird unterstellt: 1. Der Chiffretext geht über unsichere Verbindungskanäle. 2. Die Methoden der Ver-/Entschlüsselung, d.h. also die Algorithmen, sind dem Kryptoanalytiker bekannt. . sein Ziel: Wiedergewinnung des Klartextes aus dem Chiffretext ohne Kenntnis der Schlüsselparameter. Algorithmik II R. Rüdiger — 1. März 2007 — 4.1 Grundkonzepte der Kryptologie 43 . Absender/Empfänger: in aller Regel ist eine vorausgehende separate Kommunikationsmöglichkeit zur Vereinbarung der Schlüsselparameter erforderlich. . Kostenaufwand ist wichtig . 2 Arten: 1. symmetrische Chiffre: oder Ein-Schlüssel-Kryptosystem Schlüssel sind gleich oder leicht auseinander berechenbar 2. asymmetrische Chiffre: Zwei-Schlüssel-Kryptosystem Chiffrier- und Dechiffrierschlüssel sind verschieden und praktisch nicht auseinander berechenbar . Formalisierung (also ein mathematisches Modell): Ein kryptographisches System besteht aus 5 Komponenten (M, C, K, EK , DK ): (E = encrypt, D = decrypt) 1. Klartextraum M 2. Chiffretextraum C 3. Schlüsselraum K 4. einer Familie von Chiffriertransformationen EK : M → C mit K ∈ K 5. einer Familie von Dechiffriertransformationen DK : C → M mit K ∈ K Es soll gelten: DK (EK (M )) = M oder DK ◦ EK = id Algorithmik II R. Rüdiger — 1. März 2007 — 4.1 Grundkonzepte der Kryptologie 44 Klassische (historische) Verfahren 1. Cäsar-Chiffre Die Idee: der N -te Buchstabe im Alphabet wird durch den (N + k)-ten Buchstaben ersetzt. bei Cäsar: k = 3 Beispiel (k = 1): A B T U T A U B C K D L A A B T U A D E A B W X N O 2. Verbesserung: allgemeine Tabelle einfache Substitution (THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG) THEQU I CKBROWN FXJMPSVLA Z YDG ABCDEFGH I J K L MNOPQRSTUVWXYZ Idee: Jeder Buchstabe des Alphabets kommt mindestens einmal vor. Problem: ist leicht entschlüsselbar über (bekannte) Häufigkeit von Buchstaben 3. Vignère-Chiffre: entspricht Cäsar-Chiffre mit variablem k Bsp.: A B C A B C A B C A B C A B C A T T A C K A T D A W N (definiert das k) daraus: 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 A B C A B C A B C A B C A B C A T T A C K A T D A W N ----------------------------B V W B E N A C W A F D X P (entspricht variablem k) (Schluessel) (Klartext) (Chiffretext) k wird jedesmal neu bestimmt. 4. Vernam-Chiffre: one-time pad Der Schlüssel muß mindestens ebenso lang sein wie der Klartext. Das ist das einzige nachweisbar sichere Verfahren (sicher heißt hier: nur durch brute force“ zu knacken). ” Algorithmik II R. Rüdiger — 1. März 2007 — 4.1 Grundkonzepte der Kryptologie 45 Verschlüsselung mit xor xor-Verknüpfung von Chiffre und Klartext liefert den Schlüssel (Übungsaufgabe), daher: Schlüssel darf nur einmal verwendet werden (“one-time pad”) Anforderungen an public-key-System (Diffie und Hellman, 1976) . E = encryption, D = decryption . öffentliches Schlüssel-System (public-key) (Martin Aigner: Diskrete Mathematik, Vieweg, 1993): . Benutzer hat 1. einen öffentlichen Schlüssel P (public) und 2. einen geheimen Schlüssel S (secret). . ebenso öffentlich: die verwendete Codierung E, ebenso Decodierung D . Nachricht M , die Bob an Alice senden will . es soll gelten: D(E(M, PA ), SA ) = M . C = E(M, PA ) . Decodierung mittels: D(E(M, PA ), SA ) = M , also D(C, SA ) = M . Bedingungen: (A) Aus M und P ist die Berechnung von C = E(M, P ) leicht“ durch” zuführen. (B) Gegeben das Kryptogramm C, dann ist die Decodierung D(C) ohne die Kenntnis von S schwer“. ” (C) Gegeben das Kryptogramm C und der Schlüssel S, dann ist die Berechnung von D(C, S) leicht“. ” Bedingungen (A) und (B): Codierung ist eine sog. Einwegfunktion. Eine Einwegfunktion, die zusätzlich auch (C) erfüllt (also eine effiziente Invertierung bei Kenntnis des geheimen Schlüssels ermöglicht) heißt eine TrapdoorFunktion. . ein Trapdoor-System: RSA-System (von Rivest, Shamir, Adleman) Algorithmik II R. Rüdiger — 1. März 2007 — 4.2 RSA-Verfahren: Übersicht und Zahlenbeispiel 4.2 46 RSA-Verfahren: Übersicht und Zahlenbeispiel . zur Notation (z. B.: Graham, Knuth, Patashnik, p. 123): a mod m = b mod m wird geschrieben als a ≡ b (mod m) Sprechweise: “a ist kongruent zu b modulo m.” . Beispiele: → 17 ≡ 1 (mod 8), denn: 17 = 2 · 8 + 1 bzw. 17 − 1 = k · 8 → 9 ≡ −16 (mod 5), denn 9 mod 5 = 4 und (−16) mod 5 = (−20 + 4) mod 5 = 4 . In jedem Fall (d.h. für x, y ∈ R) gilt: x − bx/ycy für y 6= 0 x mod y := x für y = 0 (Für y = 0 ist das eine mögliche Definiton, s. Graham, Knuth, Patashnik, p. 82.) daraus: 0 ≤ x mod y < y für y > 0 (y < x mod y ≤ 0 für y < 0) (hier nicht wichtig) . oder: a ≡ b (mod m) bedeutet: a − b ist Vielfaches von m (ist häufig einfacher zu handhaben) z.B.: 9 ≡ −16 (mod 5): 9 − (−16) = 25 = 5 · 5 . ≡ ist eine Äquivalenzrelation . einige Rechenregeln (Graham, Knuth, Patashnik, p. 82): a ≡ b und c ≡ d a ≡ b und c ≡ d a ≡ b und c ≡ d a≡b =⇒ =⇒ =⇒ =⇒ a + c ≡ b + d (mod m) a − c ≡ b − d (mod m) ac ≡ bd (mod m) an ≡ bn (mod m), n ≥ 0 Literatur: Wätjen, S. 71: Schlüsselerzeugung für das RSA-Public-Key Kryptosystem Alice erzeugt für sich einen öffentlichen Schlüssel P und einen zugehörigen privaten Schlüssel S Algorithmik II R. Rüdiger — 1. März 2007 — 4.2 RSA-Verfahren: Übersicht und Zahlenbeispiel 47 . [(1)] Alice erzeugt zwei (große) Primzahlen p und q ungefähr gleicher Länge . [(2)] Alice berechnet n = pq sowie ϕ(n) = (p − 1)(q − 1) (Eulersche phi-Funktion) . [(3)] Alice wählt eine Zahl e, 1 < e < ϕ(n) mit gcd(e, ϕ(n)) = 1 (e teilerfremd (oder “relativ prim”) zu ϕ(n)) also e ∈ Z∗ϕ(n) , e > 1 Bemerkung: Berechnung von gcd geht effizient . [(4)] Alice berechnet d = e−1 mod ϕ(n), d. h. ed mod ϕ(n) = 1 e−1 =?? . [(5)] Der öffentliche Schlüssel von Alice ist PA = (n, e), der private SA = d (oder (n, d)). RSA-Public-Key-Verschlüsselung Bob chiffriert eine Nachricht M für Alice, die diese dechiffriert. (1) Zur Chiffrierung führt Bob folgende Schritte aus: (a) Bob besorgt sich den authentischen öffentlichen Schlüssel PA = (n, e) von Alice. (b) Bob stellt M als Zahl in Zn dar. (c) Bob berechnet C = M e mod n (d) Bob übermittelt EA (M ) = C an Alice. (2) Dechiffrierung durch Alice. Alice berechnet M = DA (C) = C d mod n. ((n, d) ist geheim.) also: M = (M e mod n)d mod n = M ed mod n . Ein Zahlen-Beispiel zum RSA-Verfahren (vgl. Informatik-Duden, S. 313) 1. Alice führt folgende Schritte aus: – Sie wählt zwei Primzahlen p = 47 und q = 59. – Sie berechnet ihren öffentlichen Schlüssel (n, e) mit n = pq = 2773 und e = 17 (wegen gcd(17, 2668) = 1)). R. Rüdiger Algorithmik II — 1. März 2007 — 4.3 Begriffe zum Verständnis des RSA-Verfahrens 48 – Sie berechnet ihren privaten Schlüssel d mittels der Eulerfunktion ϕ(n) = (p − 1)(q − 1) entsprechend ed mod ϕ(n) = 1: ed = 2669 ≡ 1 (mod 2668), also d = e−1 mod φ(n). Das Ergebnis ist: d = 157 – Damit liegt die Verschlüsselungsfunktion E = M e mod n fest, auszuführen von Bob – und ebenso die Entschlüsselungsfunktion D = C d mod n, auszuführen von Alice. 2. Bob führt folgende Schritte aus: . Der zu verschlüsselnde Text wird in Zahlen umgewandelt: . Z.B. wird das Wort STALL in Buchstaben umgesetzt gemäß dem Schema: blank → 00 A → 01 B → 02 C → 03 ... . Aus STALL“ wird damit 19 20 01 12 12. ” . Die Blockgröße i wird so gewählt, dass 10i−1 < n < 10i , d.h. für M gilt dann M ∈ Zn , in diesem Fall also i = dlog10 ne = 4 . Das Ergebnis ist: 1920 0112 1200 . Anwendung der Verschlüsselungsfunktion E (mit dem öffentlichen Schlüssel (n, e) von Alice) C ≡ M e (mod n) 2109 ≡ 192017 (mod 2773) 1084 ≡ 011217 (mod 2773) 1444 ≡ 120017 (mod 2773) . Alice entschlüsselt den verschlüsselten Text von Bob. Der Text ist: 2109 1084 1444. M ≡ C d (mod n) 1920 ≡ 2109157 (mod 2773) 0112 ≡ 1084157 (mod 2773) 1200 ≡ 1444157 (mod 2773) Sie braucht dazu also den privaten Schlüssel (n, d) = (2773, 157) 4.3 Begriffe zum Verständnis des RSA-Verfahrens . Wie wählt man große Primzahlen aus? Algorithmus dafür? R. Rüdiger Algorithmik II — 1. März 2007 — 4.4 Grundlagen 49 Die Java-API stellt in BigInteger dazu Methoden bereit. . Berechnung von e? und von d? . M ∈ Zn : Definition von Zn . Berechnung des modularen Inversen d = e−1 mod ϕ(n) auch: Berlekamp-Algorithmus . schnelle modulare Exponentiation . Definition von Z∗n . Definition der Eulerschen ϕ-Funktion ϕ(n) = |Z∗n | 4.4 Grundlagen [CLRS01, p. 850] . Schreibweise d | a: d teilt a, d.h. a = kd, k ∈ Z z. B.: 3 | 15, denn 15 = 3 · 5 7 | 49, x | 0, denn 0 = k · x für k ∈ Z, nämlich k = 0 5 6 | 11 . Primzahl (prime number): eine ganze Zahl a > 1, deren einzige Teiler die trivialen Teiler 1 und a sind zusammengesetzte Zahl (composite number): Zahl, die keine Primzahl ist . Divisionstheorem: Zu jeder Zahl a ∈ Z und zu jeder Zahl n ∈ Z mit n > 0 gibt es eindeutige ganze Zahlen q und r, so dass 0 ≤ r < n und a = qn + r. (0 ≤ r < n ist entscheidend) explizit: a = b na c · n + a mod n z.B.: 37 = 37 · 5 + 37 mod 5 5 . in Java (für a, n vom Typ long / int): R. Rüdiger Algorithmik II — 1. März 2007 — 4.4 Grundlagen 50 → q = a / n → r = a % n . a ∈ [b]n bedeutet: a ≡ b (mod n) Beispiel: [3]7 = {. . . , −11, −4, 3, 10, 17, . . .}: 3 ist Repräsentant der Menge [3]7 also [3]7 = {a | a ≡ 3 (mod 7)} = {a | a − 3 = k · 7, k ∈ Z} . Zn = {[a]n | 0 ≤ a ≤ n − 1} . übliche Notation: Zn = {0, 1, . . . , n − 1} . weitere Definition: Z∗n = {1, 2, . . . , n − 1 | gcd(a, n) = 1} . Zusammenhang mit Eulerscher-ϕ-Funktion: ϕ(n) = |Z∗n | . größter gemeinsamer Teiler zweier Zahlen a und b, nicht beide = 0: gcd(a, b) (greatest common divisor) . z.B.: gcd(24, 30) = 6, gcd(5, 7) = 1, gcd(0, 9) = 9 24 = 4 · 6 30 = 5 · 6 5 = 5·1 7 = 7·1 0 = 0·9 9 = 1·9 . allgemein gilt: Wenn a 6= 0 ∧ b 6= 0: 1 ≤ gcd(a, b) ≤ min(|a|, |b|) . Regeln: gcd(a, b) gcd(a, b) gcd(a, b) gcd(a, 0) gcd(a, ka) gcd(0, 0) = = = = = = gcd(b, a) gcd(−a, b) gcd(|a|, |b|) |a| |a| für alle k ∈ Z 0 (als Konvention) a = ±|a| R. Rüdiger Algorithmik II — 1. März 2007 — 4.5 Größter gemeinsamer Teiler. Algorithmen 51 . Theorem: Wenn a und b ganze Zahlen sind, nicht beide = 0, dann ist gcd(a, b) das kleinste positive Element der Menge {ax + by | x, y ∈ Z} von Linearkombinationen von a und b. . Zwei ganze Zahlen heißen relativ prim = teilerfremd = co-prim, wenn gcd(a, b) = 1. . Theorem Eindeutige Faktorisierung: Eine zusammengesetze Zahl a kann eindeutig geschrieben werden in der Form a = pe11 pe22 · · · perr , wobei die pi Primzahlen sind mit p1 < p2 < · · · < pr und die ei positive ganze Zahlen, also ei ≥ 1. 4.5 Größter gemeinsamer Teiler. Algorithmen [CLRS01, p. 856] [Sch01, S. 285] [Sch01, S. 286] (gcd = greatest common divisor) • gcd rekursiv berechnen mit gcd-Rekursions-Theorem: a für b = 0 gcd(a, b) = gcd(b, a mod b) für b 6= 0 . Reihenfolge der Argumente? (Muss das größere Element links stehen?) z. B.: gcd(10, 25) = gcd(25, 10 mod 25) = gcd(25, 10) = ... . daraus: Euklidscher Algorithmus: hier: a, b ≥ 0 Euclid(a, b) 1 if b = 0 2 then return a 3 else return Euclid(b, a mod b) R. Rüdiger Algorithmik II — 1. März 2007 — 4.5 Größter gemeinsamer Teiler. Algorithmen 52 Bitkomplexität: O(n3 ) . Algorithmus von Stein: auch binärer gcd-Algorithmus genannt ist ein Algorithmus zur Berechnung des gcd nur mit binären Operationen beruht auf den folgenden 4 Tatsachen über ganze Zahlen (a, b > 0): 1. gcd(a, b) = 2 gcd(a/2, b/2) falls a, b gerade 2. gcd(a, b) = gcd(a/2, b) falls a gerade, b ungerade 3. gcd(a, b) = gcd(a − b, b) falls a ≥ b 4. außerdem a, b ungerade ⇒ a − b gerade und |a − b| < max(a, b). . Formulierung in CLRS-Notation BinGCD(a, b) 1 k←1 2 while a is even and b is even 3 do a ← a/2 4 b ← b/2 5 k ← 2k 6 while a > 0 7 do if a is even 8 then a ← a/2 9 else if b is even 10 then b ← b/2 11 else t ← |a − b|/2 12 if a < b 13 then b ← t 14 else a ← t 15 return kb (Java-Formulierung in Klausur): Implementierung (die Klausurvariante, WS 03/04, Aufgabe 2, mit Ausgabeanweisungen): 1 2 3 4 5 ... public static long NN (long a, long b) { long p = 0, t; R. Rüdiger Algorithmik II — 1. März 2007 — 4.5 Größter gemeinsamer Teiler. Algorithmen while ((a & 1) == 0 && (b & 1) == 0) { a >>= 1; b >>= 1; p++; } while (a > 0) { if ((a & 1) == 0) a >>= 1; else if ((b & 1) == 0) b >>= 1; else { t = ((a > b) ? (a − b) : (b − a)) >> 1; if (a < b) b = t; else a = t; } System.out.println(a + ”\t” + b); } /* Ende von while aus Zeile 9 */ return b << p; 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 53 } ... • Euklidscher Algorithmus in erweiterter Form: Satz: Es gilt gcd(a, b) = min ({ax + by | x, y ∈ Z} ∩ N+ ) Algorithmus, um diese Darstellung zu erhalten: Extended-Euclid(a, b) 1 if b = 0 2 then return (a, 1, 0) 0 3 (d , x0 , y 0 ) ← Extended-Euclid(b, a mod b) 4 (d, x, y) ← (d0 , y 0 , x0 − ba/bc · y 0 ) 5 return (d, x, y) Rückgabe von Tripel, Implementierung! . Beispiel: gcd(21, 30) = 3 · 21 + (−2) · 30 = 3 allgemein: gcd(a, b) = d = x · a + y · b . Was kann man damit machen? u.a.: modulares Inverses effizient berechnen. (erforderlich für RSA-Verfahren) R. Rüdiger Algorithmik II — 1. März 2007 — 4.5 Größter gemeinsamer Teiler. Algorithmen 54 . oder auch mit Algorithmus von Berlekamp als Spezialfall Berlekamp(a, b) 1 Vorbedingung: gcd(a, b) = 1 2 berechnet x aus ax ≡ 1 (mod b) 3 r0 ← a 4 r1 ← b 5 q0 ← 1 6 q1 ← 0 7 while r0 > 0 and r1 > 0 8 do u ← br0 /r1 c 9 r0 ← r0 mod r1 10 q0 ← q0 + uq1 11 if r0 > 0 12 then u ← br1 /r0 c 13 r1 ← r1 mod r0 14 q1 ← q1 + uq0 15 if r0 = 0 16 then return −q1 17 else return q0 Beispiele: (1) 7x ≡ 1 (2) 9x ≡ 1 (3) 11x ≡ 1 (mod 11) (mod 13) (mod 17) x ≡ 8 (mod 11) x ≡ 3 (mod 13) x ≡ 14 (mod 17) (1) (2) (3) . Definitionen vorweg: – Def.: Z∗n = {a ∈ {1, . . . , n − 1} | gcd(a, n) = 1} – Beispiel: Z∗15 = {1, 2, 4, 7, 8, 11, 13, 14} – konkret ausschreiben: erst alle Werte aufschreiben, dann die a’s mit gcd(a, n) = gcd(a, 15) > 1 ausstreichen – Tafel zum Rechnen mit R. Rüdiger Algorithmik II — 1. März 2007 — 4.5 Größter gemeinsamer Teiler. Algorithmen 55 ∗ Zn (Menge der Restklassen, Restklassengruppe modulo n, additive Gruppe modulo n) ∗ und Z∗n (reduzierte Menge der Reste modulo n, multiplikative Gruppe modulo n) Beispiel, Uhrenrechner“ von Gauß (in Übungen nachvollziehen): ” +6 0 1 2 3 4 5 ·15 1 2 4 7 8 11 13 14 Gruppe 0 1 0 1 1 2 2 3 3 4 4 5 5 0 (Z6 , +6 ) 2 3 4 2 3 4 3 4 5 4 5 0 5 0 1 0 1 2 1 2 3 5 5 0 1 2 3 4 Gruppe (Z∗15 , ·15 ) 1 2 4 7 8 11 1 2 4 7 8 11 2 4 8 14 1 7 4 8 1 13 2 14 7 14 13 4 11 2 8 1 2 11 4 13 11 7 14 2 13 1 13 11 7 1 14 8 14 13 11 8 7 4 13 13 11 7 1 14 8 4 2 14 14 13 11 8 7 4 2 1 In dieser Menge kann man auch Divisionen ausführen. . Berechnen des modularen Inversen im Detail: – wähle a ∈ Z∗n , also gcd(a, n) = 1 – aus Extended-Euclid Algorithmus: gcd(a, n) = d = 1 = ax + ny d. h. ax − 1 = −yn, also: Differenz ist Vielfaches von n – also ax ≡ 1 (mod n) oder: a · x ergibt einen Wert der Art “(Vielfaches von n) + 1” R. Rüdiger Algorithmik II — 1. März 2007 — 4.6 Modulare Exponentiation 4.6 56 Modulare Exponentiation . iterative Variante: ((CLRS, p. 879)) Modular-Exponentiation(a, b, n) 1 berechnet ab mod n 2 d←1 3 let hbk , bk−1 , . . . , b0 i be the binary representation of b 4 for i ← k downto 0 5 do d ← (d · d) mod n 6 if bi = 1 7 then d ← (d · a) mod n 8 return d 4.7 Primzahltesten . Satz von Euler: Für alle n ≥ 2 und für alle a ∈ Z∗n (also gcd(a, n) = 1) gilt: aϕ(n) ≡ 1 (mod n) zur Erinnerung: ϕ(n) = n Y p|n 1 1− p andere Schreibweise: ∗ a|Zn | ≡ 1 (mod n) für alle a ∈ Z∗n . durch spezielle Wahl von n als Primzahl: (Kleiner) Satz von Fermat: Für alle Primzahlen n und a ∈ {1, . . . , n − 1} = Z∗n gilt an−1 ≡ 1 (mod n) denn für Primzahlen: ϕ(n) = n − 1 . bildet den Fermat-Test: Primzahlen erfüllen diese Gleichung. R. Rüdiger Algorithmik II — 1. März 2007 — 4.7 Primzahltesten 57 . Anwendung: Speziell für Primzahlen n ist damit eine vereinfachte Berechnung des modularen Inversen a−1 für a ∈ Z∗n möglich: Man berechne einfach: a−1 := an−2 mod n Begründung: Einsetzen: aa−1 ≡ aan−2 ≡ an−1 ≡ 1 (mod n) . Umkehrung gilt nicht: aus an−1 ≡ 1 (mod n) folgt nicht, dass n eine Primzahl ist. Es gilt aber fast“, d.h. es gibt nur wenige Ausnahmen ” Algorithmus, Test für a = 2: Pseudoprime(n) 1 2n−1 6≡ 1 (mod n) 2 if Mod-Exp(2, n − 1, n) 6≡ 1 (mod n) 3 then return Composite Definitely no prime 4 else return Prime We hope! (Monte-Carlo mit einseitigem Fehler) . Verbesserung: nicht nur für a = 2 testen, sondern auch a = 3, . . . . aber: Für alle a mit gcd(a, n) = 1 gibt es Zahlen, die den Fermat-Test an−1 ≡ 1 (mod n) bestehen, ohne Primzahlen zu sein: die sog. Carmichael-Zahlen. . Diese sind aber sehr selten. (Es gibt aber unendlich viele, wurde 1994 gezeigt) . Daraus weitere Verbesserungen: Test nach – Miller-Rabin – Lucas-Lehmer Beruhen auf weiteren Eigenschaften von Primzahlen. Diese werden verwendet in Java-API in BigInteger. R. Rüdiger Algorithmik II — 1. März 2007 —