Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyでの乱数の生成

乱数は、ゲーム、暗号化、建物のシミュレーションなど、さまざまな目的に役立ちます。技術的には、コンピューターは純粋に計算によって乱数を生成することはできません。決定論的なデバイスで真に乱数を生成することは基本的に不可能です。期待できる最善の方法は、疑似乱数です。これは、ランダムに生成されたかのように見える一連の数値です。

この記事では、Rubyで乱数を生成するさまざまな方法を見ていきます。

Kernel#randを使用した乱数の生成

まず、randを使用して乱数を生成しましょう。 方法。メソッドが引数なしで呼び出されると、0.0以上1.0未満のfloatが返されます。

rand()
> 0.7308136972953823

整数を取得するには、関数に整数を渡します。関数は、0以上で、関数に渡された整数よりも小さいランダムな整数値を返します。以下を実行するたびに、0から7までの数値が得られます。

rand(8)
> 5

特定の範囲内の乱数の場合、範囲をrandに渡します 。

以下は包括的を使用しています 下限(1)から乱数を生成する範囲 )、上限(10まで) 。

rand(1..10)
> 6

次の例では、非包括的を使用しています 下限から上限まで(ただし上限を含まない)の乱数を生成する範囲。

rand(1...10)
> 9

範囲は浮動小数点値の間にある場合もあります。

rand(1.5..3.0)
> 1.7494305393711571

randで負の範囲制限を使用することもできます 。

rand(-5..-1)
> -5

以下に示すように、単一の負の数を渡すと、驚くべき結果が得られる場合があります。

rand(-100)
> 94
 
rand(-0.5)
> 0.7692627344737486

これは、引数がnであるためです。 randに渡されます 、rand 0からn.to_i.absまでの乱数を返します(ただし、これは含まれません)。 。上記の例の場合、(-100).to_i.abs 100です および(-0.5).to_i.abs 0です 、したがって、結果の乱数。

rand(0)を呼び出す rand()の呼び出しに似ています 。 0.0から1.0までの乱数を取得します(包括的ではありません)。

Kernel#srandを使用した再現可能なシーケンスの生成

乱数を生成する次の方法に進む前に、まずsrandを見てみましょう。 機能。

Kernel#srand Kernel#randのシードを設定します 。これを使用して、プログラムの異なる実行間で乱数の繰り返し可能なシーケンスを生成できます。

これが何を意味するのかを理解するには、まず乱数がどのように生成されるかを理解する必要があります。

シードからの「乱数」の生成

先に述べたように、コンピューターは純粋に計算から真の乱数を生成するわけではありません。彼らがしていることは、ランダムに見える数列を生成することです。これを行うために、コンピューターはシード番号から開始し、それを何らかのアルゴリズムで実行してから、一見ランダムな出力を吐き出します。

シード番号は、さまざまな要素の組み合わせを使用してコンピューターによって生成されます。タイムスタンプ、プログラムのプロセスID、e.t.c。これらの要素は、乱数を生成する要求ごとに異なるため、シード番号は常に異なり、異なるシーケンスの番号が生成され、結果として乱数が出力されます。同じシードでアルゴリズムを実行した場合、毎回同じ数列が得られます。これがKernel#srandです できるようになります。

srand 通常、テストで使用されます。ランダムであるがテストするのに十分予測可能な値を使用して、ランダム性を処理するアプリのコードをテストする場合に便利です。また、バグの特定や再現にも役立つ可能性があります。

以下では、srandを使用します シードを設定してからrandを呼び出します 最初にいくつかの個別の乱数を生成し、次にいくつかの乱数シーケンスを生成します。

srand(777)
 
rand()
> 0.152663734901322
 
rand()
> 0.3023566097075212
 
10.times.map { rand(10) }
> [7, 1, 7, 4, 7, 9, 8, 7, 2, 0]
 
10.times.map { rand(10) }
> [1, 2, 4, 5, 7, 1, 7, 2, 2, 7]

srandを実行する場合 再び同じシードを使用して、以前に行ったのと同じ呼び出しを行うと、同じ乱数が得られることがわかります。

srand(777)
 
rand()
> 0.152663734901322
 
rand()
> 0.3023566097075212
 
10.times.map { rand(10) }
> [7, 1, 7, 4, 7, 9, 8, 7, 2, 0]
 
10.times.map { rand(10) }
> [1, 2, 4, 5, 7, 1, 7, 2, 2, 7]

