2

RNGについて3つ質問があります。

1 つ目は、シードとして使用できるデータです。私はいつも時間を使ってきましたが、他にも簡単に入手できる種があるはずです.

c++ にはどのような簡単に利用できるシードがありますか?

RNG から出てくる次の値に基づいてランダムな間隔で RNG を再シードし、質問 1 への回答からランダムにシードを選択した場合、予測が困難でよりランダムな疑似ランダム チェーンが作成されますか?

最後に、C++ で範囲内の乱数を取得する最良の方法は何ですか? 私はモジュラス演算子を使用してきましたが、範囲内で均等に分散し、AI の決定のように高低を優先しないものが必要です。

4

4 に答える 4

3
  1. それはあなたが何を必要randとしているかによって異なります。多くの用途にtimeは、完全に適切です。他の人にとってはそうではありません。私は通常/dev/random、Unix マシンから 4 バイトを読み取り、利用できないtime場合 に戻り/dev/randomます。より効果的な解決策は、より高い解像度のタイマーを使用し、プロセスやマシン ID などをハッシュすることです。

  2. 再シードしても、何かを使用していない限り、おそらく状況はあまり変わりません/dev/random。他の使用可能な値のほとんどは、かなり予測可能です。

  3. が範囲の倍数である場合RAND_MAX、モジュロは正常に機能します。そうでない場合、唯一の解決策は値を破棄することです。値の合計があり RAND_MAX + 1、 が必要nです。RAND_MAX + 1また、すべての値をにマップしn、それぞれの入力数が同じになるようなマッピングはありませんn。通常の解決策は次のようなものです。

    int リミット = (RAND_MAX + 1) - (RAND_MAX + 1) % n;
    int 結果 = rand();
    while ( 結果 >= 制限 )
        結果 = ランド ();
    結果 % n を返します。

(ここでは、範囲内の結果を探していると仮定しています [0...n)。それRAND_MAX + 1はオーバーフローしません。)

最後に、ランダム値の品質が心配な場合は、 の多くの実装がrand()特に優れているわけではないことに注意してください。ブースト ランダム ジェネレーターの 1 つに切り替えることができます。

于 2011-06-22T12:46:41.967 に答える
2

をご覧くださいboost::random

覚えておいてください:

  • セキュリティのため、または確率過程のために、なぜ乱数が必要なのですか?
  • 「もっとランダム」とはどういう意味ですか?
  • アルゴリズムに従って再シードし、そのアルゴリズムが基礎となるRNGよりも予測可能である場合、最初よりも悪化します。シードが32ビット値の場合、真にランダムなシードソースでさえ、事態を悪化させる可能性があります。
  • ランダムなソースから余分なランダム性を「ミックスイン」する必要がある場合は、XORを介して行う方がよい場合があります。つまり、真に乱数の小さなパッドを維持し、それらをRNGの出力に周期的にXORします。 、時々そのパッドを再生します。そうすれば、RNGの貴重な内部状態を捨てることはありません。または、RNG内部にアクセスできる場合は、実際のランダムソースを使用して、同様のメカニズムでビットをときどきいじります。

簡単に使えると思いますboost::mt19937が、実際はアプリケーションによって異なります。

于 2011-06-22T12:19:13.247 に答える
1

RNG で簡単に利用できるシードの 1 つは、任意の時間関数です。シードはランダムである必要はありません。プログラムを開始するたびに異なるものであれば、それで十分です。疑似乱数を「よりランダム」にしようとするのは、ややばかげた試みです。これが必要な場合、ジェネレーターはその価値がありません。
また、真のランダム ノイズを定期的にシードしない限り、とにかく出力を「よりランダム」にすることはありません。また、のランダム ノイズを定期的にシードすると、シードのみが真にランダムになり、他の値は依然として決定論的であり、全体としてこのジェネレーターによって生成された他のシーケンスと同じ統計的特性があります。

歪んだ分布が受け入れられない場合に、2 の累乗以外の範囲の数値を取得するための通常の実装は、次のようになります。

range = high - low;

while((r = rand()) > range) {}

r += low;

モジュロと乗算/除算には、よく知られたスキューとオーバーフローの問題があります。

とはいえ、あなたが言ったようにAIの決定のためなら、ある結果が別の結果より1%高い可能性がある場合、誰も気付かないでしょう. したがって、単純にモジュロを使用するだけでおそらく十分であり、決定論的な時間があり、非常に単純です。また、モジュロで適切に機能する範囲をいつでも選択できることに注意してください。

于 2011-06-22T12:43:31.920 に答える
0

ほとんどのアプリケーションでは時間で十分です。より良い乱数が必要な場合は、そのような機能を提供する特定のライブラリを調べる必要があります。

範囲生成の場合、以下は結果を歪めません。

int random = rand() * RANGE / RAND_MAX;

于 2011-06-22T12:18:39.083 に答える