按用户定义的权重选择随机元素

rof*_*fle 6 php random algorithm

可能重复:
在PHP中按权重生成随机结果?

我有一个Web应用程序,用户可以在其中添加1-20个文本字符串,并为它们指定显示频率的权重.然后,系统将根据定义的权重选择随机字符串.最好的方法是什么?每个字符串的重量范围值是否重要?我可以让用户为每个字符串分配一个数字(0-100)吗?你会如何选择随机字符串?(每个选择都不担心之前选择的内容,每个字符串在每次调用开始时选择的几率(基于权重)相同).

Kyl*_*ild 6

我在几个PHP游戏引擎中使用此函数:

<?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;
}
Run Code Online (Sandbox Code Playgroud)

用法

假设我在关联数组中有用户权重,其中每个字符串指向其权重:

$weighted_strings = array(
    "important string" => 100,
    "terrible string" => 10,
    "never string" => 0,
    // etc
);
Run Code Online (Sandbox Code Playgroud)

如果我想根据体重拉一根绳子,我会这样做:

$weights = array_values($weighted_strings);
$strings = array_keys($weighted_strings);
$index = getBucketFromWeights($weights);
$selectedString = $strings[$index];
Run Code Online (Sandbox Code Playgroud)

  • 如果你构建一个反向关联数组,其中键是权重的总和到目前为止,值是字符串,这可以进一步优化,所以像这样:`0 =>"重要的字符串",100 =>"可怕的字符串",110 =>"never string"`,这使您可以使用二进制搜索找到所选元素.当然,对于少数几个元素来说,这是不值得的. (2认同)