05 (Fri May 5 06:12:38 2006), p. 1 Übungen zur Vorlesung “Informatik A” SS 2006 Prof. Dr. Ulf Rehmann, Fakultät für Mathematik Übungsblatt 5 Ein Beispiel für die Bestimmung mittlerer Laufzeiten: Algorithmus M: Finde Maximum: Gegeben n ∈ N, x0 , . . . , xn−1 ∈ Z. Zu finden: m, j mit m = xj = max{xi |i = 0, . . . , n − 1}, j maximal. Ausführungsanzahl M 1 [Initialisieren] j ←− 0, i ←− 1, m ←− x0 1 M 2 [Ende ?] falls i == n: Ausgabe j, m, Ende. n M 3 [Vergleiche] falls m > xi , gehe nach M 5 (sonst M 4) n−1 M 4 [Ändere m, j] j ←− i, m ←− xi A = A(x0 , . . . , xn−1 ) M 5 [Inkremetiere i] i ←− i + 1, gehe nach M 2. n−1 Klar: 0 ≤ A(x0 , . . . , xn−1 ) ≤ n − 1. Also: Laufzeit des Programms ist abhängig von der Folge xi . Der Laufzeit-Beitrag von Schritt M4 liegt zwischen 0 und (n − 1) · constant. Programm: #include <iostream.h> int x[] = {3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3}; main() { int j=0, i=1, m=x[0]; // M1 while( i < sizeof(x)/sizeof(x[0]) ) { // M2 if (m <= x[i]) { // M3 j = i; m = x[i]; // M4 } i++; // M5 } cout << "j = " << j << ", m = " << m << "\n"; } M 4 werde k mal durchlaufen: k := A(x) = A(x0 , . . . , xn−1 ). Diese Zahl hängt nur von der Permutation ab, mit der man die Folge x = (xi ) in lineare Ordnung bringt: Vereinfachende Annahmen: Die xi sind paarweise verschieden. Alle n! Permutationen der xi sind gleich wahrscheinlich. (∗) Bestimmung von An für n ≤ 3: letztes Max: Anordnung: k := A(x) Permutation n == 1: x0 x0 0 id n == 2: x0 x1 x0 > x1 x1 > x0 0 1 id (01) n == 3: x0 x0 x1 x1 x2 x2 x0 x0 x1 x1 x2 x2 0 0 1 1 1 2 id (12) (01) (021) (012) (02) > x1 > x2 > x0 > x2 > x0 > x1 > x2 > x1 > x2 > x0 > x1 > x0 Sei pnk die Wahrscheinlichkeit, daß A(x) = k, also pnk := Anzahl der Permutationen der (xi ) mit A(x) = k Anzahl aller Permutationen : n! (1) 05 (Fri May 5 06:12:38 2006), p. 2 Für die Beispiele n ≤ 3 gilt also p10 = 1, p20 = p21 = 1 1 = , 2! 2 1 3 1 1 1 2 = , p31 = = , p32 = = . 3! 3 3! 2 3! 6 Es ist sinnvoll, pnk = 0 für k < 0 und k ≥ n zu setzen, so daß p für alle k ∈ Z definiert ist. nk X Dann gilt: p1k = 1 für k = 0, p1k = 0 für k 6= 0, und pnk = 1 für jedes n ∈ N. p30 = (2) k P Folgen von nicht-negativen Zahlen (αk )k mit der Eigenschaft k αk = 1 heißen ”Wahrscheinlichkeitsverteilung”. Rekursionsformeln für pnk : Es gilt für n ≥ 2: ½ A(x0 , . . . , xn−2 ) falls xn−1 6= max {x0 , . . . , xn−1 } A(x) = A(x0 , . . . , xn−1 ) = A(x0 , . . . , xn−2 ) + 1 falls xn−1 = max {x0 , . . . , xn−1 } aller Fälle. Hier wird die Annahme Die zweite Beziehung gilt in n1 aller Fälle, also die erste in n−1 n ausgenutzt, dass jede Permutation der xi gleich wahrscheinlich ist. Somit haben wir für k = 0, . . . , n − 1: n pnk = #{Perms von (xi ) mit A(xi ) = k}/(n − 1)! = (n − 1)#{Perms von (x0 , . . . , xn−2 ) mit A(x0 , . . . , xn−2 ) = k} /(n − 1)! + #{Perms von (x0 , . . . , xn−2 ) mit A(x0 , . . . , xn−2 ) = k − 1}/(n − 1)! folglich: pnk = ½ 1 n−1 n pn−1,k falls n = 1 (also k = 0), falls n > 1 + n1 pn−1,k−1 Der Mittelwert für A(x) als Maß für eine mittlere Laufzeit (unter der angegebenen Annahme (∗)) ist gegeben durch X X 1 X 1 X An := k 1= A(x) = k pnk n! n! Perms{x} k Perms{x} k A(x)=k Wir haben also A2 = p21 = 1/2 und für n > 2: An = X k n−1X k pn−1,k + n k n−1X k pn−1,k + = n k pnk = k 1X k pn−1,k−1 n k 1X (k + 1) pn−1,k n (k + 1 ←− k) k n = k pn−1,k + P k pn−1,k = An−1 , k die vorletzte Gleichung folgt wegen Es gilt X1 1X 1 pn−1,k = An−1 + = n n ν=2 ν X k k log(n + 1) − log 2 = Z 1 n P k n pn−1,k = 1. X1 dx ≤ An = ≤ x+1 ν ν=2 Z 1 n dx = log n x (∗) (∗∗) (Beweis: Man interpretiere (An )n≥2 als Treppenfunktion: Obersumme für linkes, Untersumme für rechtes Integral), daher ist An = O(log n). Aufgabe 5.1: i) Schreiben Sie Programme, die die Größen pnk und An berechnen. (4) ii) Falls Sie An über die harmonische Reihe berechnen, ist das Resultat abhängig davon, ob Sie die Summation der Reihe mit aufsteigendem oder absteigendem ν berechnen. Erklären Sie dies Phänomen möglichst genau. Welches der beiden Ergebnisse halten Sie für glaubwürdiger? (8) Hinweis: Erinnern Sie sich an Aufgabe 4.2. 05 (Fri May 5 06:12:38 2006), p. 3 Varianz und Standardabweichung Wir setzen X 1 X 1 X (k − An )2 n! pnk = (k − An )2 pnk (A(x) − An )2 = n! n! k k Perms{x} X X X X = k 2 pnk − 2An kpnk + A2n pnk = k 2 pnk − A2n Vn : = k k k Vn = X n−1X 2 k pn−1,k + n k n−1X 2 = k pn−1,k + n k 2 pnk − A2n = k k 1 4 = wegen (2). k p Vn heißen Varianz und Standard-Abweichung Die Größen Vn und σn := “Wahrscheinlichkeitsverteilung” (pnk )k . Weiter findet man V2 = (0 − 21 )2 12 + (1 − 12 )2 12 = wegen (1) 1 2 − 1 22 (auch: Streuung) der und für n > 2: ³ 1X 2 1 ´2 (k + 1 ←− k) k pn−1,k−1 − An−1 + n n k ³ 1´ 1X 2 2 (k + 2k + 1)pn−1,k − A2n−1 + An−1 + 2 n n n k n = X k 2 pn−1,k − A2n−1 + k Weil P 1 ν2 X³1 1 1 1 1´ 1 − 2 = Vn−1 + − 2 = − 2 n n n n ν ν ν=2 konvergiert, ist wegen (∗∗) auch Vn = O(log n). Die Bedeutung von Vn , σn kann beschrieben werden durch folgendes Lemma: Lemma (Chebyshev-Ungleichung). Sei K ∈ R, K > 0, d := K/σn . Für die Wahrscheinlichkeit von |A(x)−An | > dσn , also |A(x)−An | > K, gilt die Abschätzung p := X |k−An |>dσn pnk < 1 d2 also : p := X pnk < |k−An |>K Vn . K2 Ist also z. B. σn = 2 und d = 10, so ist |A(x) − An | > 20 in weniger als 1 % = 1012 aller Fälle. Beweis des Lemmas: X X X Vn = (k − An )2 pnk ≥ (k − An )2 pnk > K 2 pnk = K 2 p k 2 |k−An |>K |k−An |>K 2 Division durch d Vn = K liefert die Behauptung. Das Programm beispiel.cc rechnet aus, nach wieviel Elementen man nur noch mit 1 % Wahrscheinlichkeit damit rechnen muß, noch einmal ein größeres Element zu sehen. Z. B. ist A1000 = 6.48547 . . . und σ1000 = 2.41693, also nach dem Lemma: A(x) ≥ A1000 + 10 σ1000 , d.h. A(x) ≥ 31 in weniger als 1 % der Fälle. 05 (Fri May 5 06:12:38 2006), p. 4 Quicksort: Quicksort ”präsortiert” die Datenmenge L = {v0 , . . . , vn−1 }, indem nach willkürlicher Auswahl eines Elementes, z. B. v0 , L zerlegt wird: L = L0 ∪ {v0 } ∪ L1 , mit L0 := {vi ∈ L|vi < v0 } und L1 := {vi ∈ L|vi ≥ v0 , i 6= 0} Rekursiv wird dann mit L0 und L1 ebenso verfahren. template <class T> // Laufzeit T n void quicksort(T v[], int n) { if( n<=1 ) return; // c int k = 0; // c 0 for (int i = 1; i < n; i++) if (v[0] > v[i]) // (n-1)c 1 swap(v[++k], v[i]); swap(v[0],v[k]); // c 0 quicksort(v, k); // T k quicksort(v+k+1, n-k-1); // T n-k-1 } Abschätzung der mittleren Laufzeit Tn : Annahme: Die Wahrscheinlichkeit dafür, daß k Elemente < v[0] sind, beträgt n1 . Dies ist z. B. dann der Fall, wenn jede Permutation der zu sortierenden Daten mit gleicher Wahrscheinlichkeit auftritt. Wir wählen c2 := 2(c0 + c1 + 4c). Es soll für alle n ∈ N mit n ≥ 2 gezeigt werden: Tn ≤ c2 n log n, also Tn = O(n log n). Induktionsanfang: Für n = 2: T2 ≤ c0 + c1 + 2c ≤ c2 ≤ c2 2 log 2 Induktionsvoraussetzung: Tk ≤ c2 k log k für k < n. Für n ≥ 2 gilt: Tn ≤ c0 + (n − 1)c1 + n−1 1X (Tk + Tn−k−1 ) n wegen (A) k=0 = c0 + (n − 1)c1 + n−1 n−1 1X 1X 4 2 Tk = c0 + (n − 1)c1 + c + 2 Tk n n n k=0 (T0 = T1 = c) k=2 n−1 c2 X 2 k log k Induktionsvor. : Tk ≤ k log k n k=2 Z n c 2x log x dx Treppenfunktion ≤ x log x ≤ c0 + 4c + (n − 1)c1 + 2 n 1 ¯n Z n ´ c ³ ¯ x dx Part. Integration = c0 + 4c + (n − 1)c1 + 2 x2 log x¯ − n 1 1 c ³ n + 1´ = c0 + 4c + (n − 1)c1 + 2 n2 log n − (n − 1) n 2 ³ 1 ´ c2 = c0 + 4c + (n − 1) c1 − (1 + ) + c2 n log n 2 n ³ c2 ´ + c2 n log n wegen c2 /2 = c0 + c1 + 4c = c0 + 4c − (n − 1) c0 + 4c + 2n ≤ c2 n log n wegen n ≥ 2. ≤ c0 + (n − 1)c1 + 4c + Aufgabe 5.2: i) Entwickeln Sie einen Algorithmus, der den Median einer Folge (von Zahlen) bestimmt, ohne eine Totalordung der Folge vorzunehmen, und der mit möglichst wenig Vergleichen auskommt. Geben Sie eine Abschätzung für die Anzahl der Vergleiche, die Ihr Algorithmus höchstens oder im Mittel benötigt, bestätigen Sie die Abschätzung durch Messungen. (6) ii) Das gleiche wie in i) für die Bestimmung des i-t-größten Elementes einer Folge. (4) Hinweis: Verwenden Sie die Idee von ”Quicksort”: Man nimmt ein willkürlich gewähltes Vergleichsobjekt vj der Folge L und prä-sortiert wie in Quicksort, so daß L = L0 ∪ {vj } ∪ F1 mit L0 = {vi ∈ F |vi < vj } und F1 = {vi ∈ F |vi ≥ vj , i 6= j}. Damit erhält man die Position von vj in der – geordneten – Folge, und kann darauf eine Rekursion stützen.