4

そのため、最終的な機能を構築するために複数のモジュールを組み合わせて何か大きなものを開発するたびに、同じ質問を疑問に思っていました:複数のモジュールがランダム関数を使用する必要がある場合、ランダムシードをどこで初期化するのですか?

ランダムが必要な特定のクラスがある場合 (たとえば、入力配列を自己実装のクイックソートでソートして初期化するクラスの場合、ピボットの選択にはランダムが必要になります)、通常はプライベートstatic bool isRandOn;変数があるため、ランダムピボットの選択、私はその変数をチェックしsrand(time(NULL));、ランダムがまだオンになっていない場合に行います.

名前空間に大量のユーティリティ関数がある場合、非常に似たようなことを行います。そのような変数を utils ライブラリ内の無名名前空間に置き、クラスとほぼ同じことを行います。

私が抱えている問題は、これらのモジュールを組み合わせるときです。それだけで、各モジュールがシードを複数回設定しないことを私は知っています。しかし、さまざまな量のモジュールを一緒に使用できるようにしたい、他の人が他のモジュールとは独立して 1 つまたは複数のモジュールを使用できるようにしたい...

では、複数のランダムシードが必要なモジュールを処理する最良の方法は何ですか? 各モジュールにシードを設定しますか? シードをまったく設定しないで、代わりにランダムの使用法を文書化し、ユーザーがモジュールを使用したい場合にシードを初期化するようにしますか? 第三の何か?

4

4 に答える 4

2

プログラム レベルで共有されるグローバルな状態に依存するのではなく、Boost.Random を使用することをお勧めします。

Boost.Random には 2 つの概念があります。

  • エンジン: 乱数を生成します
  • 分布: エンジンからの結果を適応させて、特定の分布 (正規、ポアソン、ガウスなど) に適合する結果を提供します。

各モジュールは独自のエンジン、または実際には複数のエンジンを持つことができます。特定のエンジンを同じモジュール内のいくつかの異なる機能間で共有する特別な理由はありません。

最後の言葉として、何をするにしても、バグの再現目的でシードを決定論的に設定する方法があることを確認してください。複数のエンジンを使用すると、バグの再現性が向上する場合があります (パーツの分離が役立ちます)。

于 2012-05-25T09:12:30.640 に答える
1

乱数生成用の特別な「モジュール」を作成し、それをアプリケーションの他の部分から使用できます。次に、乱数モジュールが初期化されるときにシードを 1 回だけ行います。

于 2012-05-25T09:07:29.787 に答える
0

@ペネロペが正解しました。の背後には、疑似乱数シーケンスを生成するための複雑なアルゴリズムがありますrand()rand_func(prev_rand)これは、前の疑似乱数から次の疑似乱数を生成する関数のようなものです。を初めて呼び出すと、これらの条件srand(time(NULL))で が設定され、まったく未定prev_randであると想定されます。そのため、 ( を設定する) を複数回time(NULL)安全に呼び出すことができます。srand()

特別な問題は、予測可能な疑似乱数シーケンスが必要な場合です。たとえば、srand(0)などですが、そうではないようです。

于 2012-05-25T09:29:22.540 に答える