未解决问题总结:
1. 内存不足 - 主进程需要太多内存,但不应该
我将尝试计算多种任意网络的组合,并使用 doparralel 和 foreach 遇到一些问题。对于一定规模的问题,即使使用 makeCluster(3),也只会启动一个进程。此外,我的内存不足(在 Mac 上使用 ~50GB - 错误:杀死 9 后)。奇怪的是,问题的规模已经很大了,它运行起来没有任何问题。我真的无法理解它,为什么它会填满内存而不是启动一个以上的进程。会不会是太大而无法计算?
代码:
pacman::p_load(iterpc, doSNOW,data.table, gtools, e1071)
source('adj.R', chdir = TRUE)
source('mm.R', chdir = TRUE)
ptm<-proc.time()
###with n<-5 and p<-3 it is running without any problems
n<-6 #genotype length
p<-3 #phenotype length
pevo<-NULL
prob<-NULL
I = iterpc(2^p, 2^n, replace=TRUE, ordered=F) #all combinations
bgg <- adjmatrix(n)
cl <- makeCluster(6)
registerDoSNOW(cl)
res<-foreach(elem = iter_wrapper(I,100) ,.combine='rbind') %dopar% {
gc()
rm()
for(z in 1:nrow(elem)){
bzz<-matmult(t(matmult(bgg,elem[z,])),elem[z,])
size<-NULL
for(k in 1:ncol(bzz)){
size[k]<-length(which(elem==k))
}
prob<-rbind(prob,diag(bzz)/colSums(bgz)/n)
diag(bzz)<-0
pevo<-rbind(pevo,colSums(bzz != 0))
}
return(cbind(pevo,prob))
}
proc.time()-ptm
write.table(res,'res2.txt',col.names=F,row.names=F,sep=" ")
print(object.size(res), units='auto')
gc()
rm()
这是我的活动监视器的屏幕截图,其中一个 R 进程占用更多内存(高达 55GB): 活动监视器
这是错误的屏幕截图:错误
编辑 09/22:
我已经更新了上面的代码。似乎使用 DoSNOW 包而不是 doParallel 解决了进程的问题。使用 DoSNOW 时,会启动正确数量的进程。但这带来了一个新问题。foreach 运行的迭代次数过多。
我已经添加到功能:
bgg
用函数计算adjmatrix
:adjmatrix <- function(n){ require(e1071) combi <- bincombinations(n) l <- length(combi[,1]) bgg <- matrix(0,l,l) for(i in 1:(length(combi[,1])-1)){ for(j in (i+1):length(combi[,1])){ check <- 0 for(h in 1:length(combi[j,])){ if(combi[j,h]!=combi[i,h]){ check <- check+1 } } if(check==1){ bgg[i,j] <- 1 bgg[j,i] <- 1 } } } return(bgg) }
bzz
用函数改变了计算matmult
:matmult <- function(A,B){ c <- matrix(0,nrow(A),length(B)) for(i in 1:nrow(A)){ for(j in 1:length(B)){ sum <- 0 for(k in 1:length(B)){ if(j == B[k]){ sum <- sum+A[i,k]} } c[i,j] <- sum } } return(c) }
编辑 09/23: 已解决:DoSNOW 包:foreach 运行了太多迭代
原因是这部分代码:
if(is.null(prob)){
prob<-diag(bzz)/size/n
}
else{
prob<-rbind(prob,diag(bzz)/size/n)
}
diag(bzz)<-0
if(is.null(pevo)){
pevo<-colSums(bzz != 0)
}
else{
pevo<-rbind(pevo,colSums(bzz != 0))
}
以下更改导致正确的迭代次数(或结果):
prob<-rbind(prob,diag(bzz)/colSums(bgz)/n)
diag(bzz)<-0
pevo<-rbind(pevo,colSums(bzz != 0))
更新了代码。