1

我正在使用 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 %d\n", n,k);
  for(int i=0; i<n; i++) {
    int a = rand()%100;
    printf("%d\n", a);
  } 

  return 0;
}

然后在终端输入:

for((i=0; i<10; i++)); do ./gen > $i.in; done

但结果是所有 *.in 文件都包含相同的数字。当我输入:

./gen > 0.in
./gen > 1.in

依此类推,然后一切正常 - 所有 *.in 文件都不同。但我不想每次需要它们时都手动创建它们。我想循环执行此操作。为什么会这样,我该如何解决?

4

3 回答 3

4

你需要在你的bash循环中放一个延迟,这样它就不会每次都使用相同的种子。因为您将time()其用作种子,所以同一秒内的所有执行都会为您提供相同的序列。

Asleep应该可以解决问题,例如:

for((i=0; i<10; i++)); do ./gen > $i.in; sleep 2; done
于 2012-11-30T22:22:34.883 回答
2

这是因为当您从time()(整数秒)播种随机数时 - 如果您在同一秒内多次运行程序,您将获得相同的结果。

如果你想要不同的数字,你应该使用在运行之间不同的种子。

请注意,如果您只想生成一个随机数列表并且您在 linux 上,则设备/dev/urandom(非阻塞)或/dev/random(阻塞)可以解决问题。

于 2012-11-30T22:25:29.020 回答
2

使用更高质量的新 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 %d\n", n, k);
    for (int i = 0; i != n; ++i)
    {
        int a = dis(gen) % 100;
        printf("%d\n", a);
    }

    return 0;
}
于 2012-11-30T22:38:39.317 回答