r - 处理 R 中的递归深度限制

标签 r algorithm recursion

算法来自https://www.math.upenn.edu/~wilf/eastwest.pdf第 16 页 RandomKSubsets

RandomKSubsets = function(n, k){
  if (n<0 | k<0 | k<n){
    return()
  }
  else {
    if (n==0 && k==0){
      return(c())
    }
    else {
      rno = runif(1)
      if (rno < n/k){
        east = RandomKSubsets(n-1,k-1)
        return (c(east, k))
      }
      else{
        west = RandomKSubsets(n,k-1)
        return(west)
      }
    }
  }
}

在 k=4000 和 n=1200 的情况下运行程序,我遇到了递归深度限制。我尝试了 options(expressions=500000) 但这对算法来说还不够。如何为我的变量运行此代码?

最佳答案

这接近于尾递归:唯一的递归调用是在 return 语句中。此博客:http://blog.moertel.com/posts/2013-05-11-recursive-to-iterative.html描述了如何将此类函数更改为循环。我遵循了那里描述的大部分机械过程,并提出了这个版本:

RandomKSubsetsLoop = function(n, k) {
  acc <- NULL
  while (TRUE) {
    if (n<0 | k<0 | k<n){
      return(acc)
    }
    else {
      if (n==0 && k==0){
        return(acc)
      }
      else {
        rno = runif(1)
        if (rno < n/k){
          acc <- c(k, acc)
          k <- k - 1
          n <- n - 1
          next
        }
        else{
          k <- k - 1
          next
        }
      }
    }
    break
  }
}

我没有对它进行广泛的测试,但它产生的结果与本次测试中的原始结果相同:

set.seed(1)
RandomKSubsets(5, 10)
# [1]  1  3  6  9 10
set.seed(1)
RandomKSubsetsLoop(5, 10)
# [1]  1  3  6  9 10

您可能想要进行更广泛的测试,并阅读博客以确保我已经按照它描述的那样做了事情。

顺便说一句,还有其他算法可以进行这种采样,例如

中描述的那个
AUTHOR="McLeod, A.I. and Bellhouse, D.R. ",
YEAR = 1983,
TITLE="A convenient algorithm for drawing a simple random sample",
JOURNAL="Applied Statistics",
VOLUME="32",
PAGES="182-184"

那个是基于循环设计的,优点是你不需要提前知道总体规模(k 在你的符号中):你只需要不断更新你的样本直到没有更多的项目要处理。

关于r - 处理 R 中的递归深度限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57942424/

相关文章:

java - 缺少返回语句错误

注释掉从未执行的代码时,Java 程序运行速度变慢

r - 如何将 "jitter"转换为数字向量?

r - 如何使用 R 将字符从 Markdown 转换为 LaTeX

Rstats lubridate ... 区间向量

PHP - 当给定子键名称时,递归地将每个数组元素的键设置为子元素的值

r - 在 gather 函数中使用变量

python - 在Python中,从列表中删除重复项以使所有元素都是唯一的*同时保留顺序*的最快算法是什么?

algorithm - 文件中单词出现的次数 - 复杂性?

algorithm - 贪心算法 : Interval coloring