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

古い C 乱数ジェネレーターの使用法を新しい高品質の C++11 バージョンに変更します。

// 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 に答える
2

time()これは、 (整数の秒数)から乱数をシードしているときに、同じ秒にプログラムを複数回実行すると、同じ結果が得られるためです。

異なる数が必要な場合は、実行ごとに異なるシードを使用する必要があります。

乱数のリストを生成したいだけで、Linux を使用している場合は、デバイス/dev/urandom(非ブロッキング) または/dev/random(ブロッキング) でうまくいくことに注意してください。

于 2012-11-30T22:25:29.020 に答える