- ベストアンサー
乱数の初期化について
Cでモンテカルロシミュレーションを行っています。 乱数Merssenne twisterをつかって、各試行ごとに乱数を 時間で以下のように初期化しています。 init_genrand ((unsigned)time(NULL)) ; だいたい10000~100000回くらいシミュレーションを行う必要があって、 各試行は使用しているPCだと一瞬で終了します。 このときに上記の方法で種を初期化すると、 きちんと確認はしていないのですが、 試行時間が短すぎで種の時間が進んでいないような状態が起こります。 パソコンの時間で初期化する場合、間隔が短すぎると初期化種がかぶる ことはありますか。 もしあるなら、1回の試行時間が短いシミュレーションを各々初期化できる ような初期化の方法を教えていただけないでしょうか。 環境はcore2duo2.16、vista32、コンパイラはVisualC++2008です。 よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
連続投稿ですみません。 もしかして、試行ごとに別のプロセスを起こしているのでしょうか? 状況次第ですが、根本的にやり方に問題があるような気がします。
その他の回答 (5)
- Tacosan
- ベストアンサー率23% (3656/15482)
#5 の「プロセス」というのは「処理過程」の意味じゃなくて「(プログラムの) 1回の起動」という意味だと思う. つまり, 「1回の試行を行うプログラム」を 1000~10000回実行するってことじゃなくて, 「1000~10000回くらいシミュレーションをするプログラム」を作るってことでしょう.
補足
全くその通りでした。 質問以前に根本的に乱数について勘違いしてました。
- jacta
- ベストアンサー率26% (845/3158)
> time関数の戻り値が同じならそうやってrandで得られる値だって同じじゃないの? srandは1回しか呼ばないことが前提です。
- Gotthold
- ベストアンサー率47% (396/832)
Mersenne twisterの内部状態を適当なファイルにでも保存しておいて 2回目以降はその状態を引き継いで使えば良いのでは。 > time関数の結果をsrandに与えて、randで得た値 time関数の戻り値が同じならそうやってrandで得られる値だって同じじゃないの?
- jacta
- ベストアンサー率26% (845/3158)
いっそのこと、time関数の結果をsrandに与えて、randで得た値をinit_genrandに渡すのも一つの手です。
- D-Matsu
- ベストアンサー率45% (1080/2394)
time()は「秒単位の時間を得る」ので、一瞬で終わってしまうような処理をループで回す場合は全て同じ種になる(秒単位の時間が変わらないので)可能性が高いでしょう。 _ftime()でミリ秒単位の時間が取れるので、そちらを利用するのがよいのではないかと。 http://msdn.microsoft.com/ja-jp/library/z54t9z5f.aspx
お礼
回答ありがとうございました。 検索するとgetTimeGet関数というのがWindows環境で つかえたので、それを用いて解決しました。_ftime()関数は もっとユニバーサルなCの標準的な関数なのでしょうか。
お礼
お返事が遅くなって申し訳ありません。 恥ずかしながら大きな勘違いをしていて、 自分が行っていたのは同じプロセス内で変数を初期化しようと いう意味のないことをしようとしていました。 アドバイスは参考にさせていただきます。 ありがとうございました。
補足
回答ありがとうございました。 別のプロセスではなく、初期値以外は同じプロセスです。 種の種を時間で初期化して使うというのは参考になりました。 やるうえで問題はあるのでしょうか。