利用随机函数生成随机数

给定一个rand(),可以产生从0到RAND_MAX的随机数,其中RAND_MAX很大(常见值:16位int能表示的最大整数32767),写出利用rand()生成[a,b]中任意整数的函数,其中a>=0, b<=RAND_MAX,且b-a<<RAND_MAX.

分析:

这是在编程工作最常见的随机函数的应用,在这里做一个起点再合适不过。把随机数区间的起点从0变为a,同时把一共RAND_MAX+1个数的区间缩小至只含有b-a+1个数的区间,写为 a + rand()%(b-a+1),此时显然最大值是a+(b-a)= b。

进一步地,这个b-a<<RAND_MAX的条件虽然看上去不起眼,其实很重要。

附加思考:

如果b-a和RAND_MAX很接近会发生什么情况?读者不妨先做思考,问题2的分析会做出解答。

这个rand(),其实相当于《编程珠玑》提到的bigrand()。

假设:一个能返回很大随机整数的的函数bigrand(),一个能返回i..j范围内均匀选择的随机整数函数randint(i,j)。
  在C语言中,随机函数rand()通常返回约15个随机位,可以使用该函数实现上述bigrand()和randint()函数。

  int bigrand(){
      return RAND_MAX*rand() + rand();
  }
  int randint(int l, int u){
      return l + bigrand() % (u-l+1);
  }

给定一个随机数函数rand7(),它能以等概率生成1~7这7个整数。请根据rand7()写出类似的rand5()。

分析:

如果直接像问题1中一样,把1+rand7()%5作为rand5()会有什么情况发生?这时确实能产生1~5的随机数没错,可是各个数的概率相等吗?

对于随机数2,既有可能来自于1+1%5,也有可能来自于1+6%5,显然其概率是2/7,而不是1/5,不满足rand5()等概率产生各随机数这一隐含要求。不同于问题1,问题1中一个很大的区间收缩成较小区间时,各个元素映射后的新元素概率虽然概率可能不完全一样,但却是近似相同的。

  为了满足等概率的要求,可以这么做:

int rand5() {
    int res;
    do {
        res = rand7();
    } while(t>=6);
    return res;
} 

虽然保证了1~5的概率都变成了1/5,但是有一个无法避免的缺点是,每当产生了6或者7都要抛弃,相当于这一次运行是“空转”,浪费了时间。

如果对1/5这个概率不明白,可以有两种理解:每次产生6或7就被抛弃,剩下数的概率相等,必然为1/5;或者用更严密的推理:产生1~5的随机数,最终得到某一个的概率为:1/7+(1/7)*(2/7)+(1/7)*(2/7)2+...,无限项求和,结果是1/5。

给定一个随机数函数rand7(),它能以等概率生成1~7这7个整数。请根据rand7()写出类似的rand10()。

分析:

  有了问题2的概率基础,把rand7()变成rand10()仅仅需要一点点思考了。

int rand10() {
    int t1,t2,res;
    do {
        t1 = rand7();
    } while(t1>=6);
    //t1以等概率成为1/5

    do {
        t2 = rand7();
    } while(t2==7);
    //t2以1/2概率成为奇数或偶数

    res = t1+5*(t2%2);
    //res是1~10中的任意一个数的概率都是1/10
    //注意到%和*具有相同的优先级,这里去掉括号结果是错的
    return res;
}

等概率的rand10()

等概率的rand10()

给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。

利用随机函数rand()函数生成一个等概率随机生成整数1到5的函数Rand5(),然后根据Rand5()生成Rand7(),代码如下:

int Rand5()
{
    int n =1 + rand()%5;
    return n;
}
int Rand7()
{
    int n ,tmp1 ,tmp2;
    do
    {
        tmp1 = Rand5();
        tmp2 = Rand5();
        n = (tmp1-1)*5+tmp2;//n是可以取1~25的随机的数。
    } while (n>21);//当n>21舍去,这样n只能取1~21,对7取模就能取1~7之间的随机数  

    return 1+n%7;
    }  

参考https://linhan.blog.ustc.edu.cn/?p=408

http://www.cnblogs.com/wuyuegb2312/p/3141292.html#title1

时间: 2024-12-28 21:58:14

利用随机函数生成随机数的相关文章

JS更随机的随机数

一.问题背景 一个二维平面上有一群NPC,每一回合可以随机向上/下/左/右任一方向走1步,有单位碰撞体积(NPC位置不能重合) 规则就这么简单,初始情况下这群NPC是被人工均匀分布在二维平面上的,运行N个回合后发现所有NPC都集中在了左下角..怎么会这样,说好的随机呢? 二.分析 现有的实现是这样的: 根据NPC的当前位置判断得到可以去的位置,把结果存放在一维数组arr里 P.S.上/下/左/右最多4个点(周围空荡荡的),最少0个点(被围起来了) 生成[0, arr.length – 1]内的一

【转】利用matlab生成随机数函数

原文地址:利用matlab生成随机数函数 rand(n):生成0到1之间的n阶随机数方阵  rand(m,n):生成0到1之间的m×n的随机数矩阵 (现成的函数) betarnd:贝塔分布的随机数生成器 binornd:二项分布的随机数生成器 chi2rnd:卡方分布的随机数生成器 exprnd:指数分布的随机数生成器 frnd:f分布的随机数生成器 gamrnd:伽玛分布的随机数生成器 geornd:几何分布的随机数生成器 hygernd:超几何分布的随机数生成器 lognrnd:对数正态分布

利用servlet产生随机数,原理是获取Graphics对象进行绘图

public class ResonpeRandomImgDemo extends HttpServlet { int width=100; int height=30; public void doGet(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException { response.setContentType("text/html;charset=utf

【Java】揭秘如何利用不等概率随机数制作十赌九骗的赌大小游戏,请不要沉迷各种游戏

上次在<[Java]在一定的范围内产生不同的随机数>(点击打开链接)中说明了如何产生随机数,然后还说了如何在一定的范围内产生不同的随机数,但是这些都是等概率产生随机的问题.等概率在正常情况下,更应该说是学术上是够用了,但是在现实生活中,尤其在现在游戏必须打黄赌毒的擦边球吸引人的大背景下,等概率产生随机数是远远不够用的.你作为游戏商家,说得难听点就是庄家,肯定要不等概率产生随机数来圈玩家的钱.比如,合成装备就你就不能让它合成成功是50%,合成不成功是50%,你必须把合成成功设置为1%甚至更小.这

【算法设计-随机算法】利用随机算法生成均匀随机排序数组

思想: 1.首先生成1到n的数组A 2.生成1到n^3的n个数的随机数组P 例如A=<1,2,3,4> P=<36,3,62,19> 3.对p数组进行从小到大的排序(利用快速排序),生成数组P1=<3,19,36,62> 4.根据3中P1的顺序,生成随机数数组A1=<2,4,1,3> 应用:腾讯面试题目 对于一个斗地主游戏,给出一个发牌的算法,让每个人的牌确保随机. 考虑假设有N张牌,要分出来M张牌,给K个人.我能想到的是,N张牌有N种排列,随机产生一种排列

php中利用uniqid() 函数生成唯一的id

function createId($prefix = ""){    $str = md5(uniqid(mt_rand(), true));    return $prefix . $str;} //uniqid(prefix,more_entropy)uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID. prefix 可选.为 ID 规定前缀.如果两个脚本恰好在相同的微秒生成 ID,该参数很有用.more_entropy 可选.规定位于返回值末尾的更多的熵. 如果

Python利用带权重随机数解决抽奖和游戏爆装备问题

关于带权随机数 为了帮助理解,先来看三类随机问题的对比: 1.已有n条记录,从中选取m条记录,选取出来的记录前后顺序不管. 实现思路:按行遍历所有记录,约隔n/m条取一个数据即可 2.在1类情况下,还要求选取出来的m条记录是随机排序的 实现思路: 给n条记录,分别增加一列标记,值为随机选取的1至n之间的不重复数据. 3.区别于1,2类问题, 如果记录是有权重的,如何结合权重去随机选取. 比如A的权重为10, B的权重股为5, C的权重为1, 则随机选取4个时可能应该出现AABB. 第3类问题便是

java中随机生成随机数及不重复的随机数字

Java中产生随机数 1 . 调用java.lang下面Math类中的random()方法产生随机数 public class MyRandom { public static void main(String[] args) { int  radom = (int)(Math.random()*10); System.out.println(radom); } } 其中Math.random() //产生0~1之间的一个随机小数. 产生一个0~9之间的整数为:(int)(Math.random

在C语言如何利用srand()和随机数函数rand()生成随机数

摘自:百度百科 在stdlib.h 中这两个函数的原型是: int rand(); void srand (unsigned int); ?在标准的C库中函数rand()可以生成0~RAND_MAX之间的一个随机数,其中RAND_MAX 是stdlib.h 中定义的一个整数,它与系统有关.为了使程序在每次执行时都能生成一个新序列的随机值,我们通常通过为随机数生成器提供一粒新的随机种子.函数 srand()可以为随机数生成器播散种子.只要种子不同rand()函数就会产生不同的随机数序列.srand