在PHP中,我需要使用两个权重选择1到100之间的随机数。这些权重也可以在1到100之间。如果两个权重都很低,我需要随机数加权低,高加权高。如果一个权重很高而一个权重很低,或者如果它们都是中等范围,那么我预计随机数会在50年左右随机加权。
我不确定最好的办法。任何建议都会很棒!
答案 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";
}
上查看它