永发信息网

php取随机数概率算法

答案:4  悬赏:80  手机版
解决时间 2021-04-04 16:13
php取随机数概率算法
最佳答案
$number = array(
    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'];    //输出具体数字我测试时可以运行的.


全部回答
$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;
我测试过是可以运行的

问题有点模糊,我先暂时把“保留两位小数”理解成“[输出的随机数]保留两位小数”,而非其他因素保留多少小数。
又把“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.'
';
echo "1-10样本数".$a[0].', 占'.($a[0]/$total*100).'%
';
echo ">10-50样本数".$a[1].', 占'.($a[1]/$total*100).'%
';
echo ">50-100样本数".$a[2].', 占'.($a[2]/$total*100).'%
';
echo ">100-200样本数".$a[3].', 占'.($a[3]/$total*100).'%
';
echo "其他样本数".$a[4].', 占'.($a[4]/$total*100).'%
';总样本数50000
1-10样本数30052, 占60.104%
>10-50样本数12404, 占24.808%
>50-100样本数4993, 占9.986%
>100-200样本数2551, 占5.102%
其他样本数0, 占0%
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;
}
$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$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 <= $proCur) {
$result = $key;
break;
} else {
$proSum -= $proCur;
}
}
unset ($proArr);
return $result;
}
$prize_arr = array(
'0' => 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$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;
就这样
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
梦见在庙里吃饭是什么预兆
在一密闭容器中有A、B、C、D四种物质,一定条
北京到鞍山快递要几天,快递从济南到北京要多
我开学大三,学生物,不感兴趣,想要跨专业考
南沙大岗潭州这边哪里有便宜房子出租
可以同时装opencv2和opencv3吗
Microsoft PowerPoint主要功能是什么?如何使
虚拟人生3提示放入第2张光盘,是不是版本不完
加拿大健美生和澳洲澳佳宝哪个牌子好
汽车的高低挡与普通挡操作有什么区别
小米红米note4x 怎么样
下列哪项不是端午节的习俗?
请问裸车价15万整怎么去计算他的落地价?国产
亲妹妹16岁喜欢我,她小时候我关爱她,现在我
求苏有朋的《珍惜》吉他谱
推荐资讯
诊断ED的用度是多少
华为viewpoint 8030视频会议终端,我需要一份
勇敢做自己英语句子,不是做自己喜欢的事情,而
句中引用的后引号之前可以加标点么
f(x)=X(1+x),则-f(x)=-X(1+X).为什么
有在旅行社上班的吗
已知y等于(k加1)x加k减1是正比例函数,则k
磨砺和磨练的区别是什么?( )意志,括号中
下列各组词语中读音和书写全都正确的一组是(
非零和博弈
在使用分液漏斗进行分液时,正确的操作是( 
日常生活与化学有着密切的联系.(1)在野外
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?