1至15之间的随机数 [英] Random numbers between 1 and 15

查看:735
本文介绍了1至15之间的随机数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我生成许多随机数,这些随机数在C ++中需要介于1到15(包括)之间.当然,我可以产生 std::uniform_int_distribution<std::mt19937::result_type> random(1, 15); 但这是浪费,因为此mersenn扭曲器会生成32位(甚至使用mt19937_64使用64位)随机值,而我只保留4位并丢弃所有其余值,就我而言,性能是一个问题,并且会生成随机数是一个重要的贡献者.

I generate many many random numbers that need to be between 1 and 15 (included) in C++. Of course, I can generate zillons of std::uniform_int_distribution<std::mt19937::result_type> random(1, 15); but this is a waste since this mersenn twister generates 32 bits (or even 64 using mt19937_64) of random values, and I would only keep 4 bits and throw away all the rest, and in my case, performance is an issue and random number generation is a significant contributor.

因此,我的想法是生成例如0到2 ^ 64-1之间的单个64位随机值,并从中选择4位.问题是我找不到在1到15之间生成值的方法. 示例:

My idea was thus to generate for example a single 64-bit random value between 0 and 2^64-1, and select 4 bits among them. The issue is that I can't find a way to have the generated values between 1 and 15. Example:

unsigned long long int r = uniform(generator); // between 0 and 2^64-1
unsigned int r1 = (r+1)&15;     // first desired random value
unsigned int r2 = ((r>>4)+1)&15; //second desired random value 
unsigned int r3 = ((r>>8)+1)&15; //third desired random value 
...

这里,此版本当然不起作用:尽管为+1,但生成的值仍在0到15之间(因为如果r&15恰好是0xb1111,则加1会生成结果0xb0000)

Here, this version of course doesn't work : despite the +1, the generated values are still between 0 and 15 (since if r&15 happens to be 0xb1111 then adding 1 produces the result 0xb0000).

此外,我希望分布保持均匀(例如,我不想使最低有效位偏向更频繁地出现,对于(r&15+1)|((r&15 +1) >> 4)之类的情况可能就是这种情况,因为值0xb0001会经常出现两次).

Also, I would like the distribution to remain uniform (for instance, I wouldn't want to bias the least significant bit to occur more often, which could be the case with something like (r&15+1)|((r&15 +1) >> 4) since the value 0xb0001 would occur twice often).

推荐答案

代替

std::mt19937 gen(seed);
std::uniform_int_distribution<> dis(1, 15);

auto r1 = dis(gen);
auto r2 = dis(gen);
auto r3 = dis(gen);
auto r4 = dis(gen);

您可以这样做:

std::mt19937 gen(seed);
std::uniform_int_distribution<> dis(0, 15 * 15 * 15 * 15 - 1); // Assuming int at least 16 bits

auto r = dis(gen);

auto r1 = r % 15 + 1; r /= 15;
auto r2 = r % 15 + 1; r /= 15;
auto r3 = r % 15 + 1; r /= 15;
auto r4 = r + 1;

快速基准测试(第二个版本比第一个版本快2.5倍)

Quick benchmark (second version 2.5 times faster than first one)

这篇关于1至15之间的随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