Como podemos assumir que operações básicas sobre números levam tempo constante?

74

Normalmente, em algoritmos, não nos preocupamos com comparação, adição ou subtração de números - assumimos que eles correm no tempo . Por exemplo, assumimos isso quando dizemos que a classificação baseada em comparação é O ( n log n ) , mas quando os números são grandes demais para caber nos registros, normalmente os representamos como matrizes, para que operações básicas exijam cálculos extras por elemento.O(1)O(nlogn)

Existe uma prova mostrando que a comparação de dois números (ou outras funções aritméticas primitivas) pode ser feita em ? Se não, por que estamos dizendo que a classificação baseada em comparação é O ( n log n ) ?O(1)O(nlogn)


Eu encontrei este problema quando eu respondi a uma pergunta SO e eu percebi que o meu algoritmo não é , porque mais cedo ou mais tarde eu deveria lidar com big-int, também não era algoritmo de tempo pseudo polinomial, foi P .O(n)P

Rafael
fonte
3
Para contar a complexidade da comparação de números, você também deve escrever os limites da complexidade em termos do tamanho de bit da entrada. Assim, dados os números de w bits, o tamanho do bit da entrada é n = N w e a classificação pode ser feita em O ( N log w N ) = O ( n log n ) . N wn=NwO(NwlogN)=O(nlogn)
Sasho Nikolov
2
existem basicamente dois "reinos" ou "regimes" de estudo da complexidade. geralmente operações são assumidas para operações de "largura fixa", que é uma aproximação razoável para a maioria das linguagens de computador que possuem representações numéricas de largura fixa, incluindo ponto flutuante, por exemplo, de 2 a 4 bytes (consulte, por exemplo, padrões IEEE). depois, há "aritmética de precisão arbitrária" onde os números têm tamanho arbitrário e há um estudo mais cuidadoso / preciso da complexidade das operações. o primeiro contexto é mais na análise aplicada e o último é mais na análise teórica / abstrata. O(1)
vzn

Respostas:

75

Para pessoas como eu que estudam algoritmos para sobreviver, o modelo padrão de computação do século XXI é a RAM inteira . O modelo pretende refletir o comportamento de computadores reais com mais precisão do que o modelo da máquina de Turing. Computadores do mundo real processam números inteiros de vários bits em tempo constante usando hardware paralelo; não números inteiros arbitrários , mas (como os tamanhos das palavras crescem constantemente ao longo do tempo) também não números inteiros de tamanho fixo .

wwnO(1)

Formalmente, o tamanho da palavra NÃO é uma constantew para fins de análise de algoritmos nesse modelo. Para tornar o modelo consistente com a intuição, exigimos , pois, caso contrário, não podemos nem armazenar o número inteiro n em uma única palavra. No entanto, para a maioria dos algoritmos não numéricos, o tempo de execução é realmente independente de w , porque esses algoritmos não se importam com a representação binária subjacente de sua entrada. O mergesort e o heapsort são executados no tempo O ( n log n ) ; média de 3 corridas rápidas em O ( n 2wlog2nnwO(nlogn) no pior dos casos. Uma excepção notável é tipo Radix binário, o qual corre em S ( n w ) tempo.O(n2)O(nw)

Definir nos fornece o modelo de RAM de custo logarítmico tradicional. Porém, alguns algoritmos de RAM inteira são projetados para tamanhos de palavras maiores, como o algoritmo de ordenação inteira em tempo linear de Andersson et al. , Que requer w = Ω ( log 2 + ε n ) .w=Θ(logn)w=Ω(log2+εn)

Para muitos algoritmos que surgem na prática, o tamanho da palavra simplesmente não é um problema, e podemos (e fazemos) recorrer ao modelo de RAM de custo uniforme muito mais simples. A única dificuldade séria vem de multiplicação aninhada, que pode ser usado para construir muito grandes inteiros muito rapidamente. Se pudéssemos executar aritmética em números inteiros arbitrários em tempo constante, poderíamos resolver qualquer problema no PSPACE em tempo polinomial .w

Atualização: devo mencionar também que há exceções ao "modelo padrão", como o algoritmo de multiplicação inteira de Fürer , que usa máquinas de Turing multitape (ou equivalente, a "bit RAM") e a maioria dos algoritmos geométricos, que são analisados ​​teoricamente. modelo "real RAM" limpo, mas idealizado .

Sim, esta é uma lata de vermes.

JeffE
fonte
3
Sei que devo votar, mas não consigo parar de dizer: esta é a melhor resposta. O truque é que (1) operações aritméticas são constantes por definição e isso é bom, porque, em teoria, você pode escolher qualquer modelo; e (2) você deve ter alguns motivos para escolher um determinado modelo, e essa resposta explica quais são.
rgrig
nmP
11
wwN0MNlogwM=(NlgM)/(lgw)O(NM)M
JeffE
Existem algoritmos analisados ​​no modelo Real RAM que não são secretamente algoritmos "Order Type RAM"? Eu nunca pensei muito sobre isso, mas não consigo pensar rapidamente em um exemplo que não seja.
314 Louis
11
O(n3)O(n4)
24

nO(1)O(n)

Massimo Cafaro
fonte
No artigo mencionado: "pode ​​ser medido de duas maneiras diferentes: uma em termos de números inteiros sendo testados ou multiplicados e outra em termos de número de dígitos binários (bits) nesses números inteiros", mas isso não é verdade, nós deve sempre medir pelo tamanho da entrada.
11
nθ(n1/2)Pn
A propósito, algoritmos pseudo-polinomiais podem realmente ser úteis, se a ordem de magnitude de seus parâmetros em instâncias reais for razoavelmente baixa. O exemplo mais famoso é provavelmente o algoritmo pseudo-polinomial para resolver o problema da mochila.
Massimo Cafaro
PPO(nlogn)
nO(1)nO(n)=O(2lgn)lgné o tamanho da entrada, o algoritmo é exponencial no tamanho da entrada! Pense sobre isso. Agora você pode entender o que quero dizer com "Depende apenas do contexto".
Massimo Cafaro
16

Para responder à pergunta como indicado: os algoritmos apenas fazem isso com bastante frequência usando o modelo de RAM. Para classificar, em muitos casos, as pessoas até analisam o modelo de comparação mais simples , que discuto um pouco mais na resposta vinculada.

Para responder à pergunta implícita sobre por que eles fazem isso: eu diria que esse modelo tem um bom poder preditivo para certos tipos de algoritmos combinatórios, nos quais os números são todos "pequenos" e, em máquinas reais, cabem em registradores.

Para responder ao acompanhamento implícito sobre algoritmos numéricos: Não, o modelo antigo de RAM simples não é o padrão aqui. Até a eliminação gaussiana pode exigir algum cuidado. Normalmente, para cálculos de classificação, o Schwartz Lemma entrará (por exemplo, Seção 5 aqui ). Outro exemplo canônico é a análise do algoritmo elipsóide, que requer alguns cuidados para analisar.

E finalmente: as pessoas já pensaram em ordenar as cordas antes , mesmo recentemente.

Atualização: O problema com esta pergunta é que "nós" e "assumimos" não são tão precisamente especificados. Eu diria que as pessoas que trabalham no modelo de RAM não estão usando algoritmos numéricos ou teoria da complexidade (onde determinar a complexidade da divisão foi um resultado célebre ).

Louis
fonte
Hmmmm, parece que é uma resposta interessante ....
Existe uma razão para não responder completamente à pergunta?
4604 Louis
7

O(1)O(1)

python -mtimeit "$a * $b"$a10{1,2,...,66}$b = 2*$a

1050log10(sys.maxint)

Dougal
fonte
O(n)O(nlognlogm)
7

O(1)

O(logM)O(NlogN)O(NlogNlogM)

M

Erel Segal-Halevi
fonte
O(logm)O(logn)m
O(logN)
nnnn
Você está certo, eu corrigi minha resposta.
Erel Segal-Halevi
4

Eu diria que normalmente assumimos operações aritméticas O (1) porque geralmente fazemos coisas no contexto de números inteiros de 32 bits ou de 64 bits ou números de ponto flutuante IEEE 754. O (1) é provavelmente uma boa aproximação para esse tipo de aritmética.

Mas, em geral, isso não é verdade. Em geral, você precisa de um algoritmo para executar adição, subtração, multiplicação e divisão. Boolos, Burgess e Jefferies ' Computability and Logic vêm à mente como uma maneira de entender a (s) prova (s) disso, em termos de dois sistemas formais diferentes, Funções Recursivas e Máquinas de Ábaco, pelo menos na minha cópia da 4ª Edição.

Você pode consultar os termos do cálculo lambda para subtração e divisão com Numerais da Igreja para obter uma explicação fácil de ver por que essas duas operações não são O (1). É um pouco mais difícil ver adição, multiplicação e exponenciação, mas existe se você considerar a forma dos números da igreja.

Bruce Ediger
fonte