2015-09-10 10 views
5

Vedo che se uso memoise su una funzione in due modi diversi, ottengo due comportamenti diversi e mi piacerebbe capire perché.perché queste funzioni memorizzate sono diverse?

# Non Memoised function 
fib <- function(n) { 
    if (n < 2) return(1) 
    fib(n - 2) + fib(n - 1) 
} 

system.time(fib(23)) 
system.time(fib(24)) 

library(memoise) 

# Memoisation stragagy 1 
fib_fast <- memoise(function(n) { 
    if (n < 2) return(1) 
    fib_fast(n - 2) + fib_fast(n - 1) 
}) 

system.time(fib_fast(23)) 
system.time(fib_fast(24)) 

# Memoisation strategy 2 
fib_not_as_fast <- memoise(fib) 

system.time(fib_not_as_fast(23)) 
system.time(fib_not_as_fast(24)) 

Strategia 1, è davvero veloce, in quanto riutilizza i risultati ricorsive, mentre stratagy 2 è solo veloce se l'ingresso esatto è stato visto prima.

Qualcuno può spiegarmi perché questo è?

risposta

5

Penso che la ragione sia semplice. Nel caso lento, la funzione fib_not_as_fast viene memorizzata. All'interno della funzione, viene chiamato fib, che è non memoised. Per essere più dettagliato: quando si calcola lo fib_not_so_fast(24), all'interno della funzione si ha fib(22) + fib(23). Entrambi questi non sono stati registrati.

In fib_fast, tuttavia, si utilizza la versione memorizzata anche nella ricorsione. Quindi, in questo caso, fib_fast(24) deve valutare fib_fast(22) + fib_fast(23). Entrambe queste chiamate di funzione sono già avvenute, quando hai calcolato fib_fast(23) e sono quindi memoise.

+0

Follow-up: Supponiamo di avere "fib" già definito - come lo memorizzerete? Cose sostitutive nel corpo della funzione? – Frank

+1

@Frank - 'Recall' è utile per evitare quelle situazioni. Se si scrivono le funzioni ricorsive in R, si dovrebbe usare 'Recall' – Dason

+0

@Dason Ah cool, non sapevo che esistesse una tale funzione. Sembra che il pacchetto memoise non sia impostato per affrontare il caso se ho capito bene. Vedo gli stessi tempi per 'fib <- function (n) {if (n <2) return (1); Richiama (n - 2) + Richiama (n - 1)} 'e per' ffib <- memoise (fib) ' – Frank