Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picking random element by user defined weights [duplicate]

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).

like image 871
roflwaffle Avatar asked Jan 18 '11 16:01

roflwaffle


People also ask

How do you do weighted random selection?

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.

What is a weighted choice?

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.

How do you set a random probability in Python?

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.


1 Answers

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];
like image 98
Kyle Wild Avatar answered Oct 19 '22 04:10

Kyle Wild