您将需要有关这些权重的更多信息:它们对该索引的概率的权重有多大,以及该概率增加多少会扩散到相邻的索引。
我在这里假设可以提供这些参数,并且概率以正态分布分布。
我建议为每个索引创建一个包含概率的数组。您从每个索引的常量(例如 1)开始,这意味着所有索引都具有相同的被选中概率。
然后一个函数可以对它应用一个权重,给定一个权重应该集中在的索引,权重本身(它增加了该索引的现有“权重”多少),以及散布(标准差的正态分布,生成的概率将散布在周围)。
这是执行此类操作的代码。它的目的不是为了在统计上合理,但我相信它会以令人满意的方式完成这项工作:
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上运行