【问题标题】:Iteration of a recurrence solution in RR中递归解决方案的迭代
【发布时间】:2021-01-24 15:39:16
【问题描述】:

我在 R 语言中得到一个问题,要找到递归关系 x(n) = 2*x(n-1) - x(n-2) 的第 30 项,其中 x(1) = 0 和 x(2) = 1。我知道答案是 29 从数学推导。但是作为 R 的新手,我对如何在这里工作感到有些困惑。以下是我的代码:

loop <- function(n){
  a <- 0
  b <- 1
  for (i in 1:30){
    a <- b
    b <- 2*b - a
  }
  return(a)
}

loop(30)

结果我返回了 1,这太离谱了。

如果您想知道为什么这看起来像 Python,那么到目前为止,我大多只接触过 Python 编程(我一般是编程新手)。我试图检查 R 中的所有语法,但我想我的逻辑已被 Python 完全固定。在这种情况下有人可以帮助我吗?另外,R有没有像PythonTutor这样的资源来帮助可视化代码执行逻辑?

谢谢!

【问题讨论】:

    标签: r matrix iteration linear-algebra recurrence


    【解决方案1】:

    我猜你需要的可能如下所示

    loop <- function(n){
      if (n<=2) return(n-1)
      a <- 0
      b <- 1
      for (i in 3:n){
        a_new <- b
        b <- 2*b - a
        a <- a_new
      }
      return(b)
    }
    

    然后

    > loop(30)
    [1] 29
    

    如果您需要递归版本,以下是一种实现方式

    loop <- function(n) {
      if (n<=2) return(n-1)
      2*loop(n-1)-loop(n-2)
    }
    

    这也给了

    > loop(30)
    [1] 29
    

    【讨论】:

      【解决方案2】:

      你可以用另外几种方法解决它。

      1. 求解线性齐次递归关系,让

      x(n) = r^n

      代入递推关系,得到二次方

      r^n-2*r^(n-1)+r^(n-2) = 0

      ,即,

      r^2-2*r+1=0

      ,即,

      r = 1, 1

      通向通用解决方案

      x(n) = c1 * 1^n + c2 * n * 1^n = c1 + n * c2

      如果 x(1) = 0 和 x(2) = 1,你会得到 c2 = 1, c1 = -1, s.t.,

      x(n) = n - 1

      => x(30) = 29

      因此,将 x(n) 计算为 n 的函数的 R 代码很简单,如下所示:

      x <- function(n) {
         return (n-1)
      }
      x(30)
      #29
      
      1. 使用矩阵幂(首先从递归关系中找到以下矩阵A):

      (矩阵A具有代数/几何多重性,其对应的特征向量矩阵是奇异的,否则您可以自己使用谱分解来快速计算矩阵幂,这里我们将使用库expm,如下所示)

      library(expm)
      
      A <- matrix(c(2,1,-1,0), nrow=2)
      
      A %^% 29 %*% c(1,0)  # [x(31) x(30)]T = A^29.[x(2) x(1)]T
      #      [,1]
      # [1,]   30  # x(31)
      # [2,]   29  # x(30)
      
      # compute x(n)
      x <- function(n) {
          (A %^% (n-1) %*% c(1,0))[2]
      }
      x(30)
      # 29         
      

      【讨论】:

        【解决方案3】:

        你没有使用你在循环中迭代的变量,所以没有更新。

        
        loop <- function(n){
          a <- 0
          b <- 1
          for (i in 1:30){
            a <- b
            b <- 2*i - a
          }
          return(a)
        }
        
        

        【讨论】:

        • 这是一个递归关系。未使用循环变量。
        【解决方案4】:

        你可以定义一个递归函数。

        f <- function(x, n) {
          n <- 1:n
          r <- function(n) {
            if (length(n) == 2) x[2]
            else r({
              x <<- c(x[2], 2*x[2] - x[1])
              n[-1]
            })
          }
          r(n)
        }
        
        x <- c(0, 1)
        f(x, 30)
        # [1] 29
        

        【讨论】:

          猜你喜欢
          • 2013-07-22
          • 2020-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-31
          • 1970-01-01
          • 2020-10-30
          • 1970-01-01
          相关资源
          最近更新 更多