venerdì 22 dicembre 2023

CORSO DAL PROBLEMA ALL'ALGORITMO: Lezione 1 Introduzione ai Fondamenti degli Algoritmi

Introduzione ai Fondamenti degli Algoritmi

1.1 Concetti di base degli algoritmi

Definizione di Algoritmo:

Un algoritmo è una serie ordinata e finita di istruzioni che definiscono un procedimento o una sequenza di passaggi logici per risolvere un determinato problema. Le sue caratteristiche principali includono:

Correttezza: Un algoritmo deve produrre risultati corretti per tutti gli input validi, risolvendo il problema in modo accurato e senza errori.

Determinismo: Ogni passaggio dell'algoritmo deve essere definito in modo preciso e non ambiguo, producendo lo stesso risultato per uno stesso input ogni volta che viene eseguito.

Finitudine: L'algoritmo deve terminare dopo un numero finito di passaggi, producendo una soluzione entro un tempo ragionevole.

Struttura di un Algoritmo:

Un algoritmo è composto da una struttura generale che comprende:

Input: I dati di input su cui l'algoritmo opera per risolvere il problema.

Output: Il risultato ottenuto dopo l'esecuzione dell'algoritmo.

Passi Intermedi: La sequenza di passaggi logici che trasformano gli input negli output desiderati.

Caratteristiche degli Algoritmi Efficaci:

Un algoritmo efficace dimostra le seguenti qualità:

Comprensibilità: Deve essere chiaro e comprensibile, in modo che sia facilmente interpretabile da chi lo legge.

Correttezza: Deve risolvere il problema in modo accurato, producendo risultati validi e corretti.

Efficienza nel Tempo e nello Spazio: Dovrebbe impiegare un tempo ragionevole per eseguire e utilizzare una quantità accettabile di memoria o risorse.


1.2 Strutture dati comuni

Array e Liste:

Array: È una struttura dati omogenea che memorizza elementi dello stesso tipo in posizioni contigue di memoria. Le operazioni di base includono l'accesso casuale agli elementi (O(1)), l'inserimento/eliminazione in posizioni specifiche (O(n) in caso di spostamento degli elementi) e la loro dimensione fissa.

Liste: Sono strutture dati dinamiche in cui gli elementi sono memorizzati in nodi collegati. Le liste possono essere implementate come liste concatenate o liste doppiamente concatenate. Consentono l'inserimento/eliminazione in qualsiasi punto con complessità O(1) (se si conosce il punto), ma l'accesso casuale richiede tempo lineare O(n).

Pile, Coda e Strutture dati collegate:

Pila (Stack): Una struttura dati LIFO (Last-In, First-Out) dove gli elementi possono essere inseriti e rimossi solo dalla cima. Le operazioni principali sono push (inserimento) e pop (rimozione) con complessità O(1).

Coda (Queue): Una struttura dati FIFO (First-In, First-Out) in cui gli elementi possono essere inseriti solo alla fine e rimossi dall'inizio. Le operazioni principali sono enqueue (inserimento) e dequeue (rimozione) con complessità O(1).

Strutture Dati Collegate: Includono liste collegate, dove i nodi sono collegati tra loro. Le operazioni dipendono dal tipo di lista, ad esempio, l'inserimento/eliminazione in testa richiede O(1), mentre in coda richiede O(n).


1.3 Complessità computazionale

Notazione O Grande (Big O):

Notazione Big O: È una notazione utilizzata per descrivere il limite superiore dell'efficienza (temporale o spaziale) di un algoritmo in base alla dimensione dell'input. Indica il comportamento asintotico dell'algoritmo.

Interpretazione della Notazione: Un'indicazione di O(f(n)) significa che l'algoritmo ha un comportamento di crescita non peggiore di f(n) per un dato input n. Ad esempio, O(n^2) indica un comportamento quadratico.

Classi di Complessità:

O(1): Costante, l'algoritmo richiede un tempo costante indipendentemente dalle dimensioni dell'input.

O(log n): Logaritmico, l'efficienza cresce in modo logaritmico rispetto alle dimensioni dell'input.

O(n): Lineare, il tempo di esecuzione cresce linearmente rispetto alle dimensioni dell'input.

O(n^2): Quadratico, l'efficienza cresce quadraticamente rispetto alle dimensioni dell'input.

Esempi e Casi d'Uso: Ad esempio, O(1) può essere associato all'accesso casuale in un array, mentre O(n^2) può essere relativo a un algoritmo di ordinamento bubble sort.

Analisi della Complessità:

Importanza dell'Analisi della Complessità: Valutare la complessità degli algoritmi è cruciale per comprendere le prestazioni relative. Un algoritmo con una complessità inferiore potrebbe essere preferibile per dati di grandi dimensioni.

Considerazioni nella Progettazione: L'analisi della complessità aiuta a progettare algoritmi efficienti, ottimizzando le risorse e riducendo i tempi di esecuzione.


Nessun commento:

Posta un commento