Wydaje mi się, że źle rozumiem rekursję ogona; zgodnie z to this stackoverflow question R nie obsługuje rekursji ogonowej. Jednakże, rozważmy następujące funkcje obliczyć n-tą liczbę Fibonacciego:Rekursja ogona w R
wersja iteracyjna:
Fibo <- function(n){
a <- 0
b <- 1
for (i in 1:n){
temp <- b
b <- a
a <- a + temp
}
return(a)
}
„Naive” rekurencyjna wersja:
FiboRecur <- function(n){
if (n == 0 || n == 1){
return(n)
} else {
return(FiboRecur(n-1) + FiboRecur(n-2))
}
}
I wreszcie przykład stwierdziliśmy, że powinny być wywołanie rekurencyjne:
FiboRecurTail <- function(n){
fib_help <- function(a, b, n){
if(n > 0){
return(fib_help(b, a+b, n-1))
} else {
return(a)
}
}
return(fib_help(0, 1, n))
}
Teraz, jeśli spojrzymy na ślad s gdy funkcje te nazywane są, o to co mamy:
Fibo(25)
trace: Fibo(25)
[1] 75025
trace(FiboRecur)
FiboRecur(25)
Thousands of calls to FiboRecur and takes a lot of time to run
FiboRecurTail(25)
trace: FiboRecurTail(25)
[1] 75025
W przypadkach Fibo(25)
i FiboRecurTail(25)
, odpowiedź jest wyświetlana natychmiast i tylko jedno połączenie jest wykonane. W przypadku FiboRecur(25)
wykonano tysiące połączeń, które trwają kilka sekund przed wyświetleniem wyniku.
Możemy również przyjrzeć się z czasów pracy przy użyciu funkcji benchmark
z pakietu rbenchmark
:
benchmark(Fibo(30), FiboRecur(30), FiboRecurTail(30), replications = 5)
test replications elapsed relative user.self sys.self user.child sys.child
1 Fibo(30) 5 0.00 NA 0.000 0 0 0
2 FiboRecur(30) 5 13.79 NA 13.792 0 0 0
3 FiboRecurTail(30) 5 0.00 NA 0.000 0 0 0
Więc jeśli R nie obsługuje ogon rekursji, co dzieje się w FiboRecurTail(25)
który sprawia, że biegać tak szybko jako wersja iteracyjna, podczas gdy "naiwna" funkcja rekursywna działa jak melasa? Czy raczej R obsługuje rekursję ogonową, ale nie optymalizuje "naiwnej" rekursywnej wersji funkcji wywoływanej zwrotnie, jak inne języki programowania (na przykład Haskell)? Rozumiem to z tego post in R's mailing list.
Byłbym bardzo wdzięczny, gdyby ktoś rzucił w to trochę światła. Dzięki!
Masz rację, poprawiłem to. – brodrigues
Możliwy duplikat [Rekurencja ogona na środowisku statystycznym R] (http://stackoverflow.com/questions/13208963/tail-recursion-on-r-statistical-environment) –