我在groovy中实施加权抽奖。它允许一些参与者比其他参与者有更好的获胜机会(基本上与NBA选秀一样)。它的工作原理是将每个参与者投入阵列N次,其中N是您必须获胜的机会数。然后它从该数组中选择一个随机索引。
就像一个好的小编码器,我写了一个测试。它从该组中挑选100名获胜者,并输出每个参与者被选中的次数。期望它将大致与他们应该被挑选的次数(基于他们的机会数量)一致。结果是......关闭。
我将问题缩小到一行,如果分成两个单独的语句,则可以完美地运行。该例程的精简版本如下。 "坏"版本是活跃的"好版本"被注释掉了
def randomInRange(int min, int max) {
Random rand = new Random()
rand.nextInt((max - min) + 1) + min
}
def bob = [name:'bob', timesPicked:0]
def joe = [name:'joe', timesPicked:0]
def don = [name:'don', timesPicked:0]
def chanceWheel = []
//don should get picked a lot more
2.times{chanceWheel << bob}
2.times{chanceWheel << joe}
6.times{chanceWheel << don}
//pick somebody at random from the chance wheel
100.times{
//this will produce timesPicked counts that do NOT sum to 100 and usually under-represents don
chanceWheel[randomInRange(0,9)].timesPicked++
//splitting the logic into 2 lines will always have the correct sum of timesPicked with roughly the right distribution of winners
//def picked = chanceWheel[randomInRange(0,9)]
//picked.timesPicked++
}
println bob
println joe
println don
我的问题是单线版本出了什么问题?我的猜测是它的执行顺序问题,但是我不知道我的生活在哪里它会脱轨。
答案 0 :(得分:3)
chanceWheel[randomInRange(0,9)].timesPicked++
是
chanceWheel[randomInRange(0,9)].timesPicked =
chanceWheel[randomInRange(0,9)].timesPicked + 1
调用randomRange()
两次,与调用一次并分配给变量的工作示例形成对比。