3 つの異なるケースで乱数を生成する必要があります。私。サイコロ1個 ii.一対のサイコロ iii.3 サイコロ私の質問: 1. 3 つのケースすべてに対して乱数を生成するための適切なロジックを教えてください。2. 1 つではなく 2 つのサイコロの cses を考慮すると、ロジックは変わりますか? 3.乱数を生成する必要がある範囲は、ランダム関数のロジックにどの程度影響しますか?
3 に答える
範囲が十分に小さい場合、通常のモジュロ法を使用しても問題はないはずです。
int GetRandomInt(int Min, int Max)
{
return (rand()%(Max-Min+1))+Min;
}
(ここでMin
、Max
閉区間 [ Min
、Max
] を指定します)
サイコロを振るたびに1回呼び出します。アプリケーションの開始時 (乱数を取得するたびにではなくsrand(time(NULL))
、開始時のみ)を呼び出して、乱数ジェネレーターをシードすることを忘れないでください。
範囲が大きくなり始めると、次の 2 つの問題に直面する可能性があります。
まず、 の範囲はrand()
明らかに [0, +∞) ではなく、[0, RAND_MAX
] であり、RAND_MAX
は#define
少なくとも 32767 であることが保証されています。範囲 ( Max-Min
) が にまたがる場合RAND_MAX
、この方法では、返される可能性がゼロになるいくつかの数値があります。
RAND_MAX
これはより微妙です:が範囲よりも大きいと仮定しますが、それほど大きくはありませんRAND_MAX==1.5*/(Max-Min)
。この場合、結果の分布は均一ではありません。rand()
範囲 [0, RAND_MAX
] の整数を返します (この範囲の各整数は等確率である必要があります) が、除算の残りを で取っています(Max-Min)
。つまり、必要な範囲の前半の数値は、他の数値よりも返される確率が 2 倍になります。実際には、範囲の最初と3 分の 3からrand()
来る可能性がありますが、必要な範囲の後半は、範囲の 2/3 からrand()
。
これはあなたにとって何を意味しますか?
おそらく何もありません。サイコロを振るシミュレーターだけを実行したい場合は、モジュロ法で問題なく実行できます。これは、関連する範囲が小さいためです。2 番目の問題は、まだ存在しているにもかかわらず、ほとんど無関係です。範囲が 3 であるとします。MAX_RAND
32767: 0 から 32765 まで、0、1、および 2 の確率は同じですが、32767 まで上がると、0 と 1 は完全な 1/3 (10922/32766=0,333 ...) 2 の場合は 10922/32767 (~0,33332)、0 と 1 の場合は 10923/32767 (~0,33335) になる確率 (完全な分布をrand()
提供すると仮定)。
rand()
とにかく、このような問題を克服するためによく使われる方法は、次のような方法を使用して、範囲をより広い範囲に「引き延ばす」 (またはより狭い範囲に圧縮する) ことです。
int GetRandomInt(int Min, int Max)
{
return (int)(((double)rand())/MAX_RAND*(Max-Min))+Min;
}
同等性に基づくrand():MAX_RAND=X:(Max-Min)
。double への変換が必要です。それ以外の場合、rand()
とその最大値の間の整数除算は常に 0 (または のまれなケースでは 1 rand()==MAX_RAND
) になります。MAX_RAND が小さく、範囲が広すぎない場合は、最初に積を実行する整数演算で実行できます。そうしないと、オーバーフローのリスクが高くなります。
出力範囲が の範囲よりも大きい場合、rand()
「ストレッチ」と fp 値の切り捨て (int への変換による) が何らかの形で分布に影響を与えると思われますが、局所的にだけです (たとえば、小さな範囲では決して特定の数を取得しますが、グローバルな分布は問題ないように見えます)。
このメソッドは、C 標準ライブラリの乱数ジェネレーターの拡散した制限、つまり戻り値の下位ビットのランダム性が低いことを克服するのに役立つことに注意してください。出力範囲が狭い。
ただし、C 標準ライブラリ RNG は単純なものであり、「簡単な」統計規則に準拠するよう努めているため、簡単に予測できることに注意してください。「深刻な」乱数が必要な場合 (暗号化など) には使用しないでください。そのようなニーズには、専用の RNG ライブラリ (GNU Scientific Library のRNG 部分など) があります。または、本当にランダムなものが必要な場合は、実際の乱数サービスがいくつかあります (最も有名なものの 1 つはthisです)。数学的擬似 RNG ですが、実際のランダム ソース (放射性崩壊など) から数値を取得します。
はい、DarkDust が言ったように、これは宿題のように聞こえるので、それを念頭に置いて質問に答えるには、次のように言います。
--> No, the logic doesnt not change, no matter how many dices you include.
--> Easiest way to do this would be, just make a function that give you ONE
random function, and depending on how many dices you have, call it that
many times.
--> You can instead include for loop in the function and add the values into
array and return the array.
このようにして、100 個のサイコロに対して乱数を生成することもできます。
これは宿題のように聞こえるので、あなたにとって「十分」であるはずのヒントを提供します(プロは少し異なる方法で行うでしょう):random()
関数と%
(モジュロ)演算子を使用します。モジュロは除算後の「リマインダー」です。