问:如何从a-priory未知范围生成(多个)均匀分布的整数?在性能方面(生成的数字的数百万),首选方式是什么?
上下文:在我的应用程序中,我必须在很多地方生成许多伪随机数。我使用单例模式生成器来保持应用程序运行的可重复性。在我的情况下,分布总是统一的,但问题是在C ++ 11样式中预先制作分发对象的范围太多了。
我尝试过:有两个明显的解决方案,第一个是拥有一次性分发对象,第二个是使用modulo将随机数从最宽的范围转换为所需的范围。但不知何故,我怀疑这些是最好的可能:)
#include <random>
#include <iostream>
#include "limits.h"
using namespace std;
mt19937 mt;
uniform_int_distribution<int> * fixedDist;
uniform_int_distribution<int> * variableDist;
// this version creates and delete dist after just one use
int getIntFromRange1(int from, int to){
variableDist = new uniform_int_distribution<int>(from,to);
int num = (*variableDist)(mt);
delete variableDist;
return num;
}
// this version contains modulo
int getIntFromRange2(int from, int to){
int num = (*fixedDist)(mt);
int diff = to - from;
num = num % diff;
return num + from;
}
int main(){
mt.seed(123456);
fixedDist= new uniform_int_distribution<int>(0,INT_MAX)
int a = getIntFromRange1(1,10); // 1 and 10 are just for illustration
int b = getIntFromRange2(1,10); // can change freely
cout << "a: " << a << endl; // a: 6
cout << "b: " << b << endl; // b: 9
getchar();
}
答案 0 :(得分:10)
我愿意
int getIntFromRange1(int from, int to){
std::uniform_int_distribution<int> dist(from, to);
return dist(mt);
}
答案 1 :(得分:0)
我会像Jarod42's answer那样做:分配对象应该是轻量级的,所以当你需要一个随机数时构建一个新的分布是简单而快速的(这是随机引擎很昂贵)。
但是你也可以考虑这个实现:
inline int get_int_from_range(int from, int to)
{
using distribution_type = std::uniform_int_distribution<int>;
using param_type = typename distribution_type::param_type;
thread_local distribution_type dist;
return dist(mt, param_type(from, to));
}
理由是可能存在需要存储值/状态的分布。
这可能不是整数和均匀分布的情况,但有趣的是N4316 - std::rand replacement proposed implementation使用了这种技术。