Sto risolvendo una domanda dell'algoritmo e la mia analisi è che sarebbe eseguita su O (2 ^ sqrt (n)). Quanto è grande? Equivale a O (2 ^ n)? È ancora tempo non polinomiale?
Sto risolvendo una domanda dell'algoritmo e la mia analisi è che sarebbe eseguita su O (2 ^ sqrt (n)). Quanto è grande? Equivale a O (2 ^ n)? È ancora tempo non polinomiale?
Risposte:
Questa è una domanda interessante Fortunatamente, una volta che sai come risolverlo, non è particolarmente difficile.
Per le funzioni f : N → R + e g : N → R + , abbiamo f ∈ O ( g ) se e solo se lim sup n → ∞ f ( n ) / g ( n ) ∈ R .
Una funzione f : N → R + ha al massimo una crescita polinomiale se e solo se esiste una costante k ∈ N tale che f ∈ O ( n ↦ n k ). Risolviamolo per k ∈ N arbitrario ma fisso .
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 → ∞ e log (2) n 1/2 - log ( n ) k = ∞ ∉ R
La prima uguaglianza è vera perché entrambi, il nominatore e il denominatore, sono funzioni fisse in crescita monotona. La seconda uguaglianza usa l'identità x y = e log ( x ) y . Il limite non è finito perché l'esponente nell'espressione finale non è limitato sopra. Senza fornire una prova formale, si può presumere che n 1/2 domini asintoticamente log ( n ). Pertanto, la funzione in questione supera la crescita polinomiale.
Tuttavia, la sua crescita è strettamente inferiore a quella esponenziale, in cui l'esponenziale è definito (da me, a questo scopo) come O ( n ↦ 2 c n ) per c > 0. Mostrare ciò è ancora più semplice.
lim sup n → ∞ 2 c n / 2 ( n 1/2 ) = lim n → ∞ 2 c n - n 1/2 = ∞ ∉ R
per qualsiasi fisso c > 0. Pertanto, la complessità della funzione è davvero in qualche punto tra polinomio ed esponenziale.
Quanto è grande? Bene, O (2 ^ sqrt (n)) è esattamente quanto è grande :-(
Per avere un'idea di cosa significhi, immagina che il tuo algoritmo non sarebbe solo O (2 ^ sqrt (n)), ma che in realtà richiede esattamente 2 ^ sqrt (n) nanosecondi sul tuo computer:
n = 100: 2 ^ 10 = 1024 nanosecondi. Non c'è tempo. n = 1000: 2 ^ 31.xxx = 2 miliardi di nanosecondi. Due secondi, è evidente. n = 10.000: 2 ^ 100 ≈ 10 ^ 30 nanosecondi = 10 ^ 21 secondi = 30 trilioni di anni.
È molto meglio di 2 ^ n nanosecondi, dove n = 100 richiederebbe 30 trilioni di anni, ma la dimensione dei problemi che è possibile risolvere è piuttosto limitata. Se consideri un problema "risolvibile" se il tuo computer è in grado di risolverlo in una settimana, si tratta di circa 6 x 10 ^ 14 nanosecondi, ovvero circa n = 2.400. D'altra parte, fino a n = 400 può essere risolto in un millisecondo.
(In pratica, per n = 10.000 sia O (2 ^ sqrt (n)) che O (2 ^ n) impiegano esattamente lo stesso tempo: troppo tempo per aspettarlo.)
Supera qualsiasi polinomio. Prendi un altro algoritmo che impiega n ^ 1000 secondi. Che è praticamente irrisolvibile per n = 2. Questo algoritmo richiede più tempo fino a quando n è di circa 885 milioni. Ma davvero, a chi importa? A quel punto il numero di anni necessari per entrambi gli algoritmi è un numero di 9000 cifre.