以下是伪代码。
float totalStakes = 0; float [] partnerStakes [];
int EnterDraw(float _stakes) {
totalStakes += _stakes;
participantStakes.push(_stakes);
return participantStakes.length - 1;
}
int SelectWinner() {
float rnd = Random(0, totalStakes);
float sum = 0;
for(int i=0; i<participantStakes.length; i++) {
sum += participantStakes[i];
if (rnd <= sum) {
return i;
}
}
}
bool DidIWin(int _participantID) {
return (SelectWinner() == i);
}
此伪代码运行抽奖活动,参与者有不同的获胜概率。 我的问题是,是否有任何方法可以执行此操作而不必潜在地遍历所有元素?
重要:随机数仅在所有参与者都进入抽奖之后生成。
答案 0 :(得分:1)
我同意这样的评论:如果仅存储赌注的数量,就无法避免在数组中循环,而我的回答基于@juvian的评论。
我没有为每个数组存储桩数,而是为每个参与者存储了索引范围。这样,就不依赖于数组其他元素中的值。从那里进行二进制搜索以找到获胜指数。
搜索中的一项调整是从相对于获胜赌注价值的位置开始,再到总赌注而不是绝对中点。因此,这在以正态分布的数据集的情况下应该会表现更好。
int EnterDraw(float _stakes) {
totalStakes += _stakes;
min = (pStakes.length > 0) ? pStakes[pStakes.length - 1].cutoff : 0;
cutoff = min + _stakes;
pStakes.push({ min, cutoff });
return pStakes.length - 1;
}
int SelectWinner() {
float rnd = Random(0, totalStakes);
int i = floor(pStakes.length * rnd / totalStakes);
int high = totalStakes - 1;
int low = 0;
while (!(pStakes[i].min <= rnd && pStakes[i].max > rnd) {
if (pStakes[i].min > rnd) {
high = i - 1;
i = floor((i - low) / 2) + low;
}
else {
low = i + 1;
i = floor((high - i) / 2) + low;
}
}
return i;
}