对JS数组进行概率置乱
假设我有一个这样的数组:
const alphabet = ['a', 'b', 'c', 'd'];
这代表4名政治候选人和一张等级选择票,其中候选人a
是第一选择,b
是第二选择,依此类推。
a
以可能60%的概率出现在第一位,b
以20%的概率出现在第二位,c
以10%的概率出现在第三位,所有其他顺序可能以10%的概率出现。是否有一些loDash和Ramda功能可以实现这一点?
这是为了测试排名选择投票算法。随机调整数组产生的候选人的得票数几乎相同,这并不能反映大多数现实(尽管我也会测试这一点)。
我有一个非常可怕的例程,它将生成一个随机数组:
const getValues = function () {
const results = [];
const remaining = new Set(alphabet);
const probabilities = [0.6, 0.2, 0.1, 0.1];
for(let i = 0; i < alphabet.length; i++){
const r = Math.random();
const letter = alphabet[i];
if(r < probabilities[i] && remaining.has(letter)){
results.push(letter);
remaining.delete(letter);
}
else{
const rand = Math.floor(Math.random()*remaining.size);
const x = Array.from(remaining)[rand];
remaining.delete(x);
results.push(x);
}
}
return results;
};
这是"有效的",但由于条件概率的原因,它并不完全按照指定的概率对事物进行排序。有没有人知道让订单以一定的概率出现的好方法,就像我上面描述的那样?
以下是我正在寻找的一些示例输出:
[ [ 'd', 'b', 'a', 'c' ],
[ 'a', 'b', 'c', 'd' ],
[ 'a', 'd', 'b', 'c' ],
[ 'd', 'b', 'a', 'c' ],
[ 'b', 'c', 'a', 'd' ],
[ 'a', 'b', 'c', 'd' ],
[ 'd', 'b', 'c', 'a' ],
[ 'c', 'd', 'a', 'b' ],
[ 'd', 'b', 'a', 'c' ],
[ 'a', 'b', 'c', 'd' ] ]
如果您生成了足够的数据,它将不符合所需的订单/分配。
解决方案
我认为问题陈述不当。
按照规定,A在第1位的概率为60%,B在第2位的概率为20%,C和D在第3位或第4位,各占10%。没有满足这些概率标准的分布,因此没有任何算法可以产生它:如果在60%的情况下A位于第1位,则C或D必须在这60%的第3位或第4位,因此这远远高于所需的10%概率。
因此,这里的第一个任务是理解问题中所写的内容(因为在解释之后,它当然是有意义的)。
我想A的60%和B的20%不应该被解读为概率,而是一种人气。但这不能只是每个候选人的法定人数,因为在投票过程中,A将在100%的情况下排在第一位。
那么,让我们假设一个包含一些随机性的投票过程,其中A以60%的概率排在第1位,B排在第1位(!)概率为20%,然后我们可以对位置1使用加权随机选择来实现这一点。
如何继续位置2..n?我们只是保持权重不变,并删除已经被选中的候选人。如果其他候选人中有一人排到了第一名,那么这将很有可能出现在第二名,我认为这是有意义的。
相关文章