ランダムを使用した乱数の生成

Randomクラスを使用して乱数を生成することもできます。

クラスメソッドrand Kernel#randの基本機能を提供します 浮動小数点値のより良い処理とともに。

Random.rand(1...10)
> 5

Kernel#randとは異なり 、Random.randの場合 負または0が与えられます 引数の場合、ArgumentErrorが発生します。

正規分布に基づく乱数の生成

現実の世界では、多くのものが正規分布に従う傾向があります。何かが該当する値の範囲がある場合、すべての値が均等に分布することはめったにありません。ほとんどの場合、データの大部分は狭い範囲に含まれる傾向があり、小さい割合は広い範囲に含まれます。例として成人男性の身長を取り上げましょう。記録された最短の身長は54.6cm(21.5インチ)で、最高の身長は267 cm(8'9 ")です。人口の男性の身長をシミュレートするデータを生成する場合は、rand これらの制限があります。後者の方が一般的であるため、8'9"の男性を取得する確率が6'の男性を取得する確率と同じになることは望ましくありません。

正規分布に従う他の例は次のとおりです。

  • 測定のエラー
  • 血圧
  • テストスコア
  • 成人男性/女性の体重

このようなユースケースでより適切な乱数を生成するには、rubystatsを使用できます。 宝石。

$ gem install rubystats
require 'rubystats'
 
adult_male_height = Rubystats::NormalDistribution.new(178, 10)
sample = 50.times.map { adult_male_height.rng.round(1) }
 
> [183.2, 169.5, 189.7, 171.9, 176.0, 179.3, 189.3, 175.3, 188.3, 190.0, 185.5, 182.8, 187.2, 191.6, 185.4, 178.4, 187.1, 183.3, 189.6, 179.7, 172.7, 174.4, 153.8, 197.4, 176.0, 174.6, 181.1, 182.0, 204.7, 185.2, 175.9, 167.7, 160.6, 170.5, 169.3, 160.6, 165.6, 166.4, 182.6, 179.7, 183.1, 171.9, 185.4, 175.4, 179.7, 176.9, 160.6, 173.8, 181.9, 190.2]

上記では、男性の平均身長(178cm)と標準偏差10cmをNormalDistribution.newに渡します。 、この正規分布に該当する50個の値を生成する前。数学に興味がある場合は、この記事に興味があるかもしれません。

ランダムラウンドアップ

これで、この議論は終わりです。 randを使用して、Rubyで「乱数」を作成するいくつかの異なる方法について説明しました。 、srandRandom およびRubystats 。また、「乱数」がどのように作成されるかについて簡単に触れ、決定論的デバイスが実際の乱数を作成できない理由を調べました。

対象となる方法は、ランダム性を必要とするすべてのユースケースに理想的ではないことに注意してください。メソッドによって生成される整数または浮動小数点数は、ゲームのチャンスを生み出すため、またはシミュレーションを作成するために理想的かもしれませんが、パスワードリセットトークンを生成する場合など、セキュリティが必要な状況では、SecureRandomの使用を検討する必要があります。 SecureRandomを使用 、16進数、base64、2進数、およびUUID文字列を生成できます。これらの文字列は、単純な数値に比べて解読がはるかに困難です。

このいくつかがおもしろいと思ったことを願っています。私たちがカバーした内容についてコメントや質問がある場合は、@AppSignalまでご連絡ください。取り上げたいトピックのリクエストを送信することもできます。

2018年8月1日にこの記事を更新して、SecureRandomに関するメモを追加しました


  1. PHPを使用したランダム文字列の生成

    PHPを使用してランダムな文字列を生成するためのコードは、次のとおりです- 例 <?php    $res = substr(md5(mt_rand()), 0,5);    echo "Displaying random string...\n";    echo $res; ?> 出力 これにより、次の出力が生成されます- Displaying random string... 1c856 例 別の例を見てみましょう- <?php    $res = substr(md

  2. Pythonの乱数

    説明 Pythonには、乱数を生成するための関数がほとんどありません。これらは、生成するために乱数が必要な多くのゲームや宝くじなどで使用できます。 乱数を生成する関数がいくつかあります- choice() この関数を使用して、数値のコレクションから1つの乱数を生成できます。 例 print (A random number from list : ,end=) print (random.choice([1, 4, 6, 100, 31])) 出力 A random number from list : 100 randrange(beg、end、step) この関数は