2016-05-05 3 views
0

任意の項目がリスト内の他の項目の任意の組み合わせ(重複なし)の合計ではないベクトルを作成する関数を作成しようとしています。r非自己和のベクトル

この機能は仕事をしますが、かなり遅いです...どのように改善するかについての明るい考えはありますか?

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) 
} 

答えて

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 
+1

ありがとうございました!確かにはるかに高速です。しかし、大きなk(100またはそれ以上)の場合、私の問題はほぼ解決できなくなります。 –

関連する問題