Я искал здесь , и я заметил, что лучшее время выполнения для умножения двух битных чисел - это , но я легко могу заметить алгоритм, который работает в .O ( n ⋅ log n ⋅ 2 O ( log ∗ n ) O ( n ⋅ log n )
В конце концов, мы знаем, как умножить два полинома из степени в времени выполнения. Но умножение многочленов такое же, как умножение двух битных чисел. Таким образом, у нас есть алгоритм для умножения двух битных чисел в . Теперь единственной проблемой, которая может возникнуть, является перенос, но в каждой фазе мы можем исправить это за время, просто перемещаясь на самый правый бит и его левый сосед, до конца. То есть наша среда выполнения должна оставаться .O ( n log n ) n n O ( n log n ) O ( n ) O ( n ⋅ log n )
Так я сделал новое (и довольно очевидное) открытие? Или страница википедии устарела? Или, может быть, у меня есть какая-то ошибка?
источник
Ответы:
Как уже указывал @DavidRicherby, путаница возникает из-за того, что смешиваются разные меры сложности. Но позвольте мне остановиться подробнее.
Обычно при изучении алгоритмов умножения полиномов над произвольными кольцами интересует количество арифметических операций в кольце, которое использует алгоритм. В частности, для некоторого (коммутативного, унитарного) кольца и двух многочленов степени меньше алгоритму Шёнхаге-Штрассена требуется умножения и сложения в для вычисления путем, грубо говоря, присоединения первообразного корня единицы к чтобы получить некоторое большее кольцо а затем, используя быстрый Преобразование Фурье надf , g ∈ R [ X ] n O ( n log n log log n ) R f g ∈ R [ X ] n R D ⊃ R D DR f,g∈R[X] n O(nlognloglogn) R fg∈R[X] n R D⊃R D , Вычисляя продукт в .D
Если кольцо содержит -й корень из единицы, то это может быть ускорено до O ( п войти п ) операций в R , используя быстрое преобразование Фурье непосредственно над R . Более конкретно, над Z ⊂ C вы можете сделать это, используя O ( n log n ) кольцевых операций (игнорируя тот факт, что для этого потребуется точная арифметика над комплексными числами).n O(nlogn) R R Z⊂C O(nlogn)
Другой мерой, которая может быть принята во внимание, является сложность операции. И это то, что нас интересует при умножении двух целых чисел длиной . Здесь примитивные операции умножаются и складываются из двух цифр (с переносом). Таким образом, при умножении двух многочленов на Z вам действительно необходимо учитывать тот факт, что числа, возникающие во время вычислений, не могут быть умножены с использованием постоянного числа примитивных операций. Это и тот факт, что Z не имеет n-го первичного корня из единицы при n > 2, мешает вам применить O ( n log n )n Z Z n n>2 O(nlogn) алгоритм. Вы преодолеть это, учитывая , с коэффициентами из кольца Z / ⟨ 2 п + 1 ⟩ , так как коэффициенты полинома продукта не будет превышать эту оценку. Там (когда n является степенью двойки), у вас есть (класс конгруэнции) 2 в качестве n-го корня единицы, и рекурсивно вызывая алгоритм для умножения коэффициентов, вы можете получить всего O ( n log n log log n ) примитивные (т. е. битовые) операции. Это затем переносится на целочисленное умножение.f,g Z/⟨2n+1⟩ n 2 N O ( n logжурнал nжурналн )
В качестве примера, который хорошо подчеркивает важность различия между кольцевыми операциями и примитивными операциями, рассмотрим два метода оценки полиномов: метод Хорнера и метод Эстрина. Метод Хорнера оценивает многочлен при некотором x ∈ Z , используя тождество f ( x ) = ( … ( f n x + f n - 1 ) x + … + … ) +езнак равно ∑Nя = 0еяИкся x ∈ Z в
то время как метод расщепляется Эстрина до F на две части
Н = п / 2 Е я = 1 п п / 2 + я х я и
л = п / 2 Σ я = 0 е я х я
т.е. Н содержит члены степени > n / 2 и L слагаемые степени ≤ n / 2 (предположим, что n
источник
источник