Cosa significa un algoritmo più veloce in informatica teorica?


18

Se esiste un algoritmo in esecuzione nel tempo per qualche problema A, e qualcuno trova un algoritmo in esecuzione nel tempo, , dove , è considerato un miglioramento rispetto all'algoritmo precedente?O(f(n))O(f(n)/g(n))g(n)=o(f(n))

Ha senso, nel contesto dell'informatica teorica, elaborare un simile algoritmo?


4
Con "algoritmo più veloce" intendiamo "algoritmo asintoticamente più veloce".
Yuval Filmus,

@YuvalFilmus cosa intendi con "asintoticamente"
non definito

1
In esecuzione nel tempo . o(f(n))
Yuval Filmus,

Risposte:


26

No, un algoritmo in esecuzione nel tempo , dove , non è necessariamente considerato un miglioramento. Ad esempio, supponiamo che e . Quindi è un limite di tempo peggiore di .O(f(n)/g(n))g(n)=o(f(n))f(n)=ng(n)=1/nO(f(n)/g(n))=O(n2)O(f(n))=O(n)

Per migliorare un algoritmo in esecuzione nel tempo , devi trovare un algoritmo in esecuzione nel tempo , cioè nel tempo per alcune funzioni .o ( f ( n ) ) g ( n ) g ( n ) = o ( f ( n ) )f(n)o(f(n))g(n)g(n)=o(f(n))

Se tutto ciò che sai è che un algoritmo viene eseguito nel tempo , non è chiaro se un algoritmo eseguito nel tempo sia un miglioramento, qualunque sia sono. Questo perché la grande O è solo un limite superiore del tempo di esecuzione. Invece, è comune considerare il tempo della complessità nel caso peggiore, e stimare come un grande e non solo come un grande .O ( g ( n ) ) f ( n ) , g ( n ) Θ OO(f(n))O(g(n))f(n),g(n)ΘO


21
Potrebbe essere meglio prendere nel tuo primo paragrafo. L'uso di una funzione decrescente sembra un po 'ingannevole. g(n)=1
David Richerby,

1
@DavidRicherby: Forse un po ', ma OP non ha mai detto di avere un algoritmo in esecuzione in quindi la monotonia non può essere assunta. O(g(n))
Kevin,

7
@Kevin Certo, ma il contesto è l'informatica e, nell'informatica, la notazione big-O viene solitamente utilizzata per funzioni non decrescenti. Probabilmente il richiedente stava pensando in quei termini.
David Richerby,

11

Ricordare che Notazione è pensato per analizzare come l'attività cresce per diverse dimensioni di ingresso, e specificamente tralascia fattori moltiplicativi, di ordine inferiore termine e costanti.O(...)

Supponiamo di avere un algoritmo cui tempo di esecuzione effettivo è 1 n 2 + 2 n + 1 (supponendo che si possano effettivamente contare le istruzioni e conoscere i tempi esatti e così via, il che è certamente un presupposto enorme nei sistemi moderni). Supponiamo quindi di trovare un nuovo algoritmo che sembra essere O ( n ) , ma il tempo di esecuzione effettivo è 1000 n + 5000 . Supponiamo anche che tu sappia che il software per utilizzare questo algoritmo non vedrà mai una dimensione del problema di n > 10 .O(n2)1n2+2n+1O(n)1000n+5000n>10

Quindi, quale sceglieresti - l' algoritmo che impiegherà 15000 unità di tempo o quello O ( n 2 ) che prenderà solo 121 unità? Ora se il tuo software evolve per gestire dimensioni problematiche di n > 100000 , quale sceglieresti? Cosa faresti se le dimensioni del tuo problema variano notevolmente?O(n)O(n2)n>100000


2
"mai vedere una dimensione del problema di n> 10" - quindi non
useremmo

5
@AnoE Numeri semplici a fini di discussione. La stessa logica si applica sia per l'analisi di una dimensione del problema di 10 contro 1e5 o per l'analisi per 1e6 contro 1e9.
twalberg,

1
@AnoE La maggior parte dei programmi per computer non tenta di gestire una dimensione del problema infinitamente crescente. Quindi ci sarà un compromesso. Ecco perché big-O è per l' informatica teorica e i concetti possono essere applicati per migliorare i programmi attuali.
mbomb007,

Esatto, @ mbomb007. Il titolo della domanda è "Cosa significa un algoritmo più veloce in informatica teorica ?" e ha questo nel corpo: "Ha senso, nel contesto dell'informatica teorica ...".
AnoE

@AnoE Per esperienza, la notazione O viene usata quando n <10 sempre! Non che sia una buona idea ... ma è totalmente qualcosa che viene fatto!
Cort Ammon - Ripristina Monica il

5

In genere, ciò significa che, per qualsiasi dimensione di input sufficientemente grande, il tempo di esecuzione nel peggiore dei casi del vecchio algoritmo è più lento di quello nuovo. Ciò equivale al formalismo , dove g è la complessità temporale del nuovo algoritmo e f la complessità temporale del vecchio.g(n)o(f(n))gf

A volte, tuttavia, gli informatici si preoccupano delle prestazioni nel caso medio. L'esempio classico è Quicksort: il suo runtime nel caso peggiore è mentre ne conosciamo altri che girano in Θ ( n log n ) tempo, ma è ampiamente utilizzato nella pratica a causa del suo buon tempo medio di esecuzione. Può inoltre essere ottimizzato per l'esecuzione molto rapida nei casi più frequenti in natura, ad esempio array che sono per lo più nell'ordine giusto.Θ(n2)Θ(nlogn)

E a volte, anche gli informatici teorici usano "più velocemente" allo stesso modo delle persone normali. Ad esempio, la maggior parte delle implementazioni delle classi String ha l'ottimizzazione delle stringhe corte (anche chiamata ottimizzazione delle stringhe piccole), anche se accelera le cose solo per le stringhe brevi ed è un overhead puro per quelle più lunghe. Man mano che le dimensioni dell'input diventano sempre più grandi, il tempo di esecuzione di un'operazione String con SSO sarà maggiore di un piccolo termine costante, quindi per la definizione che ho dato nel primo paragrafo, la rimozione di SSO da una classe String rende “più veloce . ”In pratica, tuttavia, la maggior parte delle stringhe sono piccole, quindi SSO rende la maggior parte dei programmi che le usano più velocemente, e la maggior parte dei professori di informatica sanno meglio che andare in giro chiedendo che le persone parlino solo di ordini di complessità temporale asintotica .


1

Non esiste una definizione unificata di cosa sia un "algoritmo più veloce". Non esiste un organo di governo che decide se un algoritmo è più veloce di un altro.

Per sottolineare perché, vorrei offrire due diversi scenari che dimostrano questo concetto oscuro.

Il primo esempio è un algoritmo che cerca un elenco collegato di dati non ordinati. Se riesco a fare la stessa operazione con un array, non ho alcun cambiamento sulla grande misura Oh delle prestazioni. Entrambe le ricerche sono O (n). Se guardo solo i grandi valori di Oh, potrei dire che non ho fatto alcun miglioramento. Tuttavia, è noto che nella maggior parte dei casi le ricerche di array sono più rapide di un elenco collegato, quindi si potrebbe decidere che ciò ha reso un algoritmo "più veloce", anche se il grande Oh non è cambiato.

Se posso usare il tradizionale esempio di programmazione di un robot per creare un sandwich PBJ, posso mostrare cosa intendo in un altro modo. Considera solo il punto in cui si sta aprendo il barattolo di burro di arachidi.

Pick up the jar
Grab the lid
Unscrew the lid

Contro

Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Put the jar back down
Pick up the jar
Grab the lid
Unscrew the lid

Anche nell'impostazione teorica più accademica che mi viene in mente, scoprirai che le persone accettano che il primo algoritmo è più veloce del secondo, anche se i grandi risultati della notazione Oh sono gli stessi.

Al contrario, possiamo considerare un algoritmo per violare la crittografia RSA. Al momento, si percepisce che questo processo è probabilmente O (2 ^ n), dove n è il numero di bit. Considera un nuovo algoritmo che esegue n ^ 100 più velocemente Ciò significa che il mio nuovo processo viene eseguito in O (2 ^ n / n ^ 100). Tuttavia, nel mondo della crittografia, una velocizzazione polinomiale verso un algoritmo esponenziale non è tradizionalmente considerata una velocità teorica. Quando si eseguono prove di sicurezza, si presume che un utente malintenzionato possa scoprire una di queste accelerazioni e che non avrà alcun effetto.

Quindi in una circostanza, possiamo cambiare una O (n) in O (n) e chiamarla più velocemente. In una diversa circostanza, possiamo cambiare una O (2 ^ n) in O (2 ^ n / n ^ 100) e affermare che non c'è stata alcuna accelerazione significativa. Questo è il motivo per cui dico che non esiste una definizione unificata per un "algoritmo più veloce". È sempre contestualmente dipendente.


1

A(n)O(f(n))

 0cf< lim supnA(n)f(n)=cf

Supponiamo ora che stiamo parlando di una funzione arbitrariamente crescente dove e creiamo la funzione .lim sup n g ( n ) = h ( n ) = f ( n )g(n)lim supng(n)=h(n)=f(n)g(n)

A(n)O(h(n))A(n)O(h(n))

 0ch< lim supnA(n)h(n)=ch

Utilizzando le regole dei limiti, possiamo anche scrivere:

ch=lim supnA(n)h(n)=lim supnA(n)g(n)f(n)=cflim supng(n)

ch<cf=0

L'affermazione contrapposta è: Se , allora .A ( n ) O ( h ( n ) )cf0A(n)O(h(n))

In parole, è un "miglioramento" su nelle condizioni aggiuntive che e stanno aumentando arbitrariamente.A ( n ) A ( n ) Θ ( f ( n ) ) g ( n )A(n)A(n)A(n)Θ(f(n))g(n)

Inoltre, questo dovrebbe mostrare perché l'affermazione secondo cui non è abbastanza forte da trarre una conclusione sul fatto che sia un "miglioramento". In breve, potrebbe già essere in .A ( n ) A ( n ) O ( h ( n ) )A(n)O(f(n))A(n)A(n)O(h(n))


1
Il tuo limite dovrebbe essere superiore al limite.
Yuval Filmus,

1
@YuvalFilmus Aggiornato
Jared Goguen
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.