2

乱数生成を変数で制御できるようにしたい。たとえば、私が 100 と言った場合、数値は最大のランダム性で生成されるべきであり、50 と言った場合、数値は「ランダム」であってはなりません。「0」と言った場合、おそらく乱数はまったくランダムであってはなりません - おそらく生成されたすべての数値は同じです。

これらのような制御された乱数を生成するために何を使用できるか考えていますか? いくつかの C++ 組み込みライブラリ、またはおそらく Boost ライブラリがこれを行うかどうか、何か考えはありますか?

乱数の同じシーケンスを再生成する方法があるとよいので、ジェネレーターをシードする方法もよいでしょう。

4

6 に答える 6

5

要件を説明する方法は、正規分布(別名ガウス分布)を使用することが道のりである可能性があることを示唆しているようです。これには、平均と標準偏差の2つのパラメーターがあります。標準偏差を非常に低く設定すると、おそらく平均に非常に近いランダムな値が得られます。大きな値に設定すると、より広く分散されます。

C ++ 11では、標準ライブラリから正規分布を利用できます。C ++ 11がオプションでない場合は、Boostライブラリにもオプションがあります。

次にいくつかのサンプルコードを示します。

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <cmath>
#include <iomanip>

int main()
{
  std::random_device rd;
  std::mt19937 gen(rd());

  std::cout << std::fixed << std::setprecision(3);

  /* Mean 5, standard deviation very low (0.002): */
  std::normal_distribution<> d1(5,0.002);
  for (int i = 0 ; i < 20 ; ++i)
    std::cout << std::setw(7) << d1(gen) << "  ";
  std::cout << std::endl;

  /* Mean 5, standard deviation relatively high (2.0): */
  std::normal_distribution<> d2(5,2);
  for (int i = 0 ; i < 20 ; ++i)
    std::cout << std::setw(7) << d2(gen) << "  ";
  std::cout << std::endl;

  return 0;
}

出力は次のとおりです。

4.998    5.003    5.001    5.002    5.001    5.001    4.998    5.000    4.999    5.001    5.000    5.003    4.999    5.000    5.001    4.998    5.000    4.999    4.996    5.001  
2.781    3.795    5.669   -0.109    7.831    3.302    3.823    4.439    4.672    4.461    6.626    5.139    6.882    5.406    6.526    5.831    6.759    2.627    3.918    4.617

ご覧のとおり、最初の行ではすべての数値が5に非常に近く(つまり、「ランダム性」が低い)、2番目の行では数値がはるかに広く広がっています。

(編集:もちろん、これらの数値のランダム性は実際には影響を受けません。標準偏差パラメーターによって、値がより小さな(stddev low)またはより広い(stddev high)範囲の数値で現れる可能性が高くなるだけです。)

于 2012-10-19T03:16:26.647 に答える
1

Boostには、まさにあなたが望むことを行うためのライブラリがあります。このリンクをたどってブースト チュートリアル ページにアクセスし、数値分布の実行方法を学習してください。

于 2012-10-19T03:02:17.523 に答える
1

ランダムなビット シーケンスを生成することから始めます。

ノブが 100 のときは、シーケンスをそのままにしておきます。

ノブが 50 の場合、1 つおきのビットを強制的に 1 にします。

ノブが 0 の場合、すべてのビットを強制的に 1 にします。

[更新、詳しく説明]

この提案は、おそらく聞こえるほど恣意的なものではありません。

真にランダムなデータ ソースには、データのビットごとに 1 ビットのエントロピーがあります。その半分のエントロピー率 (つまり、データの 2 ビットごとに 1 ビットのエントロピー) が必要な場合は、1 ビットおきに 1 を設定するだけです。 3 ビットのデータ -- 3 ビットのうち 2 ビットごとに 1 を設定できます。

「データのビットあたりのエントロピーのビット数」は、数字のシーケンスがどれほどランダムであるかについて完全に合理的な定義です...そして、3ビットのうち2ビットがランダムで、他のビットが固定されている場合、シーケンスを「66%ランダム」と呼ぶことはごく自然な定義。

于 2012-10-19T03:48:35.323 に答える
1

このXKCDにはポイントがあります。あなたはそれについてしばらく瞑想したいと思うかもしれません。「興味のない数字」が存在しないのと同様に、「乱数」などは実際には存在しません。

求めることができるのは、いくつかのテストを満たす一連の数値です。たとえば、任意のサブシーケンスで、各値の頻度がほぼ同じになるか、シーケンス内の数値と後続の値の間に相関関係がないことです。これらのテストは、シーケンスが「ランダム」であることを証明しません。他のそのようなシーケンスを代表している可能性があるというだけです。おそらく、非自然、準自然、または超自然的な力によって制約されない限り、現実の世界に現れるシーケンス.

Rosencrantz と Guildenstern のコイン投げの単純なシーケンスでは、偏った分布が実存的なものでさえも疑念を引き起こすことが非常に簡単にわかります。しかし、コイントスが完全にバランスが取れていたとしましょう: 表、裏、表、裏、表、裏、表、裏… カルパティア山脈を通過します。それは多かれ少なかれランダムでしょうか?R(またはG)が言うように、「議論する」.

于 2012-10-19T03:26:54.190 に答える
0

おそらく最も簡単な解決策は、C ++でsrandとrandを使用することです。どちらも疑似ランダム性を使用します。srandのシード値が大きいほど、randによって生成された乱数でパターンが出現するのにかかる時間が長くなります。

編集:

http://www.cplusplus.com/reference/clibrary/cstdlib/srand/

于 2012-10-19T03:05:54.893 に答える
0
r1 = Mathf.PingPong(Mathf.PerlinNoise(map,23)*5+map*.01, 1);

map はランダム シードで、整数です。ピンポンは 0 から 1 の間のすべての値を跳ね返します。パーリン ノイズは、map の倍数を追加することによって 0 から 1 の間で均一化されるある種のノイズを生成します。

于 2013-04-01T02:44:13.943 に答える