【发布时间】:2016-04-08 00:53:40
【问题描述】:
我从一个据称简单的设置开始,结果变得非常具有挑战性:
说,我们有一个碗,里面有 W = 60 个白球,B = 10 个蓝球,G = 10 个绿球,Y = 10 个黄球。 现在我开始从那个碗里画三元组并将它们储存起来,直到碗是空的。 但是,有一个规则:
规则:
每个三元组不得包含超过一个相同颜色的非白色球!
完成后,我对分别有 0、1、2 和 3 个非白球的三元组的比例感兴趣。
为了解决这个问题,我从抽取样本和拒绝样本的想法开始,直到有一个样本满足上述规则。
我尝试了这个(希望是可重现的)代码:
W = rep(0, times = 60)
BGY = c(rep(1, times = 10),rep(2, times = 10),rep(3, times = 10))
sumup = matrix(c(rep(1,times=3)),byrow=FALSE)
OUTPUT = c(0,0,0,0)
getBALLS = function(W,BGY){
k = 0
while (k == 0){
POT = c(W, BGY)
STEPS = (length(W) + length(BGY))/3
randPOT <<- sample(POT, STEPS*3, replace=FALSE)
for(j in 1:STEPS){
if (.subset2(randPOT,3*j-2)!=.subset2(randPOT,3*j-1) &&
.subset2(randPOT,3*j-2)!= .subset2(randPOT,3*j) &&
.subset2(randPOT,3*j-1)!=.subset2(randPOT,3*j)){
next
}
else getBALLS(W, BGY)
}
k = 1
}
TABLES = matrix(randPOT, nrow=3, byrow=FALSE)
Bdistr = t(TABLES) %*% sumup
for(i in 1:STEPS){
if (.subset2(Bdistr,i)==1) OUTPUT[1] <<- .subset2(OUTPUT,1)+1
else if (.subset2(Bdistr,i)==0) OUTPUT[4] <<- .subset2(OUTPUT,4)+1
else if (.subset2(Bdistr,i)==2) OUTPUT[2] <<- .subset2(OUTPUT,2)+1
else OUTPUT[3] <<- .subset2(OUTPUT,3)+1
}
rOUTPUT = OUTPUT/ STEPS
return(rOUTPUT)
}
set.seed(1)
getBALLS(W,BGY)
不幸的是我遇到了两个问题:
- 循环迭代次数过多!似乎经常违反规则,这使得以这种方式进行抽样可能不可行。
- 虽然我尝试调用最有效的函数,但当有不止一种方法可以到达那里时(例如 .subset2 调用),我有一种感觉,这段代码在解决这个问题方面效率很低。
接下来我尝试了两阶段采样(更具体的是 sampling 包中的 mstage 函数):
Stage1 = c( rep(0,12), rep(1,3), rep(2,3) )
Stage2 = c( rep(0,12), rep(1,3), rep(2,3) )
b = data.frame(Stage1, Stage2)
probs = list( list( (1/12) , (1/3), (1/3) ), list( rep(1/12,12),rep(1/3,3),rep(1/3,3) ) )
m = mstage( b, stage = list("cluster","cluster"), varnames = list("Stage1","Stage2"),
size = list(3,c(1,1,1)), method = "systematic", pik = probs)
虽然这也没有成功,但我也觉得这种方法不太适合我的问题!
总而言之,在我看来,这有点像我在用大锤敲碎坚果,我觉得有一种更有效的方法来解决这个问题(特别是因为我想运行一些蒙特卡罗模拟之后)。
如果有任何帮助,我将不胜感激! 提前致谢!
【问题讨论】:
-
在 Rcpp 中实现你的功能。
标签: r conditional sample