模擬具有不同概率的事件
有時你可能只需要模擬具有兩種結果的事件,可能具有不同的概率,但你可能會發現自己處於需要具有不同概率的許多可能結果的情況。讓我們假設你想模擬一個有六個同樣可能結果的事件。這很簡單。
function simulateEvent(numEvents) {
var event = Math.floor(numEvents*Math.random());
return event;
}
// simulate fair die
console.log("Rolled a "+(simulateEvent(6)+1)); // Rolled a 2
但是,你可能不希望同樣可能的結果。假設你有三個結果的列表,表示為百分比或可能性倍數的概率陣列。這樣的例子可能是加權骰子。你可以重寫以前的函式來模擬這樣的事件。
function simulateEvent(chances) {
var sum = 0;
chances.forEach(function(chance) {
sum+=chance;
});
var rand = Math.random();
var chance = 0;
for(var i=0; i<chances.length; i++) {
chance+=chances[i]/sum;
if(rand<chance) {
return i;
}
}
// should never be reached unless sum of probabilities is less than 1
// due to all being zero or some being negative probabilities
return -1;
}
// simulate weighted dice where 6 is twice as likely as any other face
// using multiples of likelihood
console.log("Rolled a "+(simulateEvent([1,1,1,1,1,2])+1)); // Rolled a 1
// using probabilities
console.log("Rolled a "+(simulateEvent([1/7,1/7,1/7,1/7,1/7,2/7])+1)); // Rolled a 6
你可能已經注意到,這些函式返回一個索引,因此你可以將更多描述性結果儲存在陣列中。這是一個例子。
var rewards = ["gold coin","silver coin","diamond","god sword"];
var likelihoods = [5,9,1,0];
// least likely to get a god sword (0/15 = 0%, never),
// most likely to get a silver coin (9/15 = 60%, more than half the time)
// simulate event, log reward
console.log("You get a "+rewards[simulateEvent(likelihoods)]); // You get a silver coin