Ruby の乱数生成方法: まず、プログラムの先頭の任意の場所で srand を呼び出します。その後、それを実行すると、一連の異なる一見乱数を生成できます。
この記事の動作環境: Windows 7 システム、Dell G3 コンピューター、Ruby バージョン 3.0.0。
Ruby での乱数の生成
レンジ プログラム (通常はゲームやシミュレーション) で乱数を生成するために使用できます。真の乱数を生成できるコンピューターはありませんが、Ruby は擬似乱数を返すメソッドへのアクセスを提供します。
数値は実際にはランダムではありません
純粋に計算だけで真に乱数を生成できるコンピューターはありません。彼らができる最善のことは、ランダムに見えて実はそうではない一連の数値である擬似乱数を生成することです。
人間の観察者にとって、これらの数値は実際にランダムに見えます。短い繰り返しシーケンスはなく、少なくとも人間の観察者にとっては完全にランダムです。ただし、十分な時間と動機があれば、元のシードを発見し、シーケンスを再作成し、シーケンス内の次の番号を推測することは可能です。
したがって、この記事で説明する方法は、暗号的に安全である必要がある数値の生成には使用しないでください。
上で述べたように、擬似乱数生成器 (PRNG) は、新しい乱数を生成するたびに異なるシーケンスを生成するようにシードする必要があります。どのような方法も魔法ではないことに留意してください。これらの一見乱数は、比較的単純なアルゴリズムと比較的単純な算術を使用して生成されます。 PRNG をシードすると、毎回異なるポイントから開始できます。シードを行わないと、毎回同じ一連の数値が生成されます。
Ruby では、カーネルの #srand メソッドをパラメータなしで呼び出すことができます。時間、プロセス ID、シーケンス番号に基づいて乱数シードが選択されます。プログラムの先頭の任意の場所で srand を呼び出すだけで、実行するたびに異なる一連の一見乱数が生成されます。このメソッドは、プログラムの開始時に暗黙的に呼び出され、PRNG に時刻とプロセス ID (シーケンス番号なし) をシードします。
数値の生成
プログラムが実行され、カーネル #srand が暗黙的または明示的に呼び出されると、カーネル #rand メソッドを呼び出すことができます。このメソッドはパラメータなしで呼び出され、0 から 1 までの乱数を返します。以前は、この数値は通常、生成したい最大の数値に合わせて調整され、おそらく to_i 呼び出しを使用して整数に変換されていました。
# Generate an integer from 0 to 10 puts (rand() * 10).to_i
ただし、Ruby 1.9.x を使用すると、作業がより簡単になります。 Kernel#rand メソッドは 1 つのパラメータを受け入れることができます。この引数が任意の型の数値である場合、Ruby は 0 から (排他的に) その数値までの整数を生成します。
# Generate a number from 0 to 10 # In a more readable way puts rand(10)
しかし、10 から 15 までの数値を生成したい場合はどうすればよいでしょうか? 通常は、0 から 5 までの数値を生成し、それを 10 に加算します。ただし、Ruby を使用するとそれが簡単になります。
Range オブジェクトを Kernel#rand に渡すと、期待どおりの動作が行われ、範囲内のランダムな整数が生成されます。
これら 2 つのタイプの範囲に必ず注意してください。 rand(10..15) を呼び出すと、10 から 15 までの数値が生成されます。そして、 rand(10...15) (3 点) は、15 を除いた 10 から 15 までの数値を生成します。
# Generate a number from 10 to 15 # Including 15 puts rand(10..15)
非ランダムな乱数
ランダムに見える数値のシーケンスが必要な場合がありますが、毎回同じシーケンスを生成する必要があります。たとえば、単体テストで乱数を生成する場合は、毎回同じ一連の数値を生成する必要があります。
あるシーケンスで失敗した単体テストは、次回の実行時にも失敗するはずです。あるいは、次回に別のシーケンスが生成されても失敗しない可能性があります。これを行うには、既知の定数値を使用してカーネル #srand を呼び出します。
# Generate the same sequence of numbers every time # the program is run srand(5) # Generate 10 random numbers puts (0..10).map{rand(0..10)}
カーネルの #rand 実装は Ruby ではないことに注意してください。 PRNG をいかなる方法でも抽象化せず、PRNG のインスタンス化も許可しません。 PRNG の場合、すべてのコードがグローバル状態を共有します。シードを変更するか、PRNG の状態を変更すると、その影響は予想より広範囲に及ぶ可能性があります。
ただし、プログラムはこのメソッドの結果がランダムであることを期待しているため (それが目的です)、これが問題になることはありません。定数値を指定して srand を呼び出す場合など、プログラムが予期した数値シーケンスを期待する場合にのみ、予期しない結果が発生します。
以上がRuby が乱数を生成する仕組みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。