logo资料库

统计计算-MH算法(R语言).docx

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
#计算合法近邻数 nneighb <- function(x,a){ nn <- 1 sum0 <- 0 sumb <- 0 for(i in 1:length(x)){ #要判断的条件的当前值 sum0 <- sum0 + i*x[i] } #交换 x[i]和 x[j]的位置看是否符合条件 for(i in 1:(length(x)-1)){ for(j in (i+1):length(x)){ sumb = sum0 - i * x[i] - j * x[j] + i * x[j] + j * x[i] if(sumb >= a){nn = nn + 1} } } return(nn) } demo_permsub <- function(x,nout=10,n=100,a=1000){ sum1 <- 0 for(i in n){ #要判断的条件的当前值 sum1 <- sum1 + i*x[i] } ## 输出为 nout 行 n 列矩阵 resmat <- matrix(0,nout,n) nsucc <- 0 nfail <- 0 ntry <- 0 nn1 <- nneighb(x,a) while(nsucc < nout){ #已经成功找到的元素个数 #上一次成功后的累计失败次数 #总试投次数 #当前合法近邻数 ntry <- ntry +1 nfail <- nfail +1 if(nfail>1000){ cat('尝试失败超过 1000 次: nsucc',nsucc,'ntry=',ntry,'nfail=',nfail,'\n') print(x) break } #进行一次尝试,随机选取两个元素下标,交换对应元素的位置 #看是否合法元素。
I1 <- ceiling(runif(1,0,1)*n) I2 <- ceiling(runif(1,0,1)*(n-1)) if(I2 == I1){ #第一个随机下标 #第二个随机下标 I2 <- I2 + 1 } #按照新的位置,计算目标的新值,比较是否超过界限 sum2 <- sum1 - I1*x[I1] -I2*x[I2] + I1*x[I2] + I2*x[I1] if(sum2 >= a){ #交换得到新的合法元素,看是否要转移 #先跳过去,如果不满足概率要求再跳回来 tmp1 <- x[I1] x[I1] <- x[I2] x[I2] <- tmp1 tran <- FALSE nn2 <- nneighb(x,a) if(nn2 <= nn1){ tran <- TRUE } else{ R <- runif(1,0,1) if(R < nn1 / nn2){ tran <- TRUE } } if(tran == TRUE){ nsucc <- nsucc +1 nfail <- 0 resmat[nsucc,] = x nn1 <- nn2 sum1 <- sum2 } else{ tmp1 = x[I1] x[I1] = x[I2] x[I2] = tmp1 nfail <- nfail +1 } } else nfail <-nfail + 1 } return(resmat) }
#测试 #x:初始排列; n:排列的元素个数; a:界限; nout:需要输出的抽样次数 n=100 a=10000 nout=100 set.seed(200) x <- sample(1:n,n,replace = FALSE) demo_permsub(x,nout,n,a)
分享到:
收藏