3

複数の CPU を使用して並行して実行される matlab スクリプトを作成したいと考えています。スクリプトは、正規分布の乱数のシーケンスを出力する必要があります。現時点で、私のスクリプトは次のようになります。

matlabpool close force local
clusterObj = parcluster;
matlabpool(clusterObj);

parfor K = 1:10
    disp(randn)
end

期待どおりに一連の乱数を出力します。ただし、コードをもう一度実行すると、まったく同じ一連の数字が出力されます。これいらない。スクリプトを実行するたびに、独立してランダムな一連の数字が出力されます。同様に、matlab を起動するたびに、スクリプトを初めて実行するときに、ランダムに生成された 10 個の数字の異なるシーケンスを出力する必要があります。どうすればいいですか?

4

4 に答える 4

4

これまでに示した解決策は実際には正しくなく、悪い考えでさえあるかもしれません。ジェネレーターのシードを繰り返し設定することは避けるべきです。さらに重要なことに、異なるシードで別々に作成された 2 つのストリームは必ずしも独立しているとは限りません。これは、複数のストリームの作成について説明するこのページで対処されます。

独立したストリームを明示的にサポートしていないジェネレータ タイプの場合、さまざまなシードが複数のストリームを作成する方法を提供します。ただし、複数の独立したストリーム用に特別に設計されたジェネレーターを使用する方が、ストリーム全体の統計的特性がよりよく理解されるため、より良いオプションです。

したがって、最高の統計特性を保証するには、サブストリームをサポートするジェネレーターを使用するのが最善です。残念ながら、乗法ラグ フィボナッチ ジェネレーター ( 'mlfg6331_64') と組み合わせた多重再帰ジェネレーター ( 'mrg32k3a') のみが現在このプロパティをサポートしています。デフォルトの Mersenne Twister ジェネレーター ( 'mt19937ar') と比較すると、これらの周期は大幅に短くなっています。サブストリームを持つ乱数ストリームを作成して使用する方法は次のとおりです。

seed = 1;
n = 10;
[stream{1:n}] = RandStream.create('mrg32k3a','NumStreams',n,'Seed',seed);
parfor k = 1:n
    r = randn(stream{k},[1 3]);
    disp(r);
end

いくつかのこと。ループ外の 1 回の呼び出しですべての乱数を生成するだけで、パフォーマンスが大幅に向上する場合があります。これにより、デフォルトの Mersenne Twister アルゴリズムを使用することもできます。これは、たとえば、大規模なモンテカルロ シミュレーションを行う予定がある場合に重要になる場合があります。乱数 (および並列化) を扱う場合は、時間をかけてRandStreamクラスのドキュメントを読み、ここで例を確認することをお勧めします。

于 2013-08-09T18:13:28.380 に答える
0

反復ごとにランダム シードを異なる値に設定できます。

matlabpool close force local
clusterObj = parcluster;
matlabpool(clusterObj);

rng('shuffle');
seeds = round(10000*abs(randn(10,1)));

parfor K = 1:10
    rng(seeds(K))
    disp(randn)
end 
于 2013-08-09T16:09:59.500 に答える