• ベストアンサー

完全な乱数を生成する方法

C言語で乱数を生成するときに、今まで srand(time(NULL)); を使用していたのですが、それだと1秒以内に複数の処理を行った際に、 同一の乱数が生成されてしまいます。 時間にとらわれずに完全にランダムな数字を出現させるにはどのような方法を取るのが簡単なのでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

乱数を生成させるたびにsrand(time(NULL));しているのなら、そうなるでしょう。 どこかで最初に一回だけ呼ぶので十分ではありませんか?

windywatery
質問者

お礼

関数の中にsrandを突っ込んでいたためでした・・・>< ありがとうございました^^

その他の回答 (3)

noname#21649
noname#21649
回答No.4

Fotran なので多少異なる場合があります。 多分 32ビットの符号付整数を16ビット符号付整数で割るという一般的ルーチンを使っていると思います。 3次元ですとたしか13面に収束するのでちょっと面倒ですが。 この擬似乱数プログラム(乱数の入門ですからどこかに有るかと思います)を探してきて.組込み関数を使わずに個別のルーチンとして使うのが簡単な方法化と思います。 なお.確実な擬似らん数は.外部配列にテーブルを作り.組込み関数でかき混ぜるのがなんと言っても楽です。周期を自分で管理できますから。 モンテカルロでちょっと遊んだときに目いっぱい苦しんだのが乱数の周期性です。少しならばなんとでもなるのですが.ある程度大きくなると周期性とかたよりが出てしまって苦しみます。通常無限大に発散させれば偏りが消えることにはなっていますが.実数で偏りを除くのに苦労しました。

  • Soli
  • ベストアンサー率11% (7/61)
回答No.3

どの環境でプログラミングしておられますか? 超高速で複数のsrandをする場合はこの方法ではダメかもしれませんが、 Win32で作っているならば GetLocalTime()等のAPIを使って ミリ秒を取得し、それを使って乱数を初期化すれば良いと思います。 もっとシビアなタイミングに対応するならば 環境は限られてくるかもしれませんが、 QueryPerformanceCounter()APIを使うと ミリ秒よりも高精度な値が取れます。

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.2

お使いの環境に乱数装置が実装されていないか調べてみるといいかもしれません。 FreeBSDにはsrandomdev() という乱数装置を利用した乱数系列初期化ルーチンとrandom()という比較的高精度な32bit乱数が実装されています。 この乱数はsrand()/rand()より3割ほど遅いが乱数の精度はずっとよいものです。 #1氏がツッこんでいる「生成されるたびに」ということですが、毎回srandするのではなく、例えばCGIで、複数のプロセスが独立に起動されることを想定しているのでしょうか。 その場合でしたら、共有メモリにカウンタを用意するとか、プロセスid(などのプロセスに固有の値)+time(NULL)をキーにするなどすれば、よいのではないでしょうか。