9

私は次のrandom_shuffleようなベクトルでを使用しています:

#include <algorithm>
vector <Card> deck;
//some code to add cards to the deck here
random_shuffle ( deck.begin(), deck.end() );

実行すると、デッキの内容が混同されますが、プログラムを再起動すると、この混同された順序が維持されます。

私は何か見落としてますか?どうすればそれを本当にランダムにすることができますか?

4

3 に答える 3

14

最初にsrandを使用して疑似乱数ジェネレータをシードする必要があります。

#include <algorithm>
#include <cstdlib>

...

std::srand(std::time(0));

vector <Card> deck;
//some code to add cards to the deck here
random_shuffle ( deck.begin(), deck.end() );

上記のリンクからの注意:

一般的に、疑似乱数ジェネレーターは、rand()を呼び出してプログラムを開始する前に、一度だけシードする必要があります。疑似乱数の新しいバッチを生成するたびに、繰り返しシードしたり、再シードしたりしないでください。

于 2012-11-19T18:37:33.847 に答える
9

現在のC++(つまり、C ++ 11)ではshuffle、疑似乱数ジェネレーター(PRNG)オブジェクト(シード可能)を3番目のパラメーターとして使用できるアルゴリズムを使用できます。

#include <iostream>
#include <random>
#include <algorithm>
#include <vector>
#include <string>
#include <ctime>
using namespace std;

int main(int argc, char **argv)
{
  vector<string> v;
  for (int i = 1; i<argc; ++i)
    v.push_back(argv[i]);
  mt19937 g(static_cast<uint32_t>(time(0)));
  shuffle(v.begin(), v.end(), g);
  for (auto &x : v)
    cout << x << ' ';
  cout << '\n';
}

(GCC 4.8.2の場合は、を介してコンパイルする必要がありますg++ -std=c++11 -Wall -g shuffle.cc -o shuffle

上記の例では、PRNGに現在のシステム時刻がシードされています。

C ++ 11より前のコンパイラの場合、STLにはアルゴリズムしかありませんが、random_shuffleそれでもオプションで数値ジェネレータオブジェクト/関数を指定できます。PRNGオブジェクトをそのように引き込むことはできないことに注意してくださいmtl19937(メンバーを提供しないためoperator()(U upper_bound))。

したがって、次のように独自のアダプタを提供できます。

#include <iostream>
#include <random>
#include <algorithm>
#include <vector>
#include <string>
#include <ctime>
using namespace std;

struct Gen {
  mt19937 g;
  Gen()
   : g(static_cast<uint32_t>(time(0)))
  {
  }
  size_t operator()(size_t n)
  {
    std::uniform_int_distribution<size_t> d(0, n ? n-1 : 0);
    return d(g);
  }
};

int main(int argc, char **argv)
{
  vector<string> v;
  for (int i = 1; i<argc; ++i)
    v.push_back(argv[i]);
  random_shuffle(v.begin(), v.end(), Gen());
  for (vector<string>::const_iterator i = v.begin(); i != v.end(); ++i)
    cout << *i << ' ';
  cout << '\n';
}
于 2014-02-06T09:11:00.717 に答える
3

次の行を配置します。

srand (time (0));

の先頭など、他のことを行うにコード内でmain()

それがないと、デフォルトのシードである1が常に使用され、rand()それを使用するものと同じシーケンスになります。

于 2012-11-19T18:38:38.730 に答える