php取随机数概率算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php取随机数概率算法相关的知识,希望对你有一定的参考价值。
从1到200按一定概率取数,保留两位小数
1-10为60%;
10-50为25%
50-100为10%
100-200为5%
求大神解决问题
问题有点模糊,我先暂时把“保留两位小数”理解成“[输出的随机数]保留两位小数”,而非其他因素保留多少小数。
又把“1-10”,理解成包括1和10在内其两数之间的小数,
把10-50,理解成10.01到50.00之间的数,不包括10.00。以此类推。
function genRandom()
$p=rand(1,100);
if($p<=60) $r=rand(100,1000);
elseif($p>60 and $p<=85) $r=rand(1001,5000);
elseif($p>85 and $p<=95) $r=rand(5001,10000);
else $r=rand(10001, 20000);
return $r/100;
$a=array();
$total=50000;
for($i=0;$i<$total;$i++)
$c=genRandom();
if($c>=1 and $c<=10) $p=0;
elseif($c>10 and $c<=50) $p=1;
elseif($c>50 and $c<=100) $p=2;
elseif($c>100 and $c<=200) $p=3;
else $p=4;
if(!array_key_exists($p, $a)) $a[$p]=1;
else $a[$p]++;
if(!array_key_exists(4, $a)) $a[4]=0;
echo "总样本数".$total.'<br/>';
echo "1-10样本数".$a[0].', 占'.($a[0]/$total*100).'%<br/>';
echo ">10-50样本数".$a[1].', 占'.($a[1]/$total*100).'%<br/>';
echo ">50-100样本数".$a[2].', 占'.($a[2]/$total*100).'%<br/>';
echo ">100-200样本数".$a[3].', 占'.($a[3]/$total*100).'%<br/>';
echo "其他样本数".$a[4].', 占'.($a[4]/$total*100).'%<br/>';总样本数50000
1-10样本数30052, 占60.104%
>10-50样本数12404, 占24.808%
>50-100样本数4993, 占9.986%
>100-200样本数2551, 占5.102%
其他样本数0, 占0% 参考技术B $Probability["1-10"] = 0.6;
$Probability["11-50"] = 0.25;
$Probability["51-100"] = 0.10;
$Probability["101-200"] = 0.05;
//扩大1000倍便于计算
foreach($Probability as $k => $v)
$Probability[$k] = $v*1000;
$Num = 0;
$Random = rand(1,1000);//生成随机数
foreach($Probability as $k => $v)
if( $Num < $Random && $Random <= $v+$Num)
//进入这里表示随机数在哪一个范围内
$Range = explode("-", $k);
//生成范围区间的随机数
$Result = rand($Range[0],$Range[1]);
echo $Result;
break;
else
$Num += $v;
希望对您有帮助追问
谢谢大神的回答,可是需要保留两位小数,1.00-10.00,之间的小数也要算
追答结果这行改成
$Result = rand($Range[0]*100,$Range[1]*100)/100;我测试过是可以运行的
参考技术C <?phpfunction get_rand($proArr)
$result = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur)
$randNum = mt_rand(1, $proSum);
if ($randNum <= $proCur)
$result = $key;
break;
else
$proSum -= $proCur;
unset ($proArr);
return $result;
$prize_arr = array(
'0' => array('id'=>1,'prize'=>'100-200','v'=>5),
'1' => array('id'=>2,'prize'=>'50-100','v'=>10),
'2' => array('id'=>3,'prize'=>'10-50','v'=>25),
'3' => array('id'=>4,'prize'=>'1-10','v'=>60),
);
foreach ($prize_arr as $key => $val)
$arr[$val['id']] = $val['v'];
$rid = get_rand($arr); //根据概率获取奖项id
$res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项
unset($prize_arr[$rid-1]); //将中奖项从数组中剔除,剩下未中奖项
shuffle($prize_arr); //打乱数组顺序
for($i=0;$i<count($prize_arr);$i++)
$pr[] = $prize_arr[$i]['prize'];
$res['no'] = $pr;
$num = $res['yes'];
$str_num = explode('-',$num);
$row = rand($str_num[0],$str_num[1]);
//$row最终结果几率如数组V可调整
echo $row;
?>追问
必须要有两位小数
追答function get_rand($proArr)
$result = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
//概率数组循环
foreach ($proArr as $key => $proCur)
$randNum = mt_rand(1, $proSum);
if ($randNum array('id'=>1,'prize'=>'10000-20000','v'=>5),
'1' => array('id'=>2,'prize'=>'5000-10000','v'=>10),
'2' => array('id'=>3,'prize'=>'1000-5000','v'=>25),
'3' => array('id'=>4,'prize'=>'100-1000','v'=>60),
);
foreach ($prize_arr as $key => $val)
$arr[$val['id']] = $val['v'];
$rid = get_rand($arr); //根据概率获取奖项id
$res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项
unset($prize_arr[$rid-1]); //将中奖项从数组中剔除,剩下未中奖项
shuffle($prize_arr); //打乱数组顺序
for($i=0;$i<count($prize_arr);$i++)
$pr[] = $prize_arr[$i]['prize'];
$res['no'] = $pr;
$num = $res['yes'];
$str_num = explode('-',$num);
$row = rand($str_num[0],$str_num[1]);
$str = (intval($row)/100);
echo $str;
就这样
1 => array('n' => mt_rand(1, 10), 'p' => 60),
2 => array('n' => mt_rand(10, 50), 'p' => 25),
3 => array('n' => mt_rand(50, 100), 'p' => 10),
4 => array('n' => mt_rand(100, 200), 'p' => 5),
);
function rand_number($numbers)
$sum = 100;
foreach ($numbers as $key => $number)
$rand = mt_rand(1, $sum);
if ($rand <= $number['p'])
$result = $key;
break;
else
$sum = $sum - $number['p'];
return $result;
echo $number[rand_number($number)]['n'];追问
不能运行
追答$number = array(1 => array('n' => mt_rand(1 * 100, 10 * 100) / 100, 'p' => 60),
2 => array('n' => mt_rand(10 * 100, 50 * 100) / 100, 'p' => 25),
3 => array('n' => mt_rand(50 * 100, 100 * 100) / 100, 'p' => 10),
4 => array('n' => mt_rand(100 * 100, 200 * 100) / 100, 'p' => 5),
);
function rand_number($numbers)
$sum = 100;
foreach ($numbers as $key => $number)
$rand = mt_rand(1, $sum);
if ($rand <= $number['p'])
$result = $key;
break;
else
$sum = $sum - $number['p'];
return $result;
echo $number[rand_number($number)]['n']; //输出具体数字
我测试时可以运行的.
php概率算法(转)
这是一个很经典的概率算法函数:
function get_rand($proArr) { $result = ‘‘; //概率数组的总概率精度 $proSum = array_sum($proArr); //概率数组循环 foreach ($proArr as $key => $proCur) { $randNum = mt_rand(1, $proSum); //抽取随机数 if ($randNum <= $proCur) { $result = $key; //得出结果 break; } else { $proSum -= $proCur; } } unset ($proArr); return $result; }
假设:我们有这样一个数组:a奖概率20%,b奖概率30%,c奖概率50%
$prize_arr =array(‘a‘=>20,‘b‘=>30,‘c‘=>50);
模拟函数执行过程:
总概率精度为20+30+50=100
第一次数组循环,$procur=20
假设抽取的随机数rand(1,100),假设抽到$randNum=55
if判断-------
如果$randNum<=20,则result=a
否则进入下一循环,总概率精度变为100-20=80
第二次数组循环,$procur=30
假设抽取的随机数rand(1,80),假设抽到$randNum=33
if判断---------
如果$randNum<=30,则result=b
否则进入下一循环,总概率精度变为80-30=50
第三次数组循环,$prosur=50;
假设抽取的随机数rand(1,50),不管怎么抽,随机数都会<或=50,
那么得出result=c;
因为样本没有改变,虽然可能抽取的随机数不止一个,但是概率是不变的。
或者也可以这样:
function get_rand($arr) { $pro_sum=array_sum($arr); $rand_num=mt_rand(1,$pro_sum); $tmp_num=0; foreach($arr as $k=>$val) { if($rand_num<=$val+$tmp_num) { $n=$k; break; }else { $tmp_num+=$val; } } return $n; }
以上是关于php取随机数概率算法的主要内容,如果未能解决你的问题,请参考以下文章