2016-12-13 15 views
0

私はいくつかの要件を満たすいくつかの組み合わせを見たい5つのテーブルを持っています。行列の乗算を使用してすべての可能な組み合わせを作成し、後で私のニーズを満たす行を選択することで、以下のデータを簡単に解決できます。問題は、私の元の問題はそれぞれ200行の5つのテーブルで構成されていることです。可能なすべての組み合わせを生成するには、数百GBのRAMが必要です。Rで私の5ループをスピードアップするための提案?

だから私が代わりにこれを試してみました:X1 < X2とX1 <×3:果たすべき

x1 <- seq(1,10,1) 
x2 <- seq(5,15,3) 
x3 <- seq(2,11,1) 
x4 <- seq(1,5,1) 
x5 <- seq(1,20,2) 

を。

nm <- data.frame(matrix(NA,1,5)) 

for(a in 1:length(x1)){ 
for(s in 1:length(x2)){ 
for(d in 1:length(x3)){ 
for(f in 1:length(x4)){ 
for(g in 1:length(x5)){ 

l1 <- x1[a] 
l2 <- x2[s] 

if(l1 < l2){ 

l3 <- x3[d] 

if(l1 < l3){ 

l4 <- x4[f] 
l5 <- x5[g] 

fy <- c() 
fy[1] <- l1 
fy[2] <- l2 
fy[3] <- l3 
fy[4] <- l4 
fy[5] <- l5 

nm <- rbind(nm, fy) 
}}}}}}} 

私の元々の問題では、私はより多くのif文を持っています。しかし、私は約24時間稼働させていますが、それでもやっていません。上記の問題は約10秒かかるので、私はそれが固まったと思うようになります。

+3

R経験則:可能な限り、ループの代わりにベクトル化された操作を使用してください。 – OmaymaS

+1

あなたがしようとしたことを私たちに示すよりも、言葉で何をしようとしているのかを説明してみませんか?より良いアプローチがあるかもしれません。そうでないかもしれません。実際のデータに必要な反復回数を計算しましたか? – MrFlick

+0

私はもう1行追加しましたが、単語の問題を理解するために何が欠けているのか分かりません。私のオリジナルのデータには約200^5の組み合わせがありますが、どれくらいが要件を満たしているか分かりません。 – Jixxi

答えて

2

2つの問題:

大きな問題は、ループ内でオブジェクトを大きくすることです。膨大なOSのオーバーヘッドが伴うため、これは可能な限り遅い操作です。オブジェクトを事前に割り当てる必要があり、必要に応じてオブジェクトをまとめるだけです。

メディアの問題は、結果を格納するためにdata.frameを使用することです。 Data.framesは役に立ちますが、遅いです。代わりに行列を使用してください。

nm1 <- matrix(nrow = 1e3, ncol = 5) #adjust the chunk size to a reasonable estimate 
rx <- 1 

for(a in 1:length(x1)){ 
    for(s in 1:length(x2)){ 
    for(d in 1:length(x3)){ 
     for(f in 1:length(x4)){ 
     for(g in 1:length(x5)){ 

      l1 <- x1[a] 
      l2 <- x2[s] 

      if(l1 < l2){ 

      l3 <- x3[d] 

      if(l1 < l3){ 

       l4 <- x4[f] 
       l5 <- x5[g] 

       if(rx > nrow(nm1)) nm1 <- rbind(nm1, matrix(nrow = 1e3, ncol = 5)) 

       nm1[rx, 1] <- l1 
       nm1[rx, 2] <- l2 
       nm1[rx, 3] <- l3 
       nm1[rx, 4] <- l4 
       nm1[rx, 5] <- l5 

       rx <- rx + 1 

      }}}}}}} 

nm1 <- nm1[seq_len(rx - 1),] 

タイミング:

Unit: milliseconds 
     expr  min  lq  mean median  uq  max neval cld 
     mod() 589.2437 591.1576 594.4138 593.3678 595.0909 603.2087  5 a 
original() 4934.4981 4952.4502 4980.6414 4953.3183 4985.7943 5077.1463  5 b 

私たちが実際にアルゴリズムを考えるように起動することなく、10倍の性能向上を得ます。この要素は、data.frameを増やす反復回数が増えれば大きくなります。それでも遅すぎる場合は、コンパイラパッケージを使用してコードをバイトコンパイルしてみてください。 Rcppを使って実際にコンパイルされたコードとして実装することも自明です。しかし、反復回数が増えるにつれてベンチマークを行い、実際の問題にタイミングを外挿する必要があります。無理やりの力よりも優れたアルゴリズムを見つけたり、実際にこれを行う必要がある場合は、考慮する必要があります。

関連する問題