繁体   English   中英

扩展rand()最大范围

[英]Extend rand() max range

我创建了一个测试应用程序,可以生成0到250 000范围内的10k随机数。然后我计算出MAX和min值,并注意到MAX值总是在32k左右......

你知道如何扩大可能的范围吗? 我需要一个MAX值约为250 000的范围!

这是根据rand()的定义,参见:

http://cplusplus.com/reference/clibrary/cstdlib/rand/

http://cplusplus.com/reference/clibrary/cstdlib/RAND_MAX/

如果您需要更大的随机数,您可以使用外部库(例如http://www.boost.org/doc/libs/1_49_0/doc/html/boost_random.html )或从多个小随机数中计算大型随机数数字由你自己。

但要注意你想要的分配。 如果只是总结小的随机数,结果将不会平均分配。

如果您只是按常数因子缩放一个小的随机数,则可能的值之间会有间隙。

取随机数的乘积也不起作用。

可能的解决方案如下:

1) Take two random numbers a,b
2) Calculate a*(RAND_MAX+1)+b

因此,您可以获得均匀分布的随机值,最高可达(RAND_MAX + 1)^ 2-1

据推测,您还希望在此扩展范围内平均分配。 关于可以有效执行此操作的唯一方法是生成一系列较小的数字,并将它们缩放,就像您在不同的基础上工作一样。 例如,对于250000,您可能在[0,10)范围内有4个随机数,在[0,25]范围内有一个随机数:

int
random250000()
{
    return randomInt(10) + 10 * randomInt(10)
        + 100 * randomInt(10) + 1000 * randomInt(10)
        + 10000 * randomInt(25);
}

为此,你的随机数生成器必须是好的; 许多rand()都没有(或者至少没有 - 我最近没有验证过这种情况)。 您还希望消除将RAND_MAX + 1不同值映射到1025不同值时产生的偏差。 除非RAND_MAX + 11025的精确倍数(例如,是50的精确倍数),否则您需要以下内容:

int
randomInt( int upperLimit )
{
    int const limit = (RAND_MAX + 1) - (RAND_MAX + 1) % upperLimit;
    int result = rand();
    while ( result >= limit ) {
        result = rand();
    return result % upperLimit;
}

(执行此操作时注意:有些机器RAND_MAX + 1将溢出;如果可移植性存在问题,则需要采取其他预防措施。)

当然,所有这一切都假设一台质量很好的发电机,这远不是一个特定的发电机。

您可以通过生成较小的随机数来按位操作数字。

例如,如果您需要32位随机数:

int32 x = 0;
for (int i = 0; i < 4; ++i) { // 4 == 32/8
   int8 tmp = 8bit_random_number_generator();
   x <<= 8*i; x |= tmp;
}

如果你的数字不需要良好的随机性,你可以使用rand()和0xff作为8位随机数发生器。 否则,将需要更好的东西。

将您的数字向上扩展N / RAND_MAX ,其中N是您所需的最大值。 如果数字合适,你可以这样做:

unsigned long long int r = rand() * N / RAND_MAX;

显然如果初始部分溢出你不能这样做,但是N = 250000你应该没问题。 RAND_MAX在许多流行平台上都是32K。

更一般地,要在区间[A, B]统一得到随机数,请使用:

A + rand() * (B - A) / RAND_MAX;

当然你应该使用正确的C ++风格的<random>库; 在此网站上搜索许多类似的问题,解释如何使用它。


编辑:为了防止评论升级,这里是另一个正确的C ++解决方案的复制/粘贴,用于在区间[A, B]上实现真正均匀分布:

#include <random>

typedef std::mt19937 rng_type;
typedef unsigned long int int_type;  // anything you like

std::uniform_int_distribution<int_type> udist(A, B);
rng_type rng;

int main()
{
    // seed rng first:
    rng_type::result_type const seedval = get_seed();
    rng.seed(seedval);

    int_type random_number = udist(rng);
    // use random_number
}

不要忘记看到RNG! 如果存储种子值,则可以稍后重播相同的随机序列。

你使用的是短期投资吗? 如果是这样,你会看到32,767作为你的最大数量,因为任何更大的数据都会溢出short int。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM