Karacubovo násobení

Z testwiki
Skočit na navigaci Skočit na vyhledávání

Karacubovo násobení je asymptoticky rychlý násobící algoritmus, který v roce 1960 vymyslel sovětský matematik Anatolij Alexejevič Karacuba jako tehdy asymptoticky nejrychlejší algoritmus násobení dlouhých čísel. Jeho složitost je pro dvě n-ciferná čísla nanejvýš nlog23n1,585 jednociferných násobení. Tradiční školský algoritmus násobení přitom vyžaduje n2 násobení. Od doby Karacubova objevu byly vymyšleny algoritmy asymptoticky ještě rychlejší, Toomovo-Cookovo násobení a Schönhageovo-Strassenovo násobení. Karacubův algoritmus je přesto stále používán, protože je pro určitou délku vstupních čísel v praxi nejrychlejší.

Dějiny algoritmu

V roce 1952 vyslovil Andrej Nikolajevič Kolmogorov domněnku, že tradiční a tehdy jediný známý školský násobící algoritmus je pro úlohu násobení dlouhých čísel asymptoticky optimální. V roce 1960 pak Kolmogorov organizoval seminář na Lomonosovově univerzitě zaměřený na matematické problémy v kybernetice, kde tehdy třiadvacetiletý student Karacuba vymyslel algoritmus , který násobí dvě n-ciferná čísla v Θ(nlog23), čímž domněnku vyvrátil. Kolmogorova algoritmus zaujal a napsal o něm v roce 1962 do časopisu Doklady Akaděmii Nauk SSSR článek Umnoženije mnogoznačnych čisel na avtomatach, ve kterém zveřejnil také výsledek Jurije Petroviče Ofmana. Jako autoři byli uvedeni „A. Karacuba a Ju. Ofman“, ovšem Karacuba se o článku dozvěděl až s jeho zveřejněním.

Algoritmus

Základní krok

Základním krokem Karacubova algoritmu je vzorec, z kterého vyplývá možnost převést vynásobení dvou čísel x a y pomocí třech násobení menších čísel se zhruba polovinou cifer a několika ciferných posunů a sčítání.

Nechť jsou x a y n-ciferná čísla zapsaná v soustavě o základu z. Pro libovolné přirozené číslo m menší než n můžeme zadaná čísla zapsat jako

x=x1zm+x0 a
y=y1zm+y0,

kde x0 a y0 jsou menší než zm. Jejich součin je pak

xy=(x1zm+x0)(y1zm+y0)
=w2z2m+w1zm+w0,

kde

w2=x1y1,
w1=x1y0+x0y1 a
w0=x0y0

Tyto vzorce vyžadující čtyři násobení znal už Charles Babbage. Karacuba si povšiml, že za cenu několika sčítání navíc je možné výpočet provést jen pomocí tří násobení. Při w0 a w2 jako ve vzorcích výše můžeme spočítat

w1=(x1+x0)(y1+y0)w2w0,

čehož pravdivost je zřejmá z:

w1=x1y0+x0y1
w1=(x1+x0)(y1+y0)x1y1x0y0

Příklad

Při výpočtu součinu 12345 a 6789 máme z=10 a zvolíme m=3. Činitele rozložíme do podoby:

  • 12345=121000+345 a
  • 6789=61000+789

K výpočtu součinu nám pak stačí tři násobení na menších číslech:

w2=126=72
w0=345789=272205
w1=(12+345)(6+789)w2w0=35779572272205=11538

Pomocí těchto součinů už získáme výsledek jen pomocí posunů a sčítání:

123456789=w2z2m+w1zm+w0, tedy
7210002+115381000+272205=83810205

Rekurzivní použití

Mají-li vstupní čísla alespoň n4 číslice, pak pomocná násobení podle výše uvedeného postupu pracují s činiteli o méně než n číslicích. I na tato pomocná násobení je pak možné využít postup výše a tak rekurzivně dojít až k tak krátkým číslům, pro která komplikovaný postup nenabízí zrychlení a tedy jejich součin spočítáme přímo školským algoritmem.

Reference

Šablona:Překlad Šablona:Autoritní data