【发布时间】:2015-01-16 09:24:16
【问题描述】:
我在优化模型时遇到问题。我的函数在迭代过程中递增变量(Dem)的值,以达到“WHILE”中设置的条件。
我必须使用“FOR”和一些“IF”,我知道这会导致在 R 环境中的处理速度非常慢,但我必须在 R 中这样做。 变量 P 是 10958 obs 的长度。变量 A 和 C 的长度为 65511 obs。
使用system.time(myfunction),只使用变量Area[1]和C[1]中的一个元素,我的电脑需要2.5秒才能完成这个过程。但是对于 Area 和 C 的所有元素,需要 45 小时。
我的教授说它太慢了,但我认为对于数据量来说是正常的,有没有办法优化这个?是否应该使用 WHILE 来优化函数(PSO、DEoptim 等)?
myfunction = function(P,Area,C,Cap,Inc){
Vin<- Cap
Q<-NA
Ov<-NA
Def<-NA
Vf<-NA
Vp<-NA
Dem<-0
Dem_100<-NA
Fail<-0
for (i in 1:length(Area)){
while(Fail==0){
Dem<-Dem+Inc
for (j in 1:length(P)){
#-----------------------------------------------------------------------#
####################### Calculate Q #####################################
#-----------------------------------------------------------------------#
if (P[j]==0){
Q<-0
}else{
Q<-P[j]*Area[i]*C[i]
}
#-----------------------------------------------------------------------
################################ Calculate Vp ##########################
#-----------------------------------------------------------------------
Vp<- (Vin + Q) - Dem
if(Vp<0){
Fail<-1
break #stop For j and continue the while
}
#----------------------------------------------------------------------
###################################### Calculate OV ###################
#----------------------------------------------------------------------
if (Vp>Cap){
Ov<-Vp-Cap
}else{
Ov<-0
}
#---------------------------------------------------------------------
######################################## Calculate Def ###############
#---------------------------------------------------------------------
if (Vp<0){
Def<-0-Vp
}else{
Def<-0
}
#---------------------------------------------------------------------#
################################## Calculate Vf ###########
#---------------------------------------------------------------------#
if (Vp>Cap){
Vf<-Cap
}else{
if (Vp<0) {
Vf<-0
}else{
Vf<-Vp
}
}
#-----------------------------------------------------------------------#
################################## Update Vin ###########
#-----------------------------------------------------------------------#
Vin<-Vf
}
Vin<- Cap # Reset the var Vin for new j
}
Dem_100[i]<-Dem-Inc
Def<-NA
Dem<-0
Vin<- Cap
Fail<-0
}
return(list(DemGar100=Dem_100))
}
时间过程测试
P<-abs(rnorm(10958))
system.time(myfunction(P = P,Area = 100,C = 0.8,Cap = 10000,Inc = 1))
user system elapsed
2.45 0.00 2.50
【问题讨论】:
-
那是代码,几乎没有空格
-
你应该解释它应该做什么而不是仅仅给出代码。您是否使用线轮廓仪来识别一些瓶颈?这看起来很容易在 cpp 或 python 中实现,你试过吗?
-
曾经放空格抱怨,所以这次我拿了。我会再发一次。
-
@rawr 我知道这在 cpp 或 python 中会很好,但我需要在 R 中这样做。这段代码的目的是将变量 Dem 的值增加到 Vp 变量的值不是负面的。换句话说,找到更大的 Dem 值。
-
我想有人曾经说过你可以用任何语言编写 Fortran 代码。我,因为一个人在用作问题描述时阅读这样的代码几乎没有耐心。您应该花时间写出 in_natural_language 描述,首先是数据,然后是详细的处理工作流程。 (此外,for() 循环在 R 中很慢是不正确的。)这通常是正确的,但是,for 循环中间的
if(){}else{}通常可以替换为更有效的函数。您正在分配给未索引的变量,因此您将在循环的每次迭代中覆盖这些值。
标签: r for-loop optimization while-loop