在 PHP 中按权重生成随机结果?

2022-08-30 08:41:05

我知道如何在PHP中生成一个随机数,但假设我想要一个介于1-10之间的随机数,但我想要更多的3,4,5,然后是8,9,10。这怎么可能?我会发布我尝试过的东西,但老实说,我甚至不知道从哪里开始。


答案 1

基于@Allain的答案/链接,我在PHP中完成了这个快速功能。如果要使用非整数加权,则必须对其进行修改。

  /**
   * 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;
      }
    }
  }

答案 2

对于始终偏向刻度一端的有效随机数:

  • 选择一个介于 0..1 之间的连续随机数
  • 提高到一个权力γ,以偏见它。1 表示未加权,越低表示较高的数字越多,反之亦然
  • 缩放到所需范围,舍入到整数

例如。在 PHP 中(未经测试):

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

推荐