Eu estava olhando aqui e notei que o melhor tempo de execução para multiplicação de dois números de bits é , mas posso notar facilmente um algoritmo executado em .
Afinal, sabemos como multiplicar dois polinômios do grau no tempo de execução . Mas multiplicar polinômios é o mesmo que multiplicar dois números de bits. Portanto, temos um algoritmo para multiplicar dois números de bits em . Agora, o único problema que pode ocorrer é o carry, mas em cada fase podemos consertar isso em tempo, simplesmente movendo o bit mais à direita e seu vizinho esquerdo, até o fim. Ou seja, nosso tempo de execução permanecerá .
Então, eu fiz uma nova descoberta (e bastante óbvia)? Ou a página da Wikipedia está desatualizada? Ou talvez eu tenha algum erro?
runtime-analysis
TheEmeritus
fonte
fonte
Respostas:
Como o @DavidRicherby já aponta, a confusão surge porque diferentes medidas de complexidade estão se misturando. Mas deixe-me elaborar um pouco.
Geralmente, ao estudar algoritmos para multiplicação polinomial por anéis arbitrários, interessa-se o número de operações aritméticas no anel que um algoritmo usa. Em particular, dado alguns anéis (comutativos, unitários) e dois polinômios de grau menor que , o algoritmo Schönhage-Strassen precisa de multiplicações e adições em para calcular , aproximando-se da ésima raiz primitiva da unidade de para para obter um anel maior e, em seguida, usando o Fast Transformada de Fourier sobreR f,g∈R[X] n O(nlognloglogn) R fg∈R[X] n R D⊃R D , Calculando o produto em .D
Se o anel contém um raiz -ésimo de unidade, então este pode ser acelerado para operações em , usando a Fast Fourier Transform directamente sobre . Mais especificamente, em , você pode fazer isso usando operações de anel (ignorando o fato de que isso exigiria aritmética exata sobre os números complexos).n O(nlogn) R R Z⊂C O(nlogn)
A outra medida que pode ser levada em consideração é a complexidade de bits de uma operação. E é nisso que estamos interessados ao multiplicar dois números inteiros de comprimento de bit . Aqui, as operações primitivas estão se multiplicando e adicionando dois dígitos (com carry). Portanto, ao multiplicar dois polinômios sobre , é necessário levar em consideração o fato de que os números que surgem durante o cálculo não podem ser multiplicados usando um número constante de operações primitivas. Isso e o fato de que não possui a ésima raiz primitiva da unidade para impede que você aplique o algoritmo . Você supera isso considerandon Z Z n n>2 O(nlogn) f,g com coeficientes do anel , pois os coeficientes do polinômio do produto não excederão esse limite. Lá (quando é uma potência de dois), você tem (a classe de congruência de) como a ésima raiz da unidade e, chamando recursivamente o algoritmo para multiplicações de coeficientes, você pode obter um total de ) operações primitivas (isto é, bit). Isso então é transferido para a multiplicação inteira.Z/⟨2n+1⟩ n 2 n O(nlognloglogn)
Para um exemplo que destaca bem a importância da diferença entre operações em anel e operações primitivas, considere dois métodos para avaliar polinômios: o método de Horner e o método de Estrin. O método de Horner avalia um polinômio em algum explorando a identidade enquanto de Estrin método divide em duas partes e ie, contém os termos de grau e os termos de grauf=∑ni=0fiXi x∈Z
Então, podemos calcular usando e aplicando o algoritmo recursivamente.f(x)
O primeiro, usando adições e multiplicações, provou ser ótimo em relação ao número de adições e multiplicações (isto é, operações em anel), o último precisa de mais (pelo menos ).n n+logn
Mas, no nível das operações de bits, pode-se (facilmente) mostrar que, no pior dos casos, o método de Horner realiza multiplicações de números de tamanho pelo menos , levando a muitos bits operações (isso ocorre mesmo se assumirmos que dois números de bits podem ser multiplicados no tempo ), enquanto o esquema de Estrin usa operações para algumas operações , que é, de longe, assintoticamente mais rápido.n/2 n/2 Ω(n2) n O(n) O(nlogcn)=O~(n) c>0
fonte
Dizer que você pode multiplicar dois polinômios de grau no tempo implica que, em particular, você pode multiplicar polinômios de grau zero, ou seja, constantes, em tempo constante. Claramente, portanto, as afirmações "multiplicar números de bits leva tempo " e "multiplicar graus polinômios leva tempo " são relativas diferentes modelos de computação, portanto não são diretamente comparáveis.n O(nlogn) n O(2log∗nnlogn) n O(nlogn)
fonte