2. Andiamo più a fondo
• Il termine computazione deriva dal latino computare che significa sia "contare" sia
"tagliare" e ha diversi significati nella lingua italiana. Questo termine può essere
interpretato come l'azione di "fare i calcoli" o il "risultato di calcoli".
• Svolgere dei calcoli porta a soluzioni che in ambito informatico sono importanti nella
progettazione di algoritmi.
• Trovare un algoritmo efficiente può significare risparmiare tempo e denaro.
3. È molto complesso
• Per risparmiare come abbiamo detto
prima, tempo e denaro ci occorre risolvere
un algoritmo con la minima complessità.
• Tale algoritmo viene detto algoritmo
ottimo.
• Per complessità di un problema si
intende la complessità degli algoritmi
ottimi che lo risolvono.
4. Misuriamo la complessità
• Molto spesso risulta difficile giungere a una
formulazione della complessità di un
algoritmo.
• In questi casi sfruttiamo l'ordine di
grandezza della complessità, cioè la
valutazione complessiva per valori molto
grandi delle dimensioni del problema.
• Si tratta di complessità asintotica.
5. Complessità asintotica
• La complessità asintotica si esprime con la notazione matematica che si legge limite per
N che tende a infinito della funzione T(N).
• Si ottiene un'espressione in funzione di N che indica qual è il comportamento
asintotico dell'algoritmo.
6. Classi di complessità
• Possiamo individuare alcuni ordini di grandezza
per le funzioni T(N) che individuano le cosidette
classi di complessità.
• Complessità costante
• Complessità logaritmica
• Complessità lineare
• Complessità NLogN
• Complessità polinomiale
• Complessità esponenziale
7. Complessità costante
• La complessità costante indica la complessità degli algoritmi che eseguono lo stesso numero di operazioni
indipendentemente dalla dimensione dei dati di input.
8. Complessità logaritmica
• La Complessità logaritmica O(logN) indica la
complessità degli algoritmi che eseguono
un numero di operazioni proporzionale
int main(){
int a[N]={1,5,8,10,15};
int i=0, j=N-1, m, pos=-1;
do {
m=(i+j)/2;
if(a[m]==x)
pos=i;
else if (a[i]<x)
i=m+1;
else
j=m-1;
} while(i<=j && pos==-1);
if(pos!=-1)
cout<<"numero trovato in posizione: "<<pos<<endl;
else
cout<<"numero non trovato";
return 0;
}
9. Complessità lineare
• La Complessità lineare O(N) indica la complessità degli
algoritmi che eseguono un numero di operazioni
proporzionale a N, cioè proporzionale alle dimensione del
problema.
int main(){
int a[N];
int i, valore;
cout<<"inseriamo gli elementi nell'array: "<<endl;
for (i=0; i<N; i++){
cout<<"inserisci elemento: ";
cin>>a[i];
}
cout<<"Quale valore dobbiamo cercare?: ";
cin>>valore;
i=0;
while (valore!=a[i] && i<N-1) i++;
if (a[i]%valore==0)
cout<<" valore trovato in posizione: "<<i;
else
cout<<"valore non presente";
return 0; }
10. Complessità
NLogN
• La Complessità NlogN O(NlogN) è la
classe di molti algoritmi di
ordinamento.
• Un esempio di algoritmo che esprime
questo tipo di complessità è il QUICK
SORT oppure il MERGE SORT.
11. Complessità
polinomiale
• La caratteristica della Complessità polinomiale O(NK) è di
avere dimensioni del problema come base da elevare a un
esponente K.
int main()
{
int a[N],i,j,temp;
cout<<"Inserisci gli elementi:n";
for(i=0;i<N;i++)
cin>>a[i];
//ordino gli elementi
for(j=0;j<N-1;j++)
for(i=0;i<N-1;i++)
if(a[i]>a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
cout<<"Array ordinato con bubble sort:";
for(i=0;i<N;i++)
cout<<" "<<a[i];
return 0;
}
12. Complessità esponenziale
• La caratteristica della Complessità esponenziale O(KN) è di avere dimensioni del problema come
esponente. Il tipo di algoritmo usato è il Selection Sort
• int main()
{
• int i, j, min, temp;
• int a[N];
cout<<"Inserisci gli elementi:n";
for(i=0;i<N;i++)
cin>>a[i];
for(i=0;i<N-1;i++)
{
min=i;
for(j=i+1;j<N;j++)
if (a[j]<a[min])
min= j;
temp=a[min];
a[min]=a[i];
a[i]=temp;
}
• cout<<"Array ordinato con selection sort:";
for(i=0;i<N;i++)
cout<<" "<<a[i];
return 0;