不要使用rand():C++中的随机数生成器指南1
不要使用 rand()
。为什么?直接上代码。下面的代码大约会输出什么值?
#include <cstdlib>
#include <iostream>
using namespace std;
const int ITERATIONS = 1e7;
int main() {
double sum = 0;
for (int i = 0; i < ITERATIONS; i++)
sum += rand() % 1000000;
cout << "Average value: " << sum / ITERATIONS << '\n';
}
应该是 500 , 000 500,000 500,000 左右,对吗?事实证明,这取决于编译器,在 Codeforces 上2,它输出的是 16382 16382 16382,根本不接近预期。自己试一试。
这里发生了什么?
如果你查一下 C++ 文档中的 rand()
,你会发现它返回“一个介于 0
和 RAND_MAX
之间的伪随机整数”。点击 RAND_MAX
,你会看到“这个值取决于实现。保证这个值至少是 32767 32767 32767”。在 Codeforces 上, RAND_MAX
正好是 32767 32767 32767。这实在是太小了!
但这还不止于此,random_shuffle()
也使用了 rand()
。回顾一下,为了随机地打乱大小为 n n n 的数组,我们需要生成 n n n 个随机位置 。但是如果 rand()
只能达到 32767 32767 32767,那么如果我们在一个元素数量明显多于这个数的数组上调用 random_shuffle()
会发生什么?是时候编写更多的代码了。你认为下面的代码能输出什么?
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int N = 3000000;
double average_distance(const vector<int> &permutation) {
double distance_sum = 0;
for (int i = 0; i < N; i++)
distance_sum += abs(permutation[i] - i);
return distance_sum / N;
}
int main() {
vector<int> permutation(N);