Intuizione algoritmica per complessità logaritmica


60

Credo di avere una ragionevole comprensione di complessità come , Θ ( n ) e Θ ( n 2 ) .O(1)Θ(n)Θ(n2)

In termini di un elenco, è una ricerca costante, quindi sta solo diventando il capo dell'elenco. Θ ( n ) è dove avrei camminato sull'intero elenco, e Θ ( n 2 ) sta camminando sull'elenco una volta per ogni elemento dell'elenco.O(1)Θ(n)Θ(n2)

Esiste un modo intuitivo simile per cogliere oltre a sapere che si trova da qualche parte tra O ( 1 ) e Θ ( n ) ?Θ(logn)O(1)Θ(n)


8
log n è per "cercare": pensa alla ricerca binaria
Suresh

2
L'uso di per porre questa domanda non è corretto, poiché indica solo un limite superiore. Ad esempio il tempo costante è O ( log n ) . θ sarebbe più appropriato. Vedi la meta domanda: meta.cs.stackexchange.com/questions/182/…OO(logn)θ
Aryabhata


Una piccola nota: nelle impostazioni classiche di Turing Machine, tutti gli algoritmi sono , poiché devono leggere ogni simbolo dell'ingresso almeno una volta. La ricerca binaria può essere eseguita in O ( log n ) perché abbiamo la promessa che l'elenco è ordinato, ad esempio. Ω(n)O(logn)
Chazisop,

1
Un contributo tardivo: per definizione, il logaritmo di base di un numero n è solo il numero di volte che moltiplichi b da solo per ottenere n . b l = nbnbn . Ad esempio, 2 3 = 8bl=nl=logb(n) . Quindi se hai un numero n e vuoi scoprire cosa l o g b ( n ) = ? continua a dividerlo per b fino a raggiungere 1 (supponendo che n sia un potere di b per semplicità). Il numero di divisioni è uguale a l o g b ( n ) . Gli algoritmi che presentano questo comportamento di divisione hanno tempi di esecuzione in O ( l o g23=8log2(8)=3nlogb(n)=?b1nblogb(n) . O(log(n))
saadtaame,

Risposte:


54

Il la complessità è solitamente collegato con suddivisione. Quando usi elenchi come esempio, immagina un elenco i cui elementi sono ordinati. È possibile cercare in questo elenco in O ( log n ) time - in realtà non è necessario guardare ogni elemento a causa della natura ordinata dell'elenco.Θ(logn)O(logn)

Se si guarda l'elemento al centro dell'elenco e lo si confronta con l'elemento che si cerca, si può immediatamente dire se si trova nella metà sinistra o destra dell'array. Quindi puoi semplicemente prendere questa metà e ripetere la procedura fino a quando non la trovi o raggiungi un elenco con 1 elemento che banalmente confronti.

Puoi vedere che l'elenco dimezza efficacemente ogni passaggio. Ciò significa che se si ottiene un elenco di lunghezza , il numero massimo di passaggi necessari per raggiungere l'elenco di un elemento è 5 . Se hai un elenco di 128 = 2 7 elementi, hai bisogno solo di 7 passaggi, per un elenco di 1024 = 2 10 hai bisogno solo di 10 passaggi ecc.325128=2771024=21010

Come puoi vedere, l'esponente in 2 n mostra sempre il numero di passaggi necessari. Il logaritmo viene utilizzato per "estrarre" esattamente questo numero di esponente, ad esempio log 2 2 10 = 10 . Si generalizza anche per elencare lunghezze che non sono potenze di due lunghi.n2nlog2210=10


4
Va notato che questo è solo O(log n)se l'elenco ha un accesso casuale a tempo costante. Sulle implementazioni di elenchi più tipici (elenchi collegati) questo èO(n log n)
asm

1
La ricerca binaria non funziona sugli elenchi per mancanza di puntatori; di solito viene eseguito su array.
Raffaello

La ricerca binaria funziona bene sugli elenchi. È semplicemente inutile a causa dell'essere molto più complicato del necessario / utile / pratico.
Anton

@AndrewMyers La ricerca di un elenco collegato è più accurata O(n)
phant0m

1
@ phant0m Sì, mi ci è voluto un po 'per capire che si presume che ti sposti dalla posizione corrente invece di attraversare dall'inizio ogni volta.
asm

38

In termini di alberi (bilanciati) (diciamo, albero binario, quindi tutti i sono di base 2):log

  • sta ottenendo la radice dell'alberoΘ(1)
  • è una passeggiata dalla radice alla fogliaΘ(logn)
  • sta attraversando tutti i nodi dell'alberoΘ(n)
  • sono le azioni su tutti i sottoinsiemi di due nodi nella struttura, ad esempio il numero di percorsi diversi tra due nodi qualsiasi.Θ(n2)
  • - generalizzazione di quanto sopra per qualsiasi sottoinsieme di k nodi (per una costante k )Θ(nk)kk
  • sono le azioni su tutti i possibili sottoinsiemi di nodi (sottoinsiemi di tutte le dimensioni possibili, ovvero k = 1 , 2 , , n .). Ad esempio, il numero di diversisottoalberidell'albero.Θ(2n)k=1,2,,n

5
Per aggiungere a questo, intuizione per deriva da due cose: 1.) La ricorrenza T ( n ) = T ( Θ(loglogn)e 2.) Ricerca binaria su qualcosa di dimensionilog(n)cioè una ricerca binaria sull'altezza dell'albero. T(n)=T((n))+1log(n)
McCley,

17

Affinché sia possibile, è necessario essere in grado di ridurre le dimensioni del problema in modo proporzionale di una quantità arbitraria rispetto a n con un'operazione a tempo costante.O(logn)n

Ad esempio, nel caso della ricerca binaria, è possibile ridurre della metà la dimensione del problema ad ogni operazione di confronto.

Ora, devi dimezzare la dimensione del problema, in realtà no. Un algoritmo è anche se può ridurre lo spazio di ricerca del problema dello 0,0001%, finché la percentuale e l'operazione che utilizza per ridurre la dimensione del problema rimangono costanti, è un algoritmo O ( log n ) , non sarà un algoritmo veloce, ma è comunque O ( log n ) con una costante molto grande. (Supponendo che stiamo parlando del registro n con un registro di base 2)O(logn)O(logn)O(logn)logn


1
Cosa sarebbe se la "quantità ridotta" non fosse costante?
Svish,

@Svish Se riesci a ridurre il problema a una velocità positiva, sarebbe comunque un algoritmo , anche se probabilmente non sarebbe più un limite. Il tasso negativo è difficile da dire. Il presupposto è stato fatto per rendere la risposta piuttosto semplice in questo caso, poiché questa domanda ha il suo merito, sei più che benvenuto nel porre questa domanda da sola. O(logn)
Ken Li

Sì, intendevo dire che lo spazio di ricerca dei problemi è sempre diminuito, ma non necessariamente a un ritmo costante. Stavo solo pensando al tuo "fintanto che la percentuale e l'operazione che utilizza per ridurre la dimensione del problema rimangono costanti, è un algoritmo O (log n)"; se avesse un nome diverso se la percentuale non fosse costante.
Svish,


8

log(n)1n1nlog(n)

100210021002100100210021002100

10021001002100210021001002100log(n)n

Da dove vengono esponenti e logaritmi? Perché sono così interessanti per l'informatica? Potresti non accorgertene, ma l'esponente è ovunque. Hai pagato interessi sulla carta di credito? Hai appena pagato un universo per la tua casa (non così male, ma la curva si adatta). Mi piace pensare che l'espiazione provenga dalla regola del prodotto, ma altri sono invitati a fare più esempi. Qual è la regola del prodotto, potresti chiedere; E io risponderò.

ABCBCACDCAD2342421010242101010210101024

log2(n)nn2n2logb(n)bbnlog(n)nn

log(n)n


3
log(n)

3
Stavo cercando di dare un'intuizione su quanto fosse piccola.
Ravi,

5

O(logn)x

È ancora basato sulla dimensione dell'elenco, ma devi visitare solo una parte degli elementi.


4

Θ(lgkn)Θ(lgk+1n)

Θ(1)lgn

L' algoritmo di ricerca binaria è l'esempio classico.


1

L'intuizione è quante volte puoi dimezzare un numero, diciamo n, prima che sia ridotto a 1 è O (lg n).

Per la visualizzazione, prova a disegnarlo come un albero binario e conta il numero di livelli risolvendo questa progressione geometrica.

2^0+2^1+...+2^h = n

lognn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.