Ecco come viene utilizzato:
1. Identificazione di sottoproblemi sovrapposti: La programmazione dinamica risolve i problemi abbattendoli in sottoproblemi più piccoli e sovrapposti. Se lo stesso sottoproblema si incontra più volte, la memorizzazione può prevenire il ricalcolo.
2. Schemazione dei risultati: Una struttura di dati, di solito una tabella hash (dizionario in Python) o un array, viene utilizzata per archiviare i risultati dei sottoproblemi. L'input al sottoproblema (ad esempio, i parametri di una funzione ricorsiva) funge da chiave e il risultato calcolato è il valore.
3. Verifica dei risultati memorizzati nella cache: Prima di calcolare la soluzione a un sottoproblema, l'algoritmo controlla l'archiviazione per vedere se il risultato è già disponibile. Se lo è, il risultato memorizzato nella cache viene restituito immediatamente.
4. Risultati di memorizzazione e restituzione: Se il risultato non è memorizzato nella cache, l'algoritmo lo calcola, lo memorizza nella struttura dei dati e quindi lo restituisce.
Esempio (sequenza Fibonacci):
Una soluzione ricorsiva ingenua per la sequenza di Fibonacci è altamente inefficiente a causa di ripetuti calcoli. La memorizzazione migliora drasticamente questo:
soluzione ricorsiva ingenua (inefficiente):
`` `Python
def fibonacci_naive (n):
Se n <=1:
restituire n
restituisce fibonacci_naive (n-1) + fibonacci_naive (n-2)
`` `
Soluzione ricorsiva memorizzata:
`` `Python
Memo ={} # Dizionario per la memorizzazione
def fibonacci_memo (n):
Se N in memo:
Return Memo [n]
Se n <=1:
risultato =n
altro:
risultato =fibonacci_memo (n-1) + fibonacci_memo (n-2)
Memo [n] =risultato
risultato di ritorno
`` `
Nella versione memorizzata:
* `Memo` memorizza numeri di fibonacci precedentemente calcolati.
* Prima di fare una chiamata ricorsiva, `Fibonacci_memo` controlla se il risultato per` n` è già in `memo`.
* Se lo è, il valore memorizzato viene restituito direttamente. Altrimenti, il risultato viene calcolato, memorizzato in `memo` e poi restituito.
Questo cambiamento trasforma un algoritmo esponenziale in un algoritmo a tempo lineare. La chiave sta evitando i calcoli ridondanti degli stessi numeri di Fibonacci più volte.
in sostanza: La memorizzazione trasforma un approccio di programmazione dinamica dall'alto verso il basso (ricorsivo) in uno più efficiente nella cache di risultati intermedi. Completa gli approcci di tabulazione (bottom-up), che evitano anche calcoli ridondanti ma utilizza metodi iterativi anziché ricorsione. La scelta tra memorizzazione e tabulazione dipende spesso dal problema specifico e dalla preferenza del programmatore; Entrambi raggiungono lo stesso obiettivo di evitare calcoli ridondanti.
Programmazione © www.354353.com