Freie Universität Berlin Proseminar über Algorithmen 22.05.2008 Ausarbeitung zum Vortrag über Multiplikation von langen Zahlen und Multiplikation quadratischer Matrizen (von Maria Spiering) ➢ Multiplikation langer Zahlen 1. Schulmethode 1.1. einfacher Fall Um den Aufwand für die Multiplikation von langen Zahlen für die Schulmethode zu berechnen, betrachten wir zunächst den einfachen Fall, dass wir eine Zahl a mit n Ziffern mit einer Zahl b bestehend aus einer einzelnen Ziffer y multiplizieren. Für diese Multiplikation müssen wir zuerst jede dieser n Ziffern mit der Ziffer y multiplizieren. Durch diese n Teil-Multiplikationen erhalten wir n Zeilen mit Zwischenergebnissen, die wir nun spaltenweise addieren müssen. Für diesen Spezialfall erhalten wir also: ⇒ n Multiplikationen + n Additionen = 2n Operationen 1.2. komplexer Fall Betrachten wir nun das ganze für zwei n-lange Zahlen a und b. (Ist eine der beiden Zahlen kürzer, füllen wir diese vorne mit entsprechend vielen Nullen auf.) Da die Zahl b nun nicht mehr nur aus einer Ziffer sondern aus n besteht, müssen wir den ⇒ 2n2 Operationen obigen Fall für jede dieser n Stellen berechnen. Außerdem müssen wir auch wieder alle maximal 2n-langen Zwischenergebnisse spaltenweise addieren. Da wir n Zeilen mit Zwischenergebnissen haben, brauchen wir also n-1 Additionen ⇒ (n-1) 2n ⇒ 2n2- 2n Operationen für unsere 2n-langen Zahlen. Insgesamt kommen wir also auf: ⇒ 4n2 – 2n Grundoperationen (davon n2 Multiplikationen) 2. Methode von Karatsuba Die Methode von Karatsuba basiert auf dem rekursiven divide and conquer Prinzip und benötigt wesentlich weniger Operationen als die Schulmethode. Dafür schauen wir uns drei Fälle für Zahlen der Länge n=1, n=2 und n=4 an. 2.1. n = 1 Der einfachste Fall benötigt (natürlich so wie die Schulvariante) eine Multiplikation. 6⋅4=24 Beispiel: 2.2. n = 2 Wenn wir Zahlen a und b der Länge zwei haben, so können wir diese wie folgt zergliedern und multiplizieren: Zerlegung: a= p⋅10q b=r⋅10s a⋅b = p⋅10q⋅r⋅10s = pr⋅100 psqr ⋅10 qs 2.3. Optimierung Die reine Zerlegung macht die Methode von Karatsuba aber noch nicht besser als die Schulvariante, weswegen die Anzahl der Operationen (Multiplikationen) reduziert werden muss. Diese Reduktion von 4 auf 3 Multiplikationen wird über die folgende Entdeckung gelöst: alt neu u =p r v a = psqr w =qs u = pr v ' =q− p⋅ s−r =qs−qr − ps pr v n =uw−v ' w =qs ⇒ a⋅b = u⋅100 v a⋅10 w ⇒ a⋅b = u⋅100 v n⋅10 w 2.4. n = 4 Das Aufgliedern von 4 stelligen Zahlen sieht ähnlich wie bei Zahlen der Länge 2 aus. Zerlegung: 2 a= p⋅10 q 2 b=r⋅10 s Hilfsprodukte: u = pr v n =uw−q− p⋅ s−r w =qs 2 2 a⋅b = p⋅10 q⋅r⋅10 s 4 2 =u⋅10 v n⋅10 w 2.5. n = 2k Anhand der beschriebenen drei Fälle, können wir nun die Karatsubas rekursiven Algorithmus allgemein für alle Zahlen der Länge n = 2k beschreiben: Zerlegung: n /2 a= p⋅10 q n /2 b=r⋅10 s Hilfsprodukte: u = pr v n =uw−q− p⋅ s−r w =qs n a⋅b =u⋅10 v n⋅10 n /2 w 3. Vergleich Der entscheidene Unterschied zwischen den beiden Methoden besteht darin, dass Karatsubas Variante nur 3 anstatt 4 Multiplikationen für die Berechnung benötigt. Werden die zu berechnenden Zahlen sehr groß hat dies durch den rekursiven divide and conquer Ansatz einen erheblichen Einfluss, da nun für jede rekursive Berechnung eine Multiplikation eingespart werden kann. Zur Veranschaulichung des Aufwand bzgl. der Multiplikationen der beiden Methoden, können wir durch die vorangegangenen Beispiele die folgende Tabelle aufstellen: Länge 1 = 20 2 = 21 4 = 22 8 = 23 16 = 24 32 = 25 n = 2k ... Karatsuba 1 3 9 27 81 243 ... 3k Schulemethode 1 4 16 64 256 1.024 ... 4k Karatsubas Algorithmus lässt sich aber auch durch die Rekursionsgleichung T n = 3T n /2 O n beschreiben, durch die man auf eine obere Schranke von O nlog 3 im Gegensatz zu einer Laufzeit von O nlog 4 =O n2 der Schulmethode kommt. 2 2 ➢ Multiplikation quadratischer Matrizen Für die folgenden divide-and-conquer-Algorithmen gehen wir davon aus, dass die zu betrachenden Matrizen A , B , C ∈ℝ die Form n×n haben und n eine Potenz von zwei ist, also n=2 k . 1. naive Methode Wollen wir zwei Matrizen A und B multiplizieren C= A⋅B , dann können wir diese jeweils in vier n / 2 -große Untermatrizen M 1,1 , M 1,2 , M 2,1 , M 2,2 mit M ∈ { A ,B ,C } teilen und erhalten so nach der „normalen“ Multiplikation folgendes Bild: C 1,1 = A1,1⋅B1,1 A1,2⋅B2,1 C 1,1 C 1,2 A1,1 A1,2 B 1,1 B 1,2 C 1,2 = A1,1⋅B1,2 A1,2⋅B2,2 = ⋅ ⇒ C 2,1 C 2,2 A2,1 A2,2 B 2,1 B 2,2 C 2,1 = A2,1⋅B1,1 A2,2⋅B2,1 C 2,2 = A2,1⋅B 1,2 A2,2⋅B2,2 1.1. Aufwand Für die naive Methode benötigen wir für die Berechnung jeder n /2×n/2 großen C i , j -Matrix zwei Matrix-Multiplikationen. Unsere Gesamtmatrix besteht aus vier C i , j -Matrizen, weswegen diese rekursive Variante insgesamt acht Matrix-Multiplikationen für die Berechnung benötigt. Der Aufwand lässt sich allgemein über die folgende Rekursiongleichung bestimmen: log 8 3 3 2 T n = 8T n/2 O n wodurch man einen Aufwand von n =n ⇒ n kommt. 2 2. Methode von Strassen Strassens Algorithmus verfolgt ebenso den rekursiven divide-and-conquer-Ansatz in dem die Ergebnismatrix in vier n /2×n/2 große Matrizen unterteilt wird. Seine Methode hat 4 Teilschritte und erklärt wie die Matrix-Multiplikation mit einem geringeren Aufwand als die naive Methode durchgeführt werden kann. 2.1. 4 Schritte zum Erfolg 1. Teile die zu multiplizierenden Matrizen A und B in n /2×n/2 große Teilmatrizen auf (siehe naive Methode). 2. Benutze Skalaradditionen und -subtraktionen und berechne 14 Matrizen A 1 , B 1 , A 2 , B 2 , ... , A 7 , B 7 , wobei jede Matrix n /2×n/2 groß ist. 3. Berechne rekursiv die 7 Matrixprodukte: P i= A i⋅B i für i=1,2 ,..7 4. Berechne nun die gewünschten Teilmatrizen C 1,1 ,C 1,2 ,C 2,1 , C 2,2 der Ergebnismatrix C durch Addieren und/ oder Subtrahieren der unterschiedlichen Kombinationen der Pi Matrizen, unter Benutzung von nur Skalaradditionen und -subtraktionen. Entscheidend ist hierbei Schritt Nummer drei, da Strassen hier nur 7 anstatt 8 MatrixMuliplikationen verwendet. 2.2. Herleitung der Produktmatrizen P i Es stellt sich nun die Frage: Wie sehen diese 14 Matrizen A i und B i und damit auch die sieben Matrixprodukte Pi aus? Es ist nicht genau klar, wie Strassen diese Matrixprodukte bestimmt hat, denn leider gibt es dafür von Strassen selbst keine Erklärung. Jedoch wollen wir uns hier eine plausible Rekonstruktion seiner Entdeckung ansehen. Grundlage für unser weiteres Vorgehen sind die vier C i , j Matrizen, die wir nun mittels der sieben Produktmatrizen Pi darstellen wollen. ⇒ Sei C 1,2= P 1P 2 A 2 ⋅ B 2 mit P 1= A 1 ⋅ B 1 und P 2= = A1,1⋅ B1,2 −B2,2 = A1,1 A1,2⋅B 2,2 = A1,1 B1,2 −A1,1 B2,2 = A1,1 B 2,2 A1,2 B 2,2 ⇒C 1,2 =A1,1 B1,2− A1,1 B2,2 A1,1 B 2,2 A1,2 B 2,2 ⇒ Sei C 2,1 =P 3 P 4 A 3 ⋅ B 3 B 4 mit P 3= und P 4= A 4 ⋅ = A2,1 A2,2 ⋅B1,1 = A2,2⋅−B1,1 B2,1 = A2,1 B 1,1 A2,2 B 1,1 =−A2,2 B1,1 A2,2 B2,1 ⇒C 2,1=A2,1 B1,1 A2,2 B1,1 −A2,2 B1,1 A2,2 B 2,1 Bisher haben wir genauso viele Matrix-Multiplikation wie die naive Methode benötigt, weswegen wir nun mit den restlichen drei Matrizen die fehlenden C i , j erzeugen müssen. Versuchen wir also nun mit P 5 gleich zwei essentielle Terme zugleich zu erzeugen und dann mit den anderen P i so zu kombinieren, dass wir nicht mehr als sieben Matrixprodukte benötigen. P 5= A 5 ⋅ B 5 = A1,1 A2,2 ⋅ B1,1 B2,2 ⇒C 1,1=P 5−P 2P 4P 6 = A1,1 B1,1 A1,1 B2,2 A2,2 B1,1 A2,2 B2,2 = A1,1 B 1,1− A1,2 B 2,2 A2,2 B 2,1 A2,2 B 2,2P 6 P 6= A6 ⋅ B 6 = A1,2− A2,2 ⋅ B 2,1B 2,2 = A1,2 B 2,1 A1,2 B 2,2− A2,2 B 2,1− A2,2 B 2,2 ⇒C 1,1 =A1,1 B1,1 A1,2 B 2,1 Gleiches machen wir nun mit P 5 um C 2,2 zu erhalten. ⇒C 2,2= P 5 P 1−P 3P 7 = A1,1 B 1,1 A1,1 B1,2 −A2,1 B1,1 A2,2 B2,2 P 7 P 7= A 7 ⋅ B 7 =−A1,1A2,1 ⋅ B1,1B 1,2 =−A1,1 B1,1− A1,1 B 1,2 A2,1 B 1,1A2,1 B1,2 ⇒C 2,2=A2,1 B1,2 A2,2 B 2,2 Nun haben wir alle Teilmatrizen C i , j berechnet und können unsere Teilergebnise zu unserer Ergebnismatrix C zusammensetzen. Von nun an benötigen wir immer nur noch: i 1 2 3 4 5 6 A i A1,1 A1,1 A1,2 A2,1 A2,2 A2,2 A1,1 A2,2 A1,2 −A2,2 −A1,1 A2,1 B i B1,2 −B2,2 B2,2 B1,1 −B1,1B 2,1 B1,1 B2,2 B2,1 B2,2 B1,1 B1,2 7 und die obige Zuordnung der Produktmatrizen zu den jeweiligen C i , j (fett gedruckt). 2.3. Aufwand Der Aufwand der Funktion lässt sich über die Rekursiongleichung T n= 7T n /2 n 2 beschreiben, wodurch man auf eine Laufzeit von nlog 7 =O n2.81 kommt, die im Gegensatz zur naiven Methode mit acht Matrix-Multiplikation nlogs 8=n 3 besser erscheint. Es wird zwar in jedem Rekursionschritt eine Matrix-Multiplikation eingespart, jedoch wird der Algorithmus durch seine Zusatzberechnungen bei kleinen Matrizen sehr ineffizient, weswegen man ab einer hardwareabhängigen Größe n zu anderen Methoden wechselt. 2 2