使用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”方法来做几乎所有的事情。
例子:
-
随机数在一个范围内
auto val = Random::get(-10, 10); // Integer auto val = Random::get(10.f, -10.f); // Float point
-
随机布尔值
auto val = Random::get<bool>( ) // 50% to generate true auto val = Random::get<bool>( 0.7 ) // 70% to generate true
-
来自std :: initilizer_list的随机值
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
-
来自迭代器范围或所有容器的随机迭代器
auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator auto it = Random::get( vec ); // return random iterator
甚至更多的东西! 看看github页面:
这是我刚刚写的东西:
#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 ++,