Possible Duplicate:
Generating random results by weight in PHP?
I have a web application where users can add 1-20 strings of text and assign a weight to them of how often it should show up. The system would then choose a random string based on the defined weights. What is the best way to go about this? Do the range values for the weight for each string matter? Could I just have the user assign a number (0-100) for each string? How would you go about choosing a random string? (Each choice doesn't worry about what was chosen before, every string has the same odds (based on weight) of being chosen at the start of each call).
For random selection with particular weights, the following technique can then be used: Generate a random number x between 0 and s u m ( w ) − 1 sum(w)-1 sum(w)−1. Find the smallest index that corresponds to the prefix sumprefix sumIn computer science, the prefix sum, cumulative sum, inclusive scan, or simply scan of a sequence of numbers x0, x1, x2, ... is a second sequence of numbers y0, y1, y2, ..., the sums of prefixes (running totals) of the input sequence: y0 = x.https://en.wikipedia.org › wiki › Prefix_sumPrefix sum - Wikipedia greater than the randomly chosen number.
Weighted random choices mean selecting random elements from a list or an array by the probability of that element. We can assign a probability to each element and according to that element(s) will be selected.
The random. randint function will always generate numbers with equal probability for each number within the range. This means that the probability of getting any specific number when running random. randint(1, 10) is only 10% -- since each of the numbers 1-10 are each 10% likely to show up.
I use this function in several PHP game engines:
<?php
/**
* @param array $values - just the weights
* @return integer A number between 0 and count($values) - 1
*/
function getBucketFromWeights($values) {
$total = $currentTotal = $bucket = 0;
$firstRand = mt_rand(1, 100);
foreach ($values as $amount) {
$total += $amount;
}
$rand = ($firstRand / 100) * $total;
foreach ($values as $amount) {
$currentTotal += $amount;
if ($rand > $currentTotal) {
$bucket++;
}
else {
break;
}
}
return $bucket;
}
Usage
Suppose I have the user weights in an associative array where each string points to its weight:
$weighted_strings = array(
"important string" => 100,
"terrible string" => 10,
"never string" => 0,
// etc
);
If I wanted to pull a string based on weight, I'd do this:
$weights = array_values($weighted_strings);
$strings = array_keys($weighted_strings);
$index = getBucketFromWeights($weights);
$selectedString = $strings[$index];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With