您的位置:首页 > 编程语言 > PHP开发

PHP实现加权随机数(Weighted Random sampling)的生成算法

2013-01-11 20:30 435 查看
假设有如下一个数组

$list = array("A" => 5, "B" => 10, "C" => 15, "D" => 20, "E" => 50);

表示随机ABCDE,取到A的概率是5%,B为10%,C为15%,D为20%,E为50%。

思路很简单,画一根数轴,长度是ABCDE的权值的总和,按照他们的权值,分割这个数轴。

然后随机取数轴上的一点,落在哪个区间,就取哪个值。





具体算法如下

function GetRandom() {
$list = array("A" => 5, "B" => 10, "C" => 15, "D" => 20, "E" => 50);$sum = 0;
$listPoint = array(0);//这个数组记录了每个切割点的值,就是记录了数轴上,5,15,30,50,100的值。
foreach ($list as $key => $value) {
$sum+=$value;//计算出权值的总和
array_push($listPoint, $sum);//把分割点放到数组中
}
$num = rand(0, $sum);//取0到sum之间一个随机值
//echo $num . ":";
for ($i = 0; $i < count($listPoint) - 1; $i++)
{
if ($num >= $listPoint[$i] && $num <= $listPoint[$i + 1]) //判断随机值落在哪个范围内
{
$elem = array_slice($list, $i, 1);
return key($elem); //第i项的值
}
}
echo "can't be here";
}

测试代码,随机取100次,看看各个字母出现的次数。

$a = 0;
$b = 0;
$c = 0;
$d = 0;
$e = 0;
for ($i = 0; $i < 100; $i++) {
$char = GetRandom();
echo "$char  ";
switch ($char) {
case "A":
$a++;
break;
case "B":
$b++;
break;
case "C":
$c++;
break;
case "D":
$d++;
break;
case "E":
$e++;
break;
}
}
echo "A:$a<br>";
echo "B:$b<br>";
echo "C:$c<br>";
echo "D:$d<br>";
echo "E:$e<br>";
die(0);



得到的结果勉强也能接受。
本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1114895
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: