venerdì 22 dicembre 2023

CORSO DAL PROBLEMA ALL’ALGORITMO: Lezione 6 Algoritmi Greedy

Algoritmi Greedy

6.1 Principi fondamentali degli algoritmi greedy

Principi Fondamentali degli Algoritmi Greedy:

Scelta Ottimale Locale:


Gli algoritmi greedy operano prendendo la scelta migliore disponibile in ogni passaggio, senza considerare le conseguenze delle scelte future.

Ogni scelta effettuata è localmente ottimale, cioè sembra essere la migliore in quel momento, senza ricorrere a ulteriori ricalcoli o valutazioni.

Speranza di Ottimalità Globale:


La caratteristica fondamentale degli algoritmi greedy è la speranza che una serie di scelte localmente ottimali porti a una soluzione globalmente ottimale.

Non eseguono "backtracking" o revisioni delle scelte precedenti in quanto si basano sull'assunzione che le scelte fatte non debbano essere cambiate in seguito.

Non sempre producono la soluzione ottimale assoluta:


La scelta locale ottimale in ogni passaggio potrebbe non portare sempre a una soluzione complessivamente ottimale per alcuni problemi.

Tuttavia, in molte situazioni, gli algoritmi greedy forniscono soluzioni vicine all'ottimo o sufficientemente buone per l'utilizzo pratico.

Adattabilità al problema:


Gli algoritmi greedy sono adatti a problemi in cui le scelte localmente ottimali contribuiscono alla soluzione globale ottimale senza dover considerare il contesto complessivo del problema.

Applicazioni degli Algoritmi Greedy:

Algoritmi di Routing: Come l'algoritmo di Dijkstra per la ricerca del percorso più breve nei grafi pesati.

Problemi di Allocazione: Come il problema della programmazione degli orari o l'allocazione di risorse.

Problemi di Compressione: Come l'algoritmo di Huffman per la compressione dei dati.

Algoritmi di Selezione: Come l'algoritmo di selezione delle attività o il problema dello zaino (Knapsack problem) in certi casi specifici.

Limitazioni degli Algoritmi Greedy:

Non sempre garantiscono la soluzione ottimale: Poiché fanno scelte localmente ottimali in ogni passaggio, potrebbero non condurre alla soluzione ottimale per tutti i tipi di problemi.

Richiedono analisi accurata: La scelta dell'algoritmo greedy richiede una profonda comprensione del problema per identificare se l'approccio greedy porta a una soluzione accettabile o ottimale.


6.2 Applicazioni degli algoritmi greedy

Esplorerò in dettaglio l'applicazione degli algoritmi greedy nel problema della selezione di attività e negli algoritmi di compressione dati, focalizzandomi sull'algoritmo di Huffman.


Selezione di Attività:

Il problema della selezione di attività coinvolge la scelta di un sottoinsieme massimale di attività non sovrapposte, massimizzando il numero di attività eseguite.


Approccio Greedy:


Gli algoritmi greedy offrono un metodo efficace per risolvere questo problema. Si basano sull'idea di selezionare in ogni passaggio l'attività con l'orario di fine più precoce tra quelle ancora disponibili.

L'obiettivo è massimizzare il numero totale di attività selezionate senza sovrapposizioni.

Algoritmo:


Ordina le attività in base all'orario di fine in modo crescente.

Inizia selezionando la prima attività con l'orario di fine più precoce.

Itera sulle attività rimanenti, selezionando ogni volta la successiva con l'orario di inizio successivo all'orario di fine dell'ultima attività selezionata.

Esempio:

Supponiamo di avere le seguenti attività con orari di inizio e fine:


scss

Copy code

(1, 4), (3, 5), (0, 6), (5, 7), (3, 8), (5, 9), (6, 10), (8, 11), (8, 12), (2, 13), (12, 14)

Se applichiamo l'algoritmo greedy, selezioneremo le attività:


scss

Copy code

(1, 4), (5, 7), (8, 11), (12, 14)

Questo insieme di attività non sovrapposte massimizza il numero totale di attività eseguite.


Algoritmi di Compressione (Algoritmo di Huffman):

Approccio Greedy:


Gli algoritmi di compressione senza perdita come l'algoritmo di Huffman utilizzano l'approccio greedy per la compressione dei dati.

L'obiettivo è creare una rappresentazione più compatta dei dati, assegnando codici di lunghezza variabile ai simboli in modo che i simboli più frequenti siano rappresentati da codici più corti.

Algoritmo di Huffman:


Analizza la frequenza di ogni simbolo nel set di dati da comprimere.

Costruisce un albero binario completo in base alle frequenze, assegnando codici binari di lunghezza variabile ai simboli.

I simboli più frequenti ottengono codici più corti, mentre i simboli meno frequenti ottengono codici più lunghi.

Esempio:

Supponiamo di avere un insieme di caratteri con le seguenti frequenze:


yaml

Copy code

A: 8, B: 3, C: 1, D: 4, E: 11

L'algoritmo di Huffman costruirebbe un albero binario completo attribuendo codici binari di lunghezza variabile ai caratteri, dove i caratteri più frequenti avranno codici più corti.


A potrebbe essere '0', B '110', C '1110', D '10', E '1111' (ad esempio).

In questo modo, si ottiene una rappresentazione compatta per rappresentare i dati originali, riducendo la lunghezza complessiva della esplorerò due studi di caso che illustrano l'uso di algoritmi greedy in contesti specifici: l'algoritmo della moneta per il cambio di monete e l'algoritmo del percorso minimo come l'algoritmo di Dijkstra per trovare il percorso più breve in un grafo ponderato.


Studio di Caso: Algoritmo della Moneta

Problema del Cambio di Monete:


L'obiettivo è restituire il cambio con il minor numero di monete possibile.

Date un insieme di monete di diversi valori e un importo da restituire come cambio, l'obiettivo è minimizzare il numero di monete necessarie.

Approccio Greedy:


L'approccio greedy in questo caso coinvolge la selezione avida delle monete di valore più alto possibile per soddisfare l'importo richiesto.

Si inizia selezionando la moneta di valore più alto possibile che non superi l'importo da restituire, riducendo progressivamente l'importo finché non si raggiunge zero.

Esempio:

Supponiamo di avere monete di valore [1, 5, 10, 25, 50] e dobbiamo restituire 63 centesimi. Utilizzando l'approccio greedy, selezioneremo le monete come segue:


50 (1 moneta), 10 (1 moneta), 1 (3 monete).

Numero totale di monete: 5.

Studio di Caso: Algoritmo del Percorso Minimo

Problema del Percorso Minimo in un Grafo Ponderato:


L'obiettivo è trovare il percorso più breve tra due nodi in un grafo ponderato, dove il peso degli archi rappresenta la distanza tra i nodi.

Approccio Greedy:


L'algoritmo di Dijkstra è un esempio di approccio greedy utilizzato per risolvere questo problema.

Si basa sulla scelta avida del percorso con il peso più basso disponibile in ogni passaggio fino a raggiungere la destinazione.

Esempio:

Supponiamo di avere un grafo pesato con pesi sugli archi che rappresentano le distanze tra i nodi. Utilizzando l'algoritmo di Dijkstra, troveremo il percorso più breve tra due nodi specifici.


Ad esempio, in un grafo stradale, l'algoritmo di Dijkstra troverà il percorso più breve tra due città basato sulla lunghezza delle strade (peso degli archi).

Approfondimento:

L'algoritmo della moneta basato sull'approccio greedy funziona correttamente solo con determinati set di valori di monete (ad esempio, monete con denominazioni in cui le monete di valore più grande sono multipli delle monete di valore più piccolo).

L'algoritmo di Dijkstra garantisce la ricerca del percorso più breve solo se tutti i pesi degli archi sono non negativi.

Entrambi gli algoritmi dimostrano come l'approccio greedy possa essere applicato con successo a problemi specifici, ma richiedono attenzione alle limitazioni e alle condizioni specifiche per ottenere risultati corretti.

In sintesi, questi studi di caso illustrano l'efficacia degli algoritmi greedy nel risolvere problemi specifici come il cambio di monete e la ricerca del percorso più breve in un grafo ponderato. Tuttavia, è importante considerare le condizioni di utilizzo e le limitazioni per ottenere risultati corretti e ottimali.

 dei dati.


6.3 Analisi di casi di studio

esplorerò due studi di caso che illustrano l'uso di algoritmi greedy in contesti specifici: l'algoritmo della moneta per il cambio di monete e l'algoritmo del percorso minimo come l'algoritmo di Dijkstra per trovare il percorso più breve in un grafo ponderato.


Studio di Caso: Algoritmo della Moneta

Problema del Cambio di Monete:


L'obiettivo è restituire il cambio con il minor numero di monete possibile.

Date un insieme di monete di diversi valori e un importo da restituire come cambio, l'obiettivo è minimizzare il numero di monete necessarie.

Approccio Greedy:


L'approccio greedy in questo caso coinvolge la selezione avida delle monete di valore più alto possibile per soddisfare l'importo richiesto.

Si inizia selezionando la moneta di valore più alto possibile che non superi l'importo da restituire, riducendo progressivamente l'importo finché non si raggiunge zero.

Esempio:

Supponiamo di avere monete di valore [1, 5, 10, 25, 50] e dobbiamo restituire 63 centesimi. Utilizzando l'approccio greedy, selezioneremo le monete come segue:


50 (1 moneta), 10 (1 moneta), 1 (3 monete).

Numero totale di monete: 5.

Studio di Caso: Algoritmo del Percorso Minimo

Problema del Percorso Minimo in un Grafo Ponderato:


L'obiettivo è trovare il percorso più breve tra due nodi in un grafo ponderato, dove il peso degli archi rappresenta la distanza tra i nodi.

Approccio Greedy:


L'algoritmo di Dijkstra è un esempio di approccio greedy utilizzato per risolvere questo problema.

Si basa sulla scelta avida del percorso con il peso più basso disponibile in ogni passaggio fino a raggiungere la destinazione.

Esempio:

Supponiamo di avere un grafo pesato con pesi sugli archi che rappresentano le distanze tra i nodi. Utilizzando l'algoritmo di Dijkstra, troveremo il percorso più breve tra due nodi specifici.


Ad esempio, in un grafo stradale, l'algoritmo di Dijkstra troverà il percorso più breve tra due città basato sulla lunghezza delle strade (peso degli archi).

Approfondimento:

L'algoritmo della moneta basato sull'approccio greedy funziona correttamente solo con determinati set di valori di monete (ad esempio, monete con denominazioni in cui le monete di valore più grande sono multipli delle monete di valore più piccolo).

L'algoritmo di Dijkstra garantisce la ricerca del percorso più breve solo se tutti i pesi degli archi sono non negativi.

Entrambi gli algoritmi dimostrano come l'approccio greedy possa essere applicato con successo a problemi specifici, ma richiedono attenzione alle limitazioni e alle condizioni specifiche per ottenere risultati corretti.

In sintesi, questi studi di caso illustrano l'efficacia degli algoritmi greedy nel risolvere problemi specifici come il cambio di monete e la ricerca del percorso più breve in un grafo ponderato. Tuttavia, è importante considerare le condizioni di utilizzo e le limitazioni per ottenere risultati corretti e ottimali.


Nessun commento:

Posta un commento