Reputation: 75
Is there a way to extract a value based on a percentage?
Value probability:
Bad: 1%
Normal: 29%
Good: 70%
var move ["bad","normal","good"];
A simple conditional statement:
if (move == "bad") {
bad_move = "That's a bad move!";
} else if (move == "normal") {
normal_move = "Classic move!";
} else {
good_move = "Amazing move!";
}
Then, is PHP better than Javascript for this kind of problem?
Upvotes: 4
Views: 1123
Reputation: 14778
You could write a function that samples values with given probability percentages:
function weightedSample(pairs) {
const n = Math.random() * 100;
const match = pairs.find(({value, probability}) => n <= probability);
return match ? match.value : last(pairs).value;
}
function last(array) {
return array[array.length - 1];
}
const result = weightedSample([
{value: 'Bad', probability: 1},
{value: 'Normal', probability: 29},
{value: 'Good', probability: 70}
]);
console.log(result);
I can't say if PHP would be better. This kind of problem shouldn't be any more/less difficult in PHP. Which you should use (JS or PHP) really depends on whether or not the function should be run on the server or client.
Upvotes: 1
Reputation: 386670
I suggest to use a continuous check of the probability and the rest of the random number.
This function sets first the return value to the last possible index and iterates until the rest of the random value is smaller than the actual probability.
The probabilities have to sum to one.
function getRandomIndexByProbability(probabilities) {
var r = Math.random(),
index = probabilities.length - 1;
probabilities.some(function (probability, i) {
if (r < probability) {
index = i;
return true;
}
r -= probability;
});
return index;
}
var i,
move = ["bad", "normal", "good"],
probabilities = [0.01, 0.29, 0.7],
count = {},
index;
move.forEach(function (a) { count[a] = 0; });
for (i = 0; i < 1e6; i++) {
index = getRandomIndexByProbability(probabilities);
count[move[index]]++;
}
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0