生成范围内的随机数?

The*_*ner 15 c objective-c ipad

可能重复:
在Objective-C中生成随机数

如何生成一个范围内的随机数?

Jer*_*fin 67

实际上,这比大多数人意识到的要难得多:

int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
 */

    int divisor = RAND_MAX/(limit+1);
    int retval;

    do { 
        retval = rand() / divisor;
    } while (retval > limit);

    return retval;
}
Run Code Online (Sandbox Code Playgroud)

尝试仅使用%(或等效地/)获得范围内的数字几乎不可避免地引入偏差(即,某些数字将比其他数字更频繁地生成).

至于为什么使用%产生偏差结果:除非你想要的范围是RAND_MAX的除数,否则偏差是不可避免的.如果从小数字开始,很容易理解为什么.考虑服用10块糖果并试图在三个孩子之间均匀分配.显然它是不可能的 - 如果你分发所有的糖果,你可以得到的最接近的是两个孩子得到三块糖果,其中一个得到四块糖果.

所有孩子只有一种方法可以获得相同数量的糖果:确保你根本不分发最后一块糖果.

为了将其与上面的代码联系起来,让我们首先将糖果从1到10以及从1到3的孩子编号.最初的分工说,因为有三个孩子,我们的除数是三.然后我们从桶中取出一个随机的糖果,看看它的数字并除以三并将它交给那个孩子 - 但如果结果大于3(即我们选择了10号糖果)我们就是不把它拿出来 - 我们丢弃它并挑出另一种糖果.

当然,如果您正在使用C++的现代实现(即支持C++ 11或更新版本的C++),您通常应该使用distribution标准库中的一个类.上面的代码最接近std::uniform_int_distribution,但标准库还包括uniform_real_distribution许多非均匀分布的类(伯努利,泊松,正常,也许还有其他一些我目前不记得的).

  • 对不起,但是ewww!我想要做的最后一件事是在尝试获取随机数时循环划分一个不确定的数字(谁知道,也许永远).歪斜与否,我会采用更简单或者表格驱动的解决方案. (5认同)
  • 这在技术上是正确的,但是你有一个以rand()开头的GIGO问题.当限制不是RAND_MAX的因素时,您似乎正在尝试纠正偏差,使用模块化除法方法,您的错误在"limit/RAND_MAX"的顺序,直到"limit"接近"RAND_MAX".像兰德()矮人这样的PRNG开始出现问题.你支付的价格是引入一个无限制运行时间的非确定性循环[IRL它运行一次,但我们在这里分裂;-)]你没有得到任何东西,因为兰德是废话开始. (4认同)
  • @Philip Regan:在采用模数后,Skew来自小余数.假设您的随机数生成器生成11个值0 - 10然后您使用这些数字mod 5为您提供0到4之间的数字.有两种方法可以获得3(3和8)但有三种方法来获得0 (0,5,10)所以最终结果不均匀.这是一个真正的影响,但我认为,在使用PRNG的其他更大问题的噪音中,我会争辩. (4认同)
  • @Michael:在你得出任何结论之前先试试吧.事实上,"不确定数字"通常是*1.除非你在一个*真正*紧密的循环中执行此操作(例如,填充带有随机数的向量),实际上甚至无法测量它比明显更慢的版本错误. (3认同)
  • 不,不,我明白为什么其他人错了,这是一个很好的解决方案.但是,我来自嵌入的土地,直到最近,它们都是缓慢的.将它与rand()调用结合起来也很慢(更不用说非常随意的循环它们让我感觉不舒服)你可以看到我的立场.乍一看,我也担心这可能不是确定性的,但事实确实如此.呸,这里必须习惯21世纪的编码. (2认同)

Mic*_*bus 8

int rand_range(int min_n, int max_n)
{
    return rand() % (max_n - min_n + 1) + min_n;
}
Run Code Online (Sandbox Code Playgroud)

对于分数:

double rand_range(double min_n, double max_n)
{
    return (double)rand()/RAND_MAX * (max_n - min_n) + min_n;
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会给出统一的分布(除了2的幂). (4认同)
  • 我知道,但它的工作速度很快,而且小范围的分布也适用.这对游戏编码很有用.无论如何,我应该在答案的某处写下这个. (2认同)