Generating random results by weight in PHP? Generating random results by weight in PHP? php php

Generating random results by weight in PHP?


Based on @Allain's answer/link, I worked up this quick function in PHP. You will have to modify it if you want to use non-integer weighting.

  /**   * getRandomWeightedElement()   * Utility function for getting random values with weighting.   * Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)   * An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.   * The return value is the array key, A, B, or C in this case.  Note that the values assigned   * do not have to be percentages.  The values are simply relative to each other.  If one value   * weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%   * chance of being selected.  Also note that weights should be integers.   *    * @param array $weightedValues   */  function getRandomWeightedElement(array $weightedValues) {    $rand = mt_rand(1, (int) array_sum($weightedValues));    foreach ($weightedValues as $key => $value) {      $rand -= $value;      if ($rand <= 0) {        return $key;      }    }  }


For an efficient random number skewed consistently towards one end of the scale:

  • Choose a continuous random number between 0..1
  • Raise to a power γ, to bias it. 1 is unweighted, lower gives more of the higher numbers and vice versa
  • Scale to desired range and round to integer

eg. in PHP (untested):

function weightedrand($min, $max, $gamma) {    $offset= $max-$min+1;    return floor($min+pow(lcg_value(), $gamma)*$offset);}echo(weightedrand(1, 10, 1.5));


There's a pretty good tutorial for you.

Basically:

  1. Sum the weights of all the numbers.
  2. Pick a random number less than that
  3. subtract the weights in order until the result is negative and return that number if it is.