我正在使用ubuntu 10.10,我想用几个随机测试来测试我的C++程序,所以我想生成它们。我写了发电机:
// gen.cpp
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;
int main() {
srand(time(NULL));
int n=rand()%100;
int k=rand()%n+1;
printf("%d %dn", n,k);
for(int i=0; i<n; i++) {
int a = rand()%100;
printf("%dn", a);
}
return 0;
}
然后在终端中输入:
for((i=0; i<10; i++)); do ./gen > $i.in; done
但结果是所有 *.in 文件都包含相同的数字。当我输入:
./gen > 0.in
./gen > 1.in
依此类推,那么一切都很好 - 所有 *.in 文件都不同。但我不想每次需要它们时都手动创建它们。我想循环执行此操作。为什么会这样,我该如何解决这个问题?
在bash
循环中设置延迟,以便它不会每次都使用相同的种子。因为您使用time()
作为种子,所以同一秒中的所有执行都会为您提供相同的序列。
sleep
应该可以做到这一点,例如:
for((i=0; i<10; i++)); do ./gen > $i.in; sleep 2; done
当您从time()
(整数秒数)播种随机数时 - 如果您在同一秒内多次运行该程序,您将获得相同的结果。
如果你想要不同的数字,你应该使用一个种子,该种子在运行之间会有所不同。
请注意,如果您只想生成一个随机数列表并且您在 Linux 上,则/dev/urandom
(非阻塞)或/dev/random
(阻塞)的设备就可以解决问题。
使用新的更高质量的 C++11 版本更改旧 C 随机数生成器的使用:
// gen.cpp
#include <iostream>
#include <cstdio>
#include <random>
using namespace std;
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis;
int n = dis(gen) %100;
int k = dis(gen) % n + 1;
printf("%d %dn", n, k);
for (int i = 0; i != n; ++i)
{
int a = dis(gen) % 100;
printf("%dn", a);
}
return 0;
}