Karazuba-Algorithmus
Der Karatsuba-Algorithmus ist ein Algorithmus zur Multiplikation zweier ganzer Zahlen. Mit einer Laufzeitkomplexität von ist er deutlich schneller als der naive Algorithmus nach der Schulmethode. Dieser (und auch deren implizite Übertragung auf das Binärsystem in Form der russischen Bauernmultiplikation) besitzt Laufzeitkomplexität . Für hinreichend große Zahlen ist er aber auch langsamer als der Schönhage-Strassen-Algorithmus, dessen Laufzeitkomplexität beträgt und der aus Sicht der Komplexitätstheorie als schnellster bekannter Algorithmus zur Multiplikation ganzer Zahlen gilt. Der Algorithmus von Karatsuba arbeitet nach dem rekursiven Prinzip Teile und herrsche und ist der einfachste und asymptotisch langsamste Spezialfall des Toom-Cook-Algorithmus (siehe unten).
Idee des Algorithmus
Multiplizieren verursacht in der Schulmethode quadratischen Aufwand, während Additionen und Verschiebeoperation nur linearen Aufwand haben. Die Idee ist nach dem „Teile und herrsche“-Prinzip die beiden zu multiplizierenden Zahlen in zwei Teile aufzuspalten, und die teuren Multiplikationen (so gut es geht) durch Additionen und Verschiebeoperationen zu ersetzen. Das Ausmultiplizieren der geteilten Zahlen ergibt drei Teilterme, die durch vier Multiplikationen gebildet werden. Diese können durch Verschiebe- und Additionsoperationen zum Gesamtergebnis zusammengesetzt werden. Einer dieser Terme ist dabei eine Summe zweier Produkte. Dieser Term kann aber auch als Summe geschrieben werden, die aus einem (neuen) Produkt und den anderen beiden Teiltermen besteht. Insgesamt spart man so also eine teure Teil-Multiplikation ein. Führt man dieses Verfahren rekursiv durch, so erhält man eine wesentlich günstigere Laufzeit als nach der naiven Schulmethode.
Der Algorithmus im Detail
Wir gehen von zwei natürlichen Zahlen x und y aus, deren Länge jeweils 2n beträgt. Der Algorithmus kann in einfacher Weise so verallgemeinert werden, dass er auch auf ganzen Zahlen funktioniert, indem Vorzeichen gesondert berücksichtigt werden. Zahlen mit ungerader Länge können als solche mit gerader Länge dargestellt werden, indem eine führende Null vorangestellt wird. Bei Zahlen ungleicher Länge kann die kleinere Zahl ebenfalls durch voranstellen von Nullen auf gleiche Länge aufgefüllt werden. An der Laufzeitabschätzung unten ändert dies nichts. Ebenfalls unerheblich ist das betrachtete Stellenwertsystem. Wir werden in Beispielen mit Dezimalzahlen operieren.
Seien x und y dargestellt durch die Ziffernfolgen
- und
Der Algorithmus teilt diese Ziffern nun in
- und sowie
- und
auf, so dass sich diese auch Darstellen lassen mit
- und
- ,
wobei b die Basis des verwendeten Stellenwertsystems ist.
Im Folgenden werden wir nun versuchen die Multiplikation von x und y in eine andere, schneller berechenbare Form zu bringen. Ausmultiplizieren ergibt zunächst
Genauso erhält man auch
- .
In vorangegangene Gleichung eingesetzt ergibt sich nun
- .
Man erkennt, dass im Wesentlichen nur noch die drei Produkte
rekursiv berechnet und - mittels einfachen Verschiebe- und Additionsoperationen - verknüpft werden müssen zu
- .
Laufzeitanalyse
Eine Multiplikation zweier -stelliger Zahlen wird zurückgeführt auf drei Multiplikationen von je zwei -stelligen Zahlen sowie vier Additionen bzw. Subtraktionen -stelliger Zahlen. Die für letzteres benötigte Zeit ist . Damit ergibt sich als Rekursionsgleichung für die Laufzeit , die zur Multiplikation zweier -stelligen Zahlen nötig ist,
Wir bestimmen das asymptotische Verhalten dieser Funktion mit Hilfe des Master-Theorems. Mit den Bezeichnungen von dort haben wir und , also . Daher müssen wir mit vergleichen. Wir stellen fest, dass "echt kleiner" ist (genauer: für jede Funktion finden wir ein , so dass ). Also befinden wir uns im ersten Fall des Master-Theorems und können schließen, dass
ist.
Beispiel
Wir betrachten als Beispiel die Zahlen
- und
Gemäß obiger Erläuterung stellen wir diesen Zahlen noch ausreichend Nullen voran, das heißt wir setzen
- und
Wir haben nun zwei natürliche Zahlen der Länge 12, das heißt es ist . Diese beiden Zahlen können wir nun zerlegen in
- und sowie
- und
Es gilt
- und
Wir bilden nun zunächst die Produkte
- und
Zuletzt bestimmen wir noch
Der Algorithmus würde die Produkte und rekursiv bestimmen. Es bleibt das Ergebnis gemäß obiger Formel zusammenzusetzen:
Implementierung in Java
Eine nicht auf Effizienz ausgelegete Implementierung in Java kann wie folgt aussehen:
public static BigInteger karatsuba (BigInteger x, BigInteger y) { int n = Math.max (x.bitLength(), y.bitLength());
// Verwende Standard Multiplikation bei kleinen Eingaben if (n <= 1500) return x.multiply (y);
n = n / 2;
// teile; x = xH b^n + xL , y = xH b^n + yL BigInteger xH = x.shiftRight (n); BigInteger xL = x.subtract (xH.shiftLeft(n)); BigInteger yH = y.shiftRight (n); BigInteger yL = y.subtract (yH.shiftLeft(n));
// berechne die Teilresultate BigInteger p1 = karatsuba (xH, yH); BigInteger p2 = karatsuba (xL, yL); BigInteger p3 = karatsuba (xL.add (xH), yL.add (yH));
// Setzte die Teile zum Gesamtergebnis zusammen return p1.shiftLeft (2*n).add (p3.subtract (p1).subtract (p2).shiftLeft (n)).add (p2); }
Verallgemeinerung
Statt in zwei Teile, können die zu multiplizierenden Zahlen auch in mehr Teile zerlegt werden. Durch geschickte Linearkombination von Teilergebnissen genügen dann bei Zerlegung in d+1 Teile 2d+1 Multiplikationen auf den kleineren Zahlen. Rekursiv angewand führt dieses Verfahren dann zum Toom-Cook-Algorithmus.
Weblinks
- Schnelle Multiplikation beim Algorithmus der Woche
- A. Karatsuba and Yu Ofman, "Multiplication of Many-Digital Numbers by Automatic Computers." Doklady Akad. Nauk SSSR Vol. 145 (1962), pp. 293–294. Translation in Physics-Doklady 7 (1963), pp. 595–596.
- Karatsuba Multiplication on MathWorld
- Bernstein, D. J., "Multidigit multiplication for mathematicians". Mathematische Darstellung diverser Multiplikations Algorithmen. Behandelt auch den Karatsuba Algorithmus.