r非自我项目的向量

时间:2016-05-05 20:23:41

标签: r performance combinatorics

我正在尝试构建一个创建向量的函数,其中任何项目不是列表中其他项目的任何组合的总和(没有重复)。

这个功能完成了这项工作,但速度很慢......关于如何改进它的任何明智的想法?

sum_fun <- function(k)
{
  out_list <- c(2,3,4)
  new_num <- 4

  while(length(out_list) < k)
  {
    new_num <- new_num + 1
    #Check if new_num can be written as a sum of the terms in out_list
    new_valid <- T
    for (i in 2:(length(out_list) - 1)){
      if (new_num %in% (apply(combn(out_list,i), FUN = sum, MAR = 2)))
      {
        new_valid <- F
        break
      }
    }

    if (new_valid)
    {
      out_list <- c(out_list, new_num)
    }

  }
  return(out_list)
}

1 个答案:

答案 0 :(得分:0)

这是一个很好的问题。我对你的原始功能进行了一些修改,让我的运行速度比你的功能快一点。另一方面,你想找多少人?

主要的想法是,我们不应该比我们必须更频繁地计算更多的东西。我认为for循环可能会减慢一些事情,加上有多少列重复?如果我们可以“删除”列表,也许我们可以更快地搜索它[减少,重用,回收:)]。

sum_fun2 <- function(k)
{
  out_list <- c(2,3,4) #dummy list
  new_num <- 4 #dummy number
  calc_big_sum <- T #calculate big sum on the first go
  while(length(out_list) < k)
  {
    new_num <- new_num + 1 #dummy number to add

    #calculate big sum, and then find unique values
    if(calc_big_sum){
      big_sum<- unique(unlist(lapply(lapply(2:(length(out_list) - 1), 
                                    FUN = function(x) combn(out_list, m = x)), 
                                    FUN = function(y) apply(y, 2, sum))))
    }

      if(new_num %in% big_sum){
        calc_big_sum = F #don't make it calculate the sum again
      }else{
        out_list <- c(out_list, new_num) #add number to list
        calc_big_sum = T #make it calculate a new sum
      }
  }
  return(out_list)
}

> system.time(sum_fun2(10))
   user  system elapsed 
   0.03    0.00    0.03 
> system.time(sum_fun(10))
   user  system elapsed 
   1.30    0.00    1.27 
> system.time(sum_fun2(14))
   user  system elapsed 
   3.35    0.07    3.47 
> system.time(sum_fun(14))
## I ended it
Timing stopped at: 39.86 0 40.02