MemoizzazioneLa memoizzazione è una tecnica di programmazione che consiste nel salvare in memoria i valori restituiti da una funzione in modo da averli a disposizione per un riutilizzo successivo senza doverli ricalcolare. Memoizzazione, che significa letteralmente "mettere in memoria" è una tecnica caratteristica della programmazione dinamica. Spesso questo termine viene confuso con "memorizzazione" che, sebbene descriva lo stesso procedimento, ha un significato più ampio. Una funzione può essere "memoizzata" soltanto se soddisfa la trasparenza referenziale, cioè se non ha effetti collaterali e restituisce sempre lo stesso valore quando riceve in input gli stessi parametri. Le operazioni che non soddisfano questa condizione, ma i cui valori restituiti hanno una piccola probabilità di cambiare, possono ancora essere duplicate ("cached", dal francese caché) usando tecniche più complesse. In generale, i risultati memoizzati non perdono di validità nel tempo, mentre, al contrario, quelli duplicati la perdono. Nei linguaggi di programmazione funzionale è possibile costruire una funzione di livello superiore La tecnica è anche spesso utilizzata nell'approccio top-down in programmazione dinamica. EsempioUn programma banale per calcolare i numeri di Fibonacci è fib(n) { if n is 1 or 2, return 1; return fib(n-1) + fib(n-2); } Poiché alloca array per memo, settando tutti i valori a zero; inizializza memo[1] e memo[2] a 1; fib(n) { if memo[n] diverso da 0, return memo[n]; memo[n] = fib(n-1) + fib(n-2); return memo[n]; } In un linguaggio dotato di chiusure e funzioni di ordine superiore, la memoizzazione di qualunque funzione può essere definita automaticamente. Questa "memoize" costruisce e ritorna un'altra funzione che effettua la memoizzazione dell'argomento f. memoize(f) { alloca array per memo, settando tutti i valori a indefinito; costruisci una nuova funzione chiamata "temp": temp(*args) { if args not in memo { memo[args] = f(*args) } return memo[args] } return temp } La notazione Questa funzione "memoize" può essere utilizzata per costruire una versione memoizzata di "fib": memofib = memoize(fib) Il calcolo dei numeri di Fibonacci può essere comunque fatto in tempo logaritmico (vedere la successione di Fibonacci); questo esempio è solo allo scopo di illustrare il concetto di memoizzazione. Implementazioni d'esempioPythonUn banale esempio di memoizzazione in Python, utilizzando scope innestati: def memoize(f):
cache = {}
def g(*args):
if args not in cache:
cache[args] = f(*args)
return cache[args]
return g
def fib(n):
if n in [0, 1]: return n
return fib(n-1)+fib(n-2)
fib = memoize(fib)
Questo banale memoizzatore utilizza quantità sempre crescenti di memoria, poiché i vecchi elementi non sono mai rimossi dalla cache. L'utilizzo della memoria può essere migliorato utilizzando uno schema di sgombero della cache, mantenendo i risultati solo per un tempo prespecificato [1] o pulendo la cache solo quando ritorna l'ultima chiamata a MapleIl sistema algebrico per computer Maple ha un memoizzatore incorporato, attraverso l'uso delle cosiddette tabelle di remember. Per esempio, definiamo una procedura 'square' come segue:
Dopodiché ogni chiamata a 'square' causa l'inserimento nella tabella della funzione per un riutilizzo successivo. Questa tabella può anche essere estratta: > square(4), square(7); # vengono inserite due voci nella tabella 16, 49 > op(4, eval(square)); # richiama la tabella di remember e il suo contenuto table([4 = 16, 7 = 49]) StoriaIl termine "memoizzazione" (memoization) è stato coniato da Donald Michie nel suo articolo "Memo functions and machine learning" (1968) su Nature. Utilizzi
Voci correlate
Collegamenti esterni
Nota: Questo articolo contiene materiale preso da una voce di pubblico dominio del NIST Dictionary of Algorithms and Data Structures a http://www.nist.gov/dads/HTML/memoize.html |
Portal di Ensiklopedia Dunia