算法-大家能否提供一个产生随机数的算法
比如说产生1-1000的随机数,产生1-200之间的数的概率为20%,还可以动态调整这个概率。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
比如说产生1-1000的随机数,产生1-200之间的数的概率为20%,还可以动态调整这个概率。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
//初始配置
odds[4] = {2,1,3,4};
randomSource[5] = {1,200,300,500,1000};
// 种子
randomSeed = odds[0]+odds[1]+odds[2]+odds[3];
随机:
uint32 r = RandomInt(randomSeed); // 1=<r<=randomSeed
uint32 t = 0;
for (uint32 i=0; i<4; ++i){
t += odds[i];
if (r <= t) {
//在randomSource[i]和randomSource[i+1]之间随机
}
}
没写代码,思路是上面这样的,RandomInt随机出来的数字r,将r投射到odds中,这样达到了一个概率控制的效果,不知道这样说能说明白不。。。之后根据r投射在odds的区间随机数字就可以了。至于怎么样做成一个配置性较强的模块,无非就是通过配置文件吧。。
算法:开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内,如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。我想应该很容易理解,这样筛选到最终,总会有一个数满足要求(比如说前三个都不幸成为了非Luck Num,那么k已经-100-200-300=400了,那么最后一个数无论如何也会满足要求的。相当于拿东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。
<?php
/**
* 根据概率取随机数的算法(仅抽取1个)
* 用法:
* $proArr = array(10,20,30,40);
* $result = pro_rand($proArr);
* echo '你抽到的$proArr数组索引是'. $result. ',其预设概率数是'. $proArr[$result];
* @param array $proArr 概率数组。格式为array('A'=>10, 'B'=>40, 'C'=>50),或者array(10,40,50)。数组的每个键值(value)必须为大于1的整数;所有数组键值(value)加起来即为其总概率精度
* @return mixed $result 结果,将返回抽取到的概率数组索引值。
*/
function pro_rand( $proArr ){
$result = '';
//概率数组的总概率精度
$proSum = array_sum($proArr);
/*概率数组循环。(假设为array(100,200,300,400)):
开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内,
如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。
我想应该很容易理解,这样筛选到最终,总会有一个数满足要求
(比如说前三个都不幸成为了非Luck Num,那么k已经-100-200-300=400了,那么最后一个数无论如何也会满足要求的)。
相当于拿东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。
这个算法的优点是,对于没有概率重叠的数字进行筛选,最多只需要遍览一次数组就足够了。程序简单,效率高
*/
foreach ( $proArr as $key => $proCur ){
$randNum = mt_rand(1, $proSum);
if( $randNum <= $proCur ){
$result = $key;
break;
}else{
$proSum -= $proCur;
}
}
return $result;
}
/**
* 根据概率取随机数的算法(抽取多个,并且不重复)。
* 依赖于函数pro_rand
* 用法:
* $proArr = array(10,20,30,40);
* $result = pro_rand_unique_multi($proArr, 2);
* var_export($result);
* @param array $proArr 概率数组。格式为array('A'=>10, 'B'=>40, 'C'=>50),或者array(10,40,50)。数组的每个键值(value)必须为大于1的整数;所有数组键值(value)加起来即为其总概率精度
* @param integer $num 指定抽取数目。数值不能大于概率数组的个数
* @return array $result 结果,将返回指定抽取数目的概率数组索引值
*/
function pro_rand_unique_multi( $proArr, $num = 1 ){
$result = array();
if( $num > count($proArr) ){
trigger_error('The stack number of Probability Array is GREATER THAN you set!', 256);
}
while{
if($num < 1){
break;
}
$curResult = pro_rand($proArr);
$result[] = $curResult;
//重置总概率精度,有待概率论验证
unset($proArr[$curResult]);
$num -= 1;
}
return $result;
}
生成一个1000个数的数组,下标0-200间保存0-200随机获取的值,下标200-1000之间保存0-200随机获取的值,将数组值打乱,再产生0~1000的随机数,产生的随机数是多少就输出数组的第几个数。