使用C ++ 11随机库生成随机数

正如标题所示,我试图找出使用新的c ++ 11 <random>库生成随机数的方法。 我已经试过这个代码:

 std::default_random_engine generator; std::uniform_real_distribution<double> uniform_distance(1, 10.001); 

我所拥有的代码的问题是,每次我编译和运行它时,都会生成相同的数字。 所以我的问题是随机库中的其他function可以做到这一点,而真正的随机?

对于我的特殊用例,我试图在[1, 10]

微软的Stephan T. Lavavej(stl)在Going Native上做了一个讲座,讲述如何使用新的C ++ 11随机函数,以及为什么不使用rand() 。 其中,他包括一个幻灯片,基本上解决了你的问题。 我从下面的幻灯片复制了代码。

你可以在这里看到他的全面讨论: http : //channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

 #include <random> #include <iostream> int main() { std::random_device rd; std::mt19937 mt(rd()); std::uniform_real_distribution<double> dist(1.0, 10.0); for (int i=0; i<16; ++i) std::cout << dist(mt) << "\n"; } 

我们使用random_device来播种名为mt的随机数发生器。 random_device()mt19937慢,但是它不需要播种,因为它需要从你的操作系统(它将从不同的位置来源,例如RdRand )发送随机数据。


看看这个问题/答案 ,看起来uniform_real_distribution返回一个范围[a, b) ,你想要[a, b] 。 要做到这一点,我们的uniform_real_distibution实际上应该是这样的:

 std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX)); 

我的“随机”库为C ++ 11随机类提供了一个高度方便的包装。 你可以用一个简单的“get”方法来做几乎所有的事情。

例子:

  1. 随机数在一个范围内

     auto val = Random::get(-10, 10); // Integer auto val = Random::get(10.f, -10.f); // Float point 
  2. 随机布尔值

     auto val = Random::get<bool>( ) // 50% to generate true auto val = Random::get<bool>( 0.7 ) // 70% to generate true 
  3. 来自std :: initilizer_list的随机值

     auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or... 
  4. 来自迭代器范围或所有容器的随机迭代器

     auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator auto it = Random::get( vec ); // return random iterator 

甚至更多的东西! 看看github页面:

https://github.com/effolkronium/random

这是我刚刚写的东西:

 #include <random> #include <chrono> #include <thread> using namespace std; //============================================================== // RANDOM BACKOFF TIME //============================================================== class backoff_time_t { public: random_device rd; mt19937 mt; uniform_real_distribution<double> dist; backoff_time_t() : rd{}, mt{rd()}, dist{0.5, 1.5} {} double rand() { return dist(mt); } }; thread_local backoff_time_t backoff_time; int main(int argc, char** argv) { double x1 = backoff_time.rand(); double x2 = backoff_time.rand(); double x3 = backoff_time.rand(); double x4 = backoff_time.rand(); return 0; } 

你有两种常见的情况。 首先是你需要随机数字,而不是质量或执行速度过于臃肿。 在这种情况下,使用下面的macros

 #define uniform() (rand()/(RAND_MAX + 1.0)) 

在0到1 – ε的范围内给出p(除非RAND_MAX大于双精度,但是当你来到它的时候会担心)。

int x =(int)(uniform()* N);

现在给0到N -1的随机整数。

如果你需要其他发行版,你必须改变p。 或者有时多次调用uniform()会更容易。

如果你想要可重复的行为,用一个常数种子,否则种子调用time()。

现在,如果您对质量或运行时间性能感到困扰,请重写uniform()。 但是否则不要触摸代码。 始终保持统一()在0至1减eps。 现在你可以包装C ++的随机数字库来创build一个更好的uniform(),但这是一种中等的select。 如果您对RNG的特性感到困扰,那么也应该投入一些时间来了解底层方法的工作原理,然后提供一个方法。 所以你已经完全控制了代码,并且可以保证使用相同的种子,序列总是完全一样的,无论平台是哪一个版本的C ++,