Умножение в

10

Я искал здесь , и я заметил, что лучшее время выполнения для умножения двух битных чисел - это , но я легко могу заметить алгоритм, который работает в .O ( n log n 2 O ( log n ) O ( n log n )nO(nlogn2O(logn)O(nlogn)

В конце концов, мы знаем, как умножить два полинома из степени в времени выполнения. Но умножение многочленов такое же, как умножение двух битных чисел. Таким образом, у нас есть алгоритм для умножения двух битных чисел в . Теперь единственной проблемой, которая может возникнуть, является перенос, но в каждой фазе мы можем исправить это за время, просто перемещаясь на самый правый бит и его левый сосед, до конца. То есть наша среда выполнения должна оставаться .O ( n log n ) n n O ( n log n ) O ( n ) O ( n log n )nO(nlogn)nnO(nlogn)O(n)O(nlogn)

Так я сделал новое (и довольно очевидное) открытие? Или страница википедии устарела? Или, может быть, у меня есть какая-то ошибка?

TheEmeritus
источник
Каким образом «мы знаем» «умножить два полинома из степени в времени выполнения»? O ( n log n )nO(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 ( п войти п ) операций в R , используя быстрое преобразование Фурье непосредственно над R . Более конкретно, над ZC вы можете сделать это, используя O ( n log n ) кольцевых операций (игнорируя тот факт, что для этого потребуется точная арифметика над комплексными числами).nO(nlogn)RRZCO(nlogn)

Другой мерой, которая может быть принята во внимание, является сложность операции. И это то, что нас интересует при умножении двух целых чисел длиной . Здесь примитивные операции умножаются и складываются из двух цифр (с переносом). Таким образом, при умножении двух многочленов на Z вам действительно необходимо учитывать тот факт, что числа, возникающие во время вычислений, не могут быть умножены с использованием постоянного числа примитивных операций. Это и тот факт, что Z не имеет n-го первичного корня из единицы при n > 2, мешает вам применить O ( n log n )nZZnn>2O(nlogn)алгоритм. Вы преодолеть это, учитывая , с коэффициентами из кольца Z /2 п + 1 , так как коэффициенты полинома продукта не будет превышать эту оценку. Там (когда n является степенью двойки), у вас есть (класс конгруэнции) 2 в качестве n-го корня единицы, и рекурсивно вызывая алгоритм для умножения коэффициентов, вы можете получить всего O ( n log n log log n ) примитивные (т. е. битовые) операции. Это затем переносится на целочисленное умножение.f,gZ/2n+1n2NО(NжурналNжурналжурналN)

В качестве примера, который хорошо подчеркивает важность различия между кольцевыми операциями и примитивными операциями, рассмотрим два метода оценки полиномов: метод Хорнера и метод Эстрина. Метод Хорнера оценивает многочлен при некотором x Z , используя тождество f ( x ) = ( ( f n x + f n - 1 ) x + + ) +езнак равноΣязнак равно0NеяИксяИксZ в то время как метод расщепляется Эстрина до F на две части Н = п / 2 Е я = 1 п п / 2 + я х я и л = п / 2 Σ я = 0 е я х я т.е. Н содержит члены степени > n / 2 и L слагаемые степениn / 2 (предположим, что n

е(Икс)знак равно(...(еNИкс+еN-1)Икс+...+...)+е0
е
ЧАСзнак равноΣязнак равно1N/2еN/2+яИкся
Lзнак равноΣязнак равно0N/2еяИкся
ЧАС>N/2LN/2N это степень двух, для простоты).

е(Икс)

е(Икс)знак равноЧАС(Икс)ИксN/2+L(Икс)

NN+журналN

N/2N/2Ω(N2)NО(N)О(NжурналсN)знак равноО~(N)с>0

Корнелиус Бранд
источник
9

nО(NжурналN)NО(2журнал*NNжурналN)NО(NжурналN)

Дэвид Ричерби
источник
5
Я не думаю, что это проблема. Если мы думаем о числах как о полиномах, у которых «x» является базой, например, 2, то обычно мы можем умножить полиномы с нулем в степени (числа, меньшие, чем основание) в постоянное время. Я предполагаю, что проблема в том, что алгоритм O (n * log n) использует БПФ, и внутри алгоритма БПФ могут появляться асимптотически большие числа.
JKFF