Estou resolvendo uma questão de algoritmo e minha análise é que ela seria executada em O (2 ^ sqrt (n)). Quão grande é isso? Equivale a O (2 ^ n)? Ainda é hora não polinomial?
Estou resolvendo uma questão de algoritmo e minha análise é que ela seria executada em O (2 ^ sqrt (n)). Quão grande é isso? Equivale a O (2 ^ n)? Ainda é hora não polinomial?
Respostas:
Esta é uma pergunta interessante. Felizmente, depois de saber como resolvê-lo, não é particularmente difícil.
Para as funções f : N → R + e g : N → R + , temos f ∈ S ( g ) se e só se sup lim n → ∞ f ( n ) / g ( n ) ∈ R .
Uma função f : N → R + tem no máximo crescimento polinomial se e somente se existir uma constante k ∈ N tal que f ∈ O ( n ↦ n k ). Vamos resolver isso para k ∈ N arbitrário, mas fixo .
lim sup n → ∞ 2 ( n 1/2 ) / n k =
lim n → ∞ 2 ( n 1/2 ) / n k =
lim n → ∞ e log (2) n 1/2 / e log ( n ) k =
lim n → log e log (2) n 1/2 - log ( n ) k = ∉ R
A primeira igualdade é verdadeira porque ambos, o nominador e o denominador, estão monotonicamente crescendo funções estáveis. A segunda igualdade usa a identidade x y = e log ( x ) y . O limite não é finito porque o expoente na expressão final não está delimitado acima. Sem fornecer uma prova formal, pode-se presumir que n 1/2 domina log ( n ) assintoticamente. Portanto, a função em questão excede o crescimento polinomial.
No entanto, seu crescimento é estritamente menor que exponencial, onde exponencial é definido (por mim, para esse propósito) como O ( n ↦ 2 c n ) para c > 0. Mostrar isso é ainda mais direto.
lim sup n → c 2 c n / 2 ( n 1/2 ) = lim n → ∞ 2 c n - n 1/2 = ∉ ∉ R
para qualquer c fixo > 0. Portanto, a complexidade da função está em algum lugar entre polinômio e exponencial.
Quão grande é isso? Bem, O (2 ^ sqrt (n)) é exatamente quão grande é :-(
Para se ter uma idéia do que isso significa, imagine que seu algoritmo não seria apenas O (2 ^ sqrt (n)), mas que na verdade leva precisamente 2 ^ sqrt (n) nanossegundos no seu computador:
n = 100: 2 ^ 10 = 1024 nanossegundos. Não há tempo. n = 1000: 2 ^ 31.xxx = 2 bilhões de nanossegundos. Dois segundos, isso é perceptível. n = 10.000: 2 ^ 100 × 10 ^ 30 nanossegundos = 10 ^ 21 segundos = 30 trilhões de anos.
Isso é muito melhor do que 2 ^ n nanossegundos, em que n = 100 levaria 30 trilhões de anos, mas ainda assim o tamanho dos problemas que você pode resolver é bastante limitado. Se você considera um problema "solucionável" se o seu computador puder resolvê-lo em uma semana, isso equivale a cerca de 6 x 10 ^ 14 nanossegundos, ou seja, n = 2.400. Por outro lado, até n = 400 podem ser resolvidos em um milissegundo.
(Na prática, para n = 10.000, O (2 ^ sqrt (n)) e O (2 ^ n) levam exatamente o mesmo tempo: muito tempo para esperar por isso.)
Excede qualquer polinômio. Pegue outro algoritmo, levando n ^ 1000 segundos. O que é praticamente insolúvel para n = 2. Esse algoritmo leva mais tempo até n ser cerca de 885 milhões. Mas sério, quem se importa? Nesse ponto, o número de anos que os dois algoritmos levam é um número de 9.000 dígitos.