3

chooseランダムに数値を取得したいとし1-10ますが、各数値には重みがあります。

1 - 15% chance
2 - 15% chance
3 - 12% chance
4 - 12% chance
5 - 10% chance
6 - 10% chance
7 - 8% chance
8 - 8% chance
9 - 5% chance
10 - 5% chance

これを でコーディングするにはどうすればよいPHPですか?

4

4 に答える 4

4

あなたのパーセンテージの合計は 100% になると思いますか?

で配列を構築します

15 times a '1' value, 
15 times a '2' value, 
... 
10 times a '6' value, 
8 times a '7' value,
...
5 times 1 '10' value

最終的には、100 個の要素を含む単一の配列になります。

要素をランダムに選択します (そして配列からポップします)。

于 2012-05-11T21:54:49.990 に答える
1

重みがパーセンテージの場合は、0 から 100 の間の乱数を選択し、ゼロを超えるまでパーセンテージを繰り返し減算します。

<?php
function getWeightedRandom() {
    $weights = array(15, 15, 12, ...); // these should add up to 100
    $r = rand(0, 99);
    for ($i=0; $i<count($weights); $i++) {
        $r -= $weights[$i];
        if ($r < 0)
            return $i+1;
    }
}
?>

これには、整数以外の重みをサポートするという追加の利点があります。

于 2012-05-11T21:57:09.290 に答える
1

以下のクラスで OP の重みを使用して値をエコーする例:

echo 1+Rand::get_weighted_rand(array(15,15,12,12,10,10,8,8,5,5));

そしてクラス:

class Rand
{
    /*
     * generates a random value based on weight
     * @RETURN MIXED: returns the key of an array element
     * @PARAM $a ARRAY:
     *  the array key is the value returned and the array value is the weight
     *      if the values sum up to less than 100 than the last element of the array 
     *      is the default value when the number is out of the range of other values
     * @PARAM $p INT: number of digits after decimal
     *
     * i.e array(1=>20, 'foo'=>80): has an 80 chance of returning Foo
     * i.e array('bar'=>0.5, 2=>1, 'default'=>0), 1: 98.5% chance of returning default
     */
    public static function get_weighted_rand($a, $p=0)
    {
        if(array_sum($a)>100)
            return FALSE;#total must be less than 100
        $p=pow(10, $p+2);
        $n=mt_rand(1,$p)*(100/$p);
        $range=100;
        foreach($a as $k=>$v)
        {
            $range-=$v;
            if($n>$range)
                return $k;
        }
            #returning default value
        end($a);
        return key($a);
    }
}
于 2012-05-11T21:57:34.867 に答える
0

1 15 回、3 12 回など、すべて複数回配列に入れます。次に、その配列から乱数を選択します。

$array = array_merge (array_fill (0, 15, 1), array_fill (0, 15, 2), array_fill (0, 12, 3), array_fill (0, 12, 4), array_fill (0, 10, 5), array_fill (0, 10, 6), array_fill (0, 8, 7), array_fill (0, 8, 8), array_fill (0, 5, 9), array_fill (0, 5, 10));
$random_number = array_rand ($array);
于 2012-05-11T21:55:31.393 に答える