【问题标题】:How to iteratively perform combinations on larger datasets?如何在更大的数据集上迭代地执行组合?
【发布时间】:2018-01-05 08:14:59
【问题描述】:

背景 - 我想尝试彻底搜索一组所有可能的 250 行组合,一次取 10 行。为了迭代得到这个,我使用下面的代码

`
## Function definition
gen.next.cbn <- function(cbn, n){
  ## Generates the combination that follows the one provided as input
  cbn.bin      <- rep(0, n)
  cbn.bin[cbn] <- 1
  if (tail(cbn.bin, 1) == 0){
    ind <- tail(which(cbn.bin == 1), 1)
    cbn.bin[c(ind, ind+1)] <- c(0, 1)
  }else{
    ind <- 1 + tail(which(diff(cbn.bin) == -1), 1)
    nb  <- sum(cbn.bin[-c(1:ind)] == 1)
    cbn.bin[c(ind-1, (n-nb+1):n)] <- 0
    cbn.bin[ind:(ind+nb)]         <- 1
  }
  cbn <- which(cbn.bin == 1)
}

## Example parameters
n   <- 40
k   <- 10

## Iteration example
for (i in 1:choose(n, k)){
  if (i == 1){
    cbn <- 1:k
  }else{
    cbn <- gen.next.cbn(cbn, n)

  }
  print(cbn)


}


`

当我超过 40 行时,我收到错误“无法分配大小为 n GB 的向量”。

理想的解决方案: a)如果可以转储组合并且可以在循环中的每次运行后迭代地刷新内存(我可以在其中检查进一步的条件) b) 如果可以将组合转储到 csv 文件中,这样就不会造成内存占用。

感谢您的支持。

【问题讨论】:

  • 250 行中有 10 行有 219005316087032475 组合。即使你每秒可以进行一百万次组合,也需要 6900 多年才能运行。你确定这是你想要做的吗?
  • 如果你真的想这样做,你需要大规模并行化它。您也不应该使用 R,而是使用编译语言。您可以访问一个非常大的集群吗?
  • 谢谢弗洛里安,你是对的。如果我能逃脱 200 行中的 5 行,我什至可以生存。这将复杂性降低到 1e12,我相信可以在不到一周的时间内破解。
  • 您应该查看iterpc。这正是它的目的。

标签: r dataset combinations combn


【解决方案1】:

正如我在 cmets 中所说,iterpc 是完成此类任务的方法。您首先需要通过iterpc 函数初始化一个迭代器。接下来我们可以通过getnext 生成下一个n 组合。在此之后,我们只需将结果附加到 csv(或您喜欢的任何文件类型)。

getComboChunks <- function(n, k, chunkSize, totalCombos, myFile) {
    myIter <- iterpc(n, k)

    ## initialized myFile
    myCombs <- getnext(myIter, chunkSize)
    write.table(myCombs, file = myFile, sep = ",", col.names = FALSE)

    maxIteration <- (totalCombos - chunkSize) %/% chunkSize

    for (i in 1:maxIteration) {
        ## get the next "chunkSize" of combinations
        myCombs <- getnext(myIter, chunkSize)

        ## append the above combinations to your file
        write.table(myCombs, file = myFile, sep = ",",
                    col.names = FALSE , append = TRUE)
    }
}

例如,getComboChunks(250, 10, 100, 1000, "myCombos.csv") 将一次将 1000 个 250 个选择 10 的组合写入文件 myCombos.csv 100 个组合。分块做会比一次一个更有效。

这个库是用C/C++ 编写的,所以它应该相当高效,但正如@Florian 在 cmets 中指出的那样,它不会很快生成所有gmp::chooseZ(250, 10) = Big Integer ('bigz') : [1] 219005316087032475 组合。我没有测试过,但如果你满足于 200 选择 5,我认为你将能够在一天之内产生它(它刚刚超过 25 亿个结果)。

【讨论】:

  • 感谢约瑟夫伍德。这似乎很有效并且可以解决问题。我现在正在尝试。
  • 有没有更好的方法来检查条件。 iterpc 函数帮助转储了值,正如您提到的它是用 CC++ 编写的,我可以感觉到它的效率。
  • 你指的是什么条件?能举个例子吗?
  • 嗨@Joseph 我正在尝试按照此处提供的代码行做一些事情-link
猜你喜欢
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 2018-12-24
  • 2019-11-29
  • 2019-06-10
  • 2014-02-12
  • 1970-01-01
相关资源
最近更新 更多