随机加权两个权重

时间:2017-03-18 23:53:53

标签: php algorithm random

在PHP中,我需要使用两个权重选择1到100之间的随机数。这些权重也可以在1到100之间。如果两个权重都很低,我需要随机数加权低,高加权高。如果一个权重很高而一个权重很低,或者如果它们都是中等范围,那么我预计随机数会在50年左右随机加权。

我不确定最好的办法。任何建议都会很棒!

1 个答案:

答案 0 :(得分:0)

您需要有关这些权重的更多信息:如何权衡该指数的概率,以及该概率增加多少传播到相邻指数。

我将在此假设可以提供这些参数,并且概率以正态分布传播。

我建议创建一个包含每个索引概率的数组。你从每一个开始都有一个常量(例如1),这意味着所有索引都有相同的被选中概率。

然后一个函数可以对它应用一个权重,给定一个权重应该居中的索引,权重本身(它增加了多少现有的"权重"在该指数),以及spread(生成概率的正态分布的标准偏差)。

这是执行此类操作的代码。它不是统计上合理的,但我相信它会以令人满意的方式完成这项工作:

function density($x, $median, $stddev) {
    // See https://en.wikipedia.org/wiki/Probability_density_function#Further_details
    return exp(-pow($x - $median,2)/(2*pow($stddev,2))/(2*pi()*$stddev));
}

function homogeneous_distribution($size) {
    return array_fill(0, $size, 1);
}

function add_weight(&$distr, $median, $weight, $spread) {
    foreach ($distr as $i => &$prob) {
        $prob += $weight * density($i, $median, $spread);
    }
}

function random_float() { // between 0 and 1 (exclusive)
    return mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax();
}

function weighted_random($distr) {
    $r = random_float() * array_sum($distr);
    foreach ($distr as $i => $prob) {
        $r -= $prob;
        if ($r < 0) return $i;
    }
}

// Example use with 20 instead of 100.
$distr = homogeneous_distribution(20); // range is 0 .. 19
add_weight($distr, 0, 4, 1); // at index 0, put a weight of 4, spreading with 1
add_weight($distr, 16, 8, 0.5); // at index 16, put a weight of 8, spreading with 0.2

// Print distribution (weights for every index):
echo "DISTRIBUTION:\n";
print_r($distr);

// Get 10 weighted random indexes from this distribution:
echo "RANDOM SAMPLES:\n";
foreach (range(0, 10) as $i) {
    echo weighted_random($distr) . "\n";
}

rextester.com

上查看它