2012-04-17 6 views
1

C++のTR1乱数生成スキームは、異なるスレッドのランダムエンジンの独立した状態を保持するという観点から、または独立したランダムシーケンスに対して古いCランタイムライブラリを改良しました。古いライブラリにはグローバルステートマシンがあり、これは通常悪いことです。ランダムなエンジン状態と複数の確定的な独立したランダムシーケンス

しかし、決定論的ランダムシーケンスを必要とするアルゴリズムを実装する場合、そのようなシーケンスから数値を描画する必要があるメソッドにエンジンを渡す必要があることがわかります。デザインの観点から見ると、ランダムシードを初期化するコードは、スタックのどのメソッドが乱数を使用しているかを知る必要はありません。ので、まだそれらの内側の方法は、自分のランダムエンジンを初期化することはできません。

  1. は、彼らが
  2. メモリ要件は、多くの下流のクライアントのために別々の状態を保っ防ぐユニークな再現性のある種子を作成するための知識が不足している

明確にするために、下流のメソッドはメインメソッドと同じシーケンスから数値を引き出す必要はありませんが、別々の実行で独立して再現可能である必要があります。

この難解な問題をどのように解決するかについてのアイデアはどれですか?

EDIT

あなたのアーキテクチャに関するいくつかの詳細を知らなくても、状況

typedef std::mt19937 RandEng; 

class PossibleRandomConsumer; 

class RandomProvider { 
public: 
    void foo() { 
     std::uniform_int<> uni; 
     uni(eng, 17); // using the random engine myself 
     std::for_each(children.begin(), children.end(), [](PossibleRandomConsumer& child) { 
      // may or may not need a random number. if it does, it has to be different than from other children, and from other providers 
      child.DoSomething(eng); 
     }); 
    } 
private: 
    RandEng eng; // unique seed per RandomProvider 
    std::array<PossibleRandomConsumer,10000> children; // lots of these... 
}; 
+0

複数の乱数シーケンスが実際に必要ですか、または1つのグローバルRNGで十分ですか? – thiton

+1

それぞれの 'クライアント'は異なるシーケンスを必要とします。同じエンジンを各クライアントに順番に渡すと(グローバルRNGのような)ジョブが実行されますが、それを渡すことはエレガントではありません。 – killogre

+0

@killogre:それについては何が違うのですか?あなたは仕事をするために必要な情報を各関数に渡しています。それにはRNGが必要なので、RNGに渡します。 –

答えて

0

ない簡単な質問を明確にするいくつかのコード。これは単なる試行です。
乱数を提供する方法を知っているインターフェイスへの参照を渡すのはどうですか?このインターフェイスは、質問された場合に乱数の量を返す関数を1つだけ持つことができます。このようにして、下流の関数(メソッド)から実装の詳細を隠すことができ、定数参照を渡すことはほぼ無料です。あなたはそれらの乱数がどこから来るかをトップレベルで決めることさえできます(ファイル、乱数ジェネレータ、室温...)。

class RandomNumberProvider { 
    public: 
     typedef std::vector<int> RandomArray; 
     virtual RandomArray Generate(unsigned numNumbers) = 0; 
}; 

void Consumer(const RandomNumberProvider& rndProvider) { 
    RandomNumberProvider::RandomArray rndNumber; 
    rndNumber = rndProvider(10); // get a sequence of 10 random numbers 
    ... 
} 

このようなものです。

+0

インターフェイスをダウンストリームに渡す必要がある場合、下流の誰かがそれを必要とするかもしれないことを知っています。現在、いくつかの実装で必要な場合に備えて、ランダムエンジンをダウンしています。 – killogre

+0

OK私はあなたに役立つ可能性のある抽象化のレベルを示したかっただけです。したがって、実装でランダムジェネレータが必要かどうかわからない場合は、乱数ジェネレータを要求できる静的インスタンスを実装することができます。おそらく、そのようなものを提供できるクラスの単一インスタンスまたはグローバルインスタンスです。ありがとう、@ pag3faul7。 – pag3faul7

+0

私は静的インスタンスを避けようとしていました(古いC rand()と同じです)。シングルトンは適切ではありませんが、プロバイダごとに1つのインスタンスがあります(上記の編集例を参照)。 – killogre

関連する問題