Множення в


10

Я дивився сюди , і помітив, що найкращий час для множення двох бітних чисел є , але я легко помічаю алгоритм, який працює в .O ( n log n 2 O ( log n ) O ( n log n )nO(nlogn2O(logn)O(nlogn)

Зрештою, ми знаємо, як помножити два поліноми зі ступенем n в O(nlogn) часу виконання. Але множення многочленів - це те саме, що множення двох n бітних чисел. Отже, у нас є алгоритм множення двох n бітних чисел в O(nlogn) . Тепер єдина проблема, яка може виникнути, - це перенесення, але в кожній фазі ми можемо виправити це в O(n) час, просто перемістившись по найсправедливішому шматочку і його лівому сусідові, до кінця. Тобто, наш час виконання залишатиметься O(nlogn) .

Тож я зробив нове (і досить очевидне) відкриття? Або сторінка вікіпедії застаріла? Чи, можливо, у мене є якась помилка?


Який спосіб "ми знаємо" "помножити два поліноми від ступеня n в O(nlogn) час виконання"?

Відповіді:


8

Як вже зазначає @DavidRicherby, плутанина виникає через те, що різні заходи складності змішуються. Але дозвольте мені трохи детальніше.

Зазвичай, вивчаючи алгоритми множення поліномів на довільні кільця, цікавить кількість арифметичних операцій у кільці, яке використовує алгоритм. Зокрема, враховуючи деяке (комутаційне, унітарне) кільце та два многочлени ступеня менше , алгоритм Шенгаге-Штрассена потребує множення та доповнення в , щоб обчислити , приблизно, примикаючи до -го примітивних коренів єдності до щоб отримати трохи більше кільце а потім, використовуючи швидкий Перетворення Фур'є черезf , g R [ X ] n O ( n log n log log n ) R f g R [ X ] n R D R D DRf,gR[X]nO(nlognloglogn)RfgR[X]nRDRD, Обчислюючи продукт в .D

Якщо ваше кільце містить -й корінь з одиниці, то це може бути прискорене до операцій в за допомогою швидкого перетворення Фур'є безпосередньо над . Більш конкретно, над це можна зробити за допомогою кільцевих операцій (ігноруючи той факт, що це вимагатиме точної арифметики над складними числами).O ( n log n ) R R ZC O ( n log n )nO(nlogn)RRZCO(nlogn)

Іншим заходом, який можна врахувати, є бітова складність операції. І це те, що нас цікавить при множенні двох цілих чисел бітової довжини . Тут примітивні операції - це множення і додавання двох цифр (з перенесенням). Отже, при множенні двох многочленів на вам потрібно враховувати той факт, що числа, що виникають під час обчислення, не можна перемножувати, використовуючи постійну кількість примітивних операцій. Це та факт, що не має -го примітивного кореня єдності для заважає застосувати алгоритм . Ви долаєте це, вважаючиZ Z п п > 2 Про ( п увійти п ) е , г Z /2 п + 1 п 2 п Про ( п увійти п увійти журналу п )nZZnn>2O(nlogn)f,gз коефіцієнтами з кільця , оскільки коефіцієнти многочлена добутку не перевищуватимуть цю межу. Там (коли - потужність двох), ви маєте (клас конгруентності) як -й корінь єдності, і рекурсивно викликаючи алгоритм множення коефіцієнтів, ви можете досягти загального примітивні (тобто, бітові) операції. Потім це переходить до цілого множення.Z/2n+1n2nO(nlognloglogn)

Для прикладу, який добре підкреслює важливість різниці між операціями кільця та примітивними операціями, розглянемо два методи оцінки поліномів: метод Хорнера та метод Естріна. Метод Горнера оцінює поліном на деякому , використовуючи тотожність тоді як метод Естріна розбивається на дві частини і тобто містить терміни ступеня а терміни ступеняf=i=0nfiXixZ

f(x)=((fnx+fn1)x++)+f0
f
H=i=1n/2fn/2+iXi
L=i=0n/2fiXi
H>n/2Ln/2(припустимо, - сила двох, для простоти).n

Тоді ми можемо обчислити використовуючи і застосовуючи алгоритм рекурсивно.f(x)

f(x)=H(x)xn/2+L(x)

Перший, використовуючи додавань і множень, виявився оптимальним wrt числом додавань і множень (тобто кільцевих операцій), другий потребує більшої кількості (принаймні ).nn+logn

Але, на рівні бітових операцій можна (досить легко) показати, що в гіршому випадку метод Горнера виконує множення чисел розміром принаймні , що призводить до безлічі біт операції (це справедливо, навіть якщо припустити, що два бітні числа можна помножити за часом ), тоді як схема Естріна використовує операції для деяких , що, безумовно, асимптотично швидше.n / 2 Ω ( n 2 ) n O ( n ) O ( n log c n ) = ˜ O ( n ) c > 0n/2n/2Ω(n2)nO(n)O(nlogcn)=O~(n)c>0


9

Якщо говорити про те, що можна помножити два многочлени на ступінь за часом то, зокрема, можна помножити багаточлени градусів на нуль, тобто константи, в постійний час. Тому очевидно, що формула винаходу "розмножувальної -розрядним число вимагає часу " і "множення градусів- многочленів вимагає часу " відносні для різних моделей обчислень, тому вони безпосередньо не порівнянні.O ( n log n ) n O ( 2 log n n log n ) n O ( n log n )nO(nlogn)nO(2lognnlogn)nO(nlogn)


5
Я не думаю, що це проблема. Якщо ми думаємо про числа як поліноми, "x" є базовою, наприклад, 2, то, як правило, ми можемо помножувати многочлени градусів на нуль (числа, менші за основу) за постійний час. Я думаю, що проблема полягає в тому, що алгоритм O (n * log n) використовує FFT, і всередині алгоритму FFT можуть з'являтися асимптотично більші числа.
jkff
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.