乱数発生器の制御"rng"の影響範囲について

12 views (last 30 days)
shun
shun on 21 Jul 2023
Commented: shun on 24 Jul 2023
コード内で複数の乱数(A, B, C)を生成しており,一部の乱数のみシードを指定したいとします.
下のコードでは,Cのみ乱数シードを指定したいのですが,AとBともに実行毎に同じ行列が生成されます.
clear all;
%rng('shuffle');
A = randi(10,5) %下のrngの影響を受ける
test_rand %下のrngの影響を受ける
rng(1);
C = randi(10,5)
function test_rand
B = randi(10,5)
end
この場合,シードをシャッフルする以外の解決方法はありますか?(2行目にコメントアウトしています)
一度コード内にrngを記述すると,その上の行や,関数内にも影響を与えるのは仕様でしょうか.
MATLABのシード設定について,その影響範囲を教示いただけると幸いです.

Accepted Answer

Akira Agata
Akira Agata on 21 Jul 2023
Edited: Akira Agata on 21 Jul 2023
「一度コード内にrngを記述すると、その上の行にも影響を与えるのか?」とのご質問ですが、結論から言いますと「No」となります。rng(1) はその行以降の処理に影響を与えるのみで、それ以前の処理には影響しません。
おそらく、プログラムを何度も連続して実行すると「AとBともに同じ行列が生成」されるためにそのような疑問を持たれたのではないかと思います。しかし注意深く見て頂くと、MATLABを起動して 1回目にプログラムを実行したときと、2回目の実行時では配列A,Bは異なる値が生成されていると思います。ところが 2回目以降は何度実行しても「AとBともに同じ行列が生成」されます。さて、何が起きているのでしょうか?
謎を解く手がかりは、「プログラムを連続して実行する」という部分にあります。ここで、MATLABを起動した時点での乱数発生器の状態をXとします。1回目にプログラムを実行すると、乱数発生器Xから配列Aが生成されることになります。その後、プログラム終了時点で乱数発生器の状態がYになったとします。2回目にプログラムを実行すると、乱数発生器Yから配列Aを生成するので、1回目とは異なる配列となります。さて、2回目のプログラム終了時点での乱数発生器の状態はどうなっているでしょうか?答えは「1回目終了時と同じ、Yになっている」です。これは、プログラムの中に rng(1) が入っているためです。すると 3回目に実行すると、ふたたび乱数発生器Yから配列Aが生成されるため、2回目の実行時と同じ配列Aになってしまうというわけです。
これを回避するには、やはり 2行目の rng('shuffle') を含めるのが確実かと思います。
  3 Comments
Atsushi Ueno
Atsushi Ueno on 22 Jul 2023
横やり失礼致します。
「グローバル(の乱数)ストリーム」と「独立した乱数ストリーム」が存在するという事ですね。
  • rng 関数は、グローバル ストリームのシード値を設定します
  • RandStream 関数は、独立した乱数ストリームを作成します
> どちらがより適切でしょうか
Cのみ他とは独立した乱数列として管理したいのであれば、乱数ストリームを個別で指定するのが適切です。グローバル ストリームはその存在を意識せずに乱数を扱えますが、皆が共有する一つの乱数ストリームです。
独立した乱数ストリームを使う動機は、上記ドキュメントにもある通り下記の様なものでしょう。
  • 何らかの理由で、グローバル ストリームを使いたくない
  • 複数の乱数列を管理したい (複数の乱数ストリームやサブストリームを使う)
下記は既にご存知の内容かと思われる余談です。
  • 「乱数ストリーム」とは「滅茶苦茶な旋律の楽譜」の様なものです。その内容はランダムでも、同じシード値でリセットした乱数発生器から出てくる乱数列はいつも決まって同じになります。
  • 例えば、迷路ゲームのステージ番号をシード値として乱数発生器をリセットすれば、乱数ストリームを迷路データとして活用できます。(ステージ番号がわかれば同一の迷路データを生成する事が可能)
  • プログラムを起動する度に異なる乱数列を生成する常套手段は「時刻データをシード値として乱数生成器をリセットする」事です。rng('shuffle');もこれと同じです。
shun
shun on 24 Jul 2023
Akira Agata様
私が勘違いしている原因も汲み取りご回答いただきありがとうございました.以前はmatlabで乱数を使用するのに不安があったのですが,今後はしっかりと理解した上で作業できるので嬉しく思います.ありがとうございました.
Atsushi Ueno様
乱数ストリームに種類があることを明確にしてくださり,ありがとうございました.randi(10,5,'seed',15)のような書き方だと直感的にわかりやすいのですが,Ueno様のお陰でハッキリと理解できました.

Sign in to comment.

More Answers (0)

Products


Release

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!