我把上面所有的东西都涂红了,还有大约 40 个其他带有 c++ 的页面,比如 this 并观看了 video from Stephan T. Lavavej "STL"
并且仍然不确定随机数在实践中是如何工作的,所以我花了整整一个星期天来弄清楚它的全部内容以及它是如何工作和可以使用的。
在我看来,STL 关于“不再使用 srand”是正确的,他在视频 2 中解释得很好。
他还建议使用:
a) void random_device_uniform() -- 用于加密生成但速度较慢(来自我的示例)
b) mt19937 的示例 -- 更快,能够创建种子,未加密
我拿出了我可以访问的所有声称的 c++11 书籍,并找到了 f.e.像 Breymann (2015) 这样的德国作家仍然使用
srand( time( 0 ) );
srand( static_cast<unsigned int>(time(nullptr))); or
srand( static_cast<unsigned int>(time(NULL))); or
只用<random> 而不是<time> and <cstdlib> #includes - 所以要小心只从一本书中学习:)。
含义 - 自 c++11 起不应使用,因为:
程序通常需要随机数源。在新的之前
标准,C 和 C++ 都依赖于一个简单的 C 库函数,名为
兰特该函数产生统一的伪随机整数
分布在从 0 到系统相关最大值的范围内
至少是 32767。
rand 函数有几个问题: 许多(如果不是大多数)程序
需要与产生的随机数不同的范围内的随机数
兰特某些应用程序需要随机浮点数。一些
程序需要反映非均匀分布的数字。
程序员在尝试转换时经常会引入非随机性
rand 生成的数字的范围、类型或分布。
(引自 Lippmans C++ 入门第五版 2012)
我终于在 Bjarne Stroustrups 较新的 20 本书中找到了最好的解释 - 他应该知道他的东西 - 在“C++ 2019 之旅”、“使用 C++ 2016 的编程原理和实践”和“ C++ 编程语言第 4 版 2014”以及“Lippmans C++ 入门第五版 2012”中的一些示例:
而且非常简单,因为随机数生成器由两部分组成:
(1) 产生一系列随机或伪随机值的引擎。
(2) 将这些值映射到某个范围内的数学分布的分布。
尽管微软的 STL 专家有意见,Bjarne Stroustrups 写道:
在 中,标准库提供了随机数引擎和
分布(§24.7)。默认使用 default_random_engine ,
选择它是因为适用性广,成本低。
void die_roll() 示例来自 Bjarne Stroustrups - 使用 using (more bout that here) 生成引擎和分发的好主意。
为了能够实际使用 <random> 中的标准库提供的随机数生成器这里有一些带有不同示例的可执行代码,已减少到希望安全时间的最少必要性和钱给你们:
#include <random> //random engine, random distribution
#include <iostream> //cout
#include <functional> //to use bind
using namespace std;
void space() //for visibility reasons if you execute the stuff
{
cout << "\n" << endl;
for (int i = 0; i < 20; ++i)
cout << "###";
cout << "\n" << endl;
}
void uniform_default()
{
// uniformly distributed from 0 to 6 inclusive
uniform_int_distribution<size_t> u (0, 6);
default_random_engine e; // generates unsigned random integers
for (size_t i = 0; i < 10; ++i)
// u uses e as a source of numbers
// each call returns a uniformly distributed value in the specified range
cout << u(e) << " ";
}
void random_device_uniform()
{
space();
cout << "random device & uniform_int_distribution" << endl;
random_device engn;
uniform_int_distribution<size_t> dist(1, 6);
for (int i=0; i<10; ++i)
cout << dist(engn) << ' ';
}
void die_roll()
{
space();
cout << "default_random_engine and Uniform_int_distribution" << endl;
using my_engine = default_random_engine;
using my_distribution = uniform_int_distribution<size_t>;
my_engine rd {};
my_distribution one_to_six {1, 6};
auto die = bind(one_to_six,rd); // the default engine for (int i = 0; i<10; ++i)
for (int i = 0; i <10; ++i)
cout << die() << ' ';
}
void uniform_default_int()
{
space();
cout << "uniform default int" << endl;
default_random_engine engn;
uniform_int_distribution<size_t> dist(1, 6);
for (int i = 0; i<10; ++i)
cout << dist(engn) << ' ';
}
void mersenne_twister_engine_seed()
{
space();
cout << "mersenne twister engine with seed 1234" << endl;
//mt19937 dist (1234); //for 32 bit systems
mt19937_64 dist (1234); //for 64 bit systems
for (int i = 0; i<10; ++i)
cout << dist() << ' ';
}
void random_seed_mt19937_2()
{
space();
cout << "mersenne twister split up in two with seed 1234" << endl;
mt19937 dist(1234);
mt19937 engn(dist);
for (int i = 0; i < 10; ++i)
cout << dist() << ' ';
cout << endl;
for (int j = 0; j < 10; ++j)
cout << engn() << ' ';
}
int main()
{
uniform_default();
random_device_uniform();
die_roll();
random_device_uniform();
mersenne_twister_engine_seed();
random_seed_mt19937_2();
return 0;
}
我认为这一切都加起来了,就像我说的那样,我花了很多时间阅读这些例子 - 如果你有更多关于数字生成的内容,我很高兴通过 pm 或 in评论部分,如有必要,将添加或编辑此帖子。布尔