2016-08-01 10 views
1

大きな範囲の3つの変数を使用して値を最適化しようとしている私のコードの速度を改善しようとしています。最も可能性の高い出力は、範囲の中間で値を使用するため、各変数の可能な限り低い値から始まる時間が無駄になります。中間の価値から始めて繰り返したい!実際の問題には、数が150〜650の数千の行があります。 C、H、およびOの制限は、開始番号に基づいていくらか定義されますが、常に定義された範囲内の中心値である可能性が高くなります。 forループを定義して私が望むように外側に働く方法はありますか?私が考えることができる唯一の非常に浅い方法は、ループ内の値をベクトル(例えば、1 = 20,2 = 21,3 = 19など)から単に再定義することです。現在以下のコードを参照してください:中央値から極値へのループforループ

set_error<-2.5 
ct<-c(325.00214,325.00952,325.02004,325.02762,325.03535,325.03831,325.04588, 325.05641,325.06402,325.06766,325.07167,325.07454,325.10396) 


FormFun<-function(x){ 
    for(C in 1:40){ 
     for(H in 1:80){ 
     for(O in 1:40){ 
     test_mass=C*12+H*1.007825+O*15.9949146-1.0072765 

     error<-1000000*abs(test_mass-x)/x 

     if(error<set_error){ 
      result<-paste("C",C,"H",H,"O",O,sep ="") 
      return(result) 
      break;break;break;break 
     } 
     } 
     } 
     } 
} 

old_t <- Sys.time() 
ct2<-lapply(ct,FormFun) 
new_t <- Sys.time() - old_t # calculate difference 
print(new_t) 

答えて

1

使用ベクトルをと作成closure:これは、すべての組み合わせについてのエラーを機能環境でのC、H、Oのすべての組み合わせのグリッドを保存し、計算

FormFun1_fac <- function(gr) { 
    gr <<- gr 
    function(x, set_error){ 
    test_mass <- with(gr, C*12+H*1.007825+O*15.9949146-1.0072765) 
    error <- 1000000 * abs(test_mass - x)/x 
    ind <- which(error < set_error)[1] 
    if (is.na(ind)) return(NULL) 
    paste0("C", gr[ind, "C"],"H", gr[ind, "H"],"O", gr[ind, "O"]) 
    } 
} 
FormFun1 <- FormFun1_fac(expand.grid(C = 1:40, H = 1:80, O = 1:40)) 

ct21 <- lapply(ct, FormFun1, set_error = set_error) 
all.equal(ct2, ct21) 
#[1] TRUE 

(ベクトル化されたコードでは高速です)。テストに合格した最初の組み合わせが返されます。

+0

優秀、ありがとうございます! – JHawkes

+0

Roland、grグリッドの複数の行にエラー JHawkes

+0

'ind < - which(エラー Roland

関連する問題