扩展rand()的最大范围
Extend rand() max range
我创建了一个测试应用程序,它可以生成0到250 000范围内的10k个随机数。然后我计算了最大值和最小值,注意到最大值总是在32k左右。。。
你知道如何扩大可能的范围吗?我需要一个最大值在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,您可以使用4个随机数在[0,10)范围内和一个在[0,25)范围内,沿线:
int
random250000()
{
return randomInt(10) + 10 * randomInt(10)
+ 100 * randomInt(10) + 1000 * randomInt(10)
+ 10000 * randomInt(25);
}
要使其工作,您的随机数生成器必须是好的;许多的rand()
的实现不是(或者至少不是)我没有最近核实了情况)。您还需要消除将RAND_MAX + 1
的不同值映射到10
或CCD_ 4不同的值。除非RAND_MAX + 1
是10
和25
(例如是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位随机数生成器。否则,就需要更好的东西。
您是否使用短整型?如果是这样,您将看到32767作为您的最大值,因为任何较大的值都会溢出短整数。
按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!如果您存储种子值,您可以稍后重播相同的随机序列。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 在基于范围的for循环中使用结构化绑定声明
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 为什么我不能将 rand() 与数组的大小一起使用?
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 为左值和右值的包装器实现C++范围
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 为什么 rand() 的范围比 int 的范围小?
- RAND()在递归功能中产生的数字高于设定范围
- 输出在我的字符数组范围之外,同时使用 rand()
- 扩展rand()的最大范围
- 如何从 rand() 函数的范围中省略一些数字?
- 大的超出范围的数字出现在c++ rand()中