在R中,使用动态编程计算fibonnaci

在R中,使用动态编程计算fibonnaci,r,recursion,dynamic-programming,fibonacci,R,Recursion,Dynamic Programming,Fibonacci,我试图写一个函数来计算R中的第n个Fibonnaci数。我可以递归地这样做 fibonacci = function(n){ if (n == 1) {return(1)} if (n == 2) {return(2)} return(fibonacci(n - 1) + fibonacci(n - 2)) } 我在R中找不到任何例子,但从其他语言的指南中,我得出了以下结论。然而,它似乎没有跑得更快 fibonacci = function(n, lookup = NULL){

我试图写一个函数来计算R中的第n个Fibonnaci数。我可以递归地这样做

fibonacci = function(n){
  if (n == 1) {return(1)}
  if (n == 2) {return(2)}

  return(fibonacci(n - 1) + fibonacci(n - 2))
}
我在R中找不到任何例子,但从其他语言的指南中,我得出了以下结论。然而,它似乎没有跑得更快

fibonacci = function(n, lookup = NULL){
  if (is.null(lookup)) {
    lookup = integer(n + 1)
  }


  if (n == 1) {return(1)}
  if (n == 2) {return(2)}

  lookup[1] = 1
  lookup[2] = 2

  if (lookup[n - 1] == 0) {
    lookup[n - 1] = fibonacci(n - 1, lookup)
  }

  if (lookup[n - 2] == 0) {
    lookup[n - 2] = fibonacci(n - 2, lookup)
  }
  return(lookup[n - 1] + lookup[n - 2])
}

解决方案的问题在于,查找向量始终是调用帧环境的本地向量,并且新的解决方案不会传播到调用方,即,当函数返回时,对查找向量的更改将丢失。为了使持久变量成为C中的静态变量,可以为充当记忆器的函数创建一个属性。这里有一个解决方案:

fibonaccid = function(n, init=T){
  if (init) {
    lookup <- integer(n + 1)
    lookup[1] <- 1
    lookup[2] <- 2
  } else {
    lookup <- attr(fibonaccid, ".lookup")
  }

  # ... calculate lookup as before, recurse with fibonaccid(...,init=F)

  attr(fibonaccid, ".lookup") <<- lookup

  return(lookup[n - 1] + lookup[n - 2])
}

有关详细信息,请参阅。

解决方案的问题在于,查找向量始终是调用帧环境的本地向量,并且新的解决方案不会传播到调用方,即,当函数返回时,对查找向量的更改将丢失。为了使持久变量成为C中的静态变量,可以为充当记忆器的函数创建一个属性。这里有一个解决方案:

fibonaccid = function(n, init=T){
  if (init) {
    lookup <- integer(n + 1)
    lookup[1] <- 1
    lookup[2] <- 2
  } else {
    lookup <- attr(fibonaccid, ".lookup")
  }

  # ... calculate lookup as before, recurse with fibonaccid(...,init=F)

  attr(fibonaccid, ".lookup") <<- lookup

  return(lookup[n - 1] + lookup[n - 2])
}

有关更多信息,请参阅。

那么您的问题到底是什么?这只是速度问题吗?您测试代码的时间是什么?那么您的问题是什么?这只是速度问题吗?测试代码的时间是什么?