Rubyで乱数を取得する方法


786

0との間で乱数を生成するにはどうすればよいnですか?


コードを記述するsrand <some_number>前に使用するrandと、必要に応じて確定的な(つまり、反復可能な)疑似ランダムシーケンスが得られます。 ruby-doc.org/core-2.5.6/Random.html#method-c-srand
Purplejacket

回答:


952

使用する rand(range)

Rubyの乱数から:

6面ダイスのロールをシミュレートするためにランダムな整数が必要な場合は、次を使用します1 + rand(6)。クラップスのロールはでシミュレートできます2 + rand(6) + rand(6)

最後に、ランダムなフロートが必要な場合randは、引数なしで呼び出します。


マルク=アンドレ・Lafortuneはに言及し(それupvote行く)以下の彼の答えRubyの1.9.2は独自の持っているRandomクラスを(マルク=アンドレ・自身がいることをデバッグするのに役立ったため、1.9.2ターゲットその機能のため)。

たとえば、10個の数字を推測する必要があるこのゲームでは、次のように初期化できます。

10.times.map{ 20 + Random.rand(11) } 
#=> [26, 26, 22, 20, 30, 26, 23, 23, 25, 22]

注意:

「ゼロ以上で引数未満のランダムな整数」を返すRandom.new.rand(20..30)ので20 + Random.rand(11)、がと同等になるのはこのためです。30を含み、11を除く0から11の間の乱数を考え出す必要があります。Random.rand(int)20..30


2
これはひどくルビーのようではないですか?私はすべてがオブジェクトであり、驚くべきことではないと思っていました...
Dan Rosenstark 2010年

1
@yar:少し「完璧」です。今、Rubyは(私の答えを参照)、それのランダムなクラスを持っている
マルク=アンドレ・Lafortune

3
@VonC:回答を編集して新しいRandomクラスについて言及したのは素晴らしいことですRandom.newが、例のように複数回呼び出すのはひどい考えです。私はそれを述べるために私の答えを編集しました。
マルク=アンドレ・Lafortune

2
@VonCああ:)すみません、私が少し厳しいのなら、それは私を驚かせただけです
horseyguy

1
Random.rand 実際に、範囲を受け入れます。(1.9.3以降、私は信じています。)
Ajedi32

591

あなたが使用できる間 rand(42-10) + 10の間の乱数を取得する1042(10包括的で、42排他的な場所)、あなたが呼び出すことができますルビー1.9.3、以来、より良い方法があります:

rand(10...42) # => 13

私のbackportsgemを要求することにより、Rubyのすべてのバージョンで使用できます。

Ruby 1.9.2はまた導入しました Randomクラスをため、独自の乱数ジェネレーターオブジェクトを作成でき、優れたAPIを備えています。

r = Random.new
r.rand(10...42) # => 22
r.bytes(3) # => "rnd"

Randomあなたが直接呼び出すので、クラス自体は、乱数発生器として機能します:

Random.rand(10...42) # => same as rand(10...42)

注意事項 Random.new

ほとんどの場合、最も簡単なのはrandまたはを使用することRandom.randです。乱数が必要になるたびに新しいランダムジェネレーターを作成するのは非常に悪い考えですです。これを行うと、ランダムジェネレーター自体のプロパティと比較してひどい初期シーディングアルゴリズムのランダムプロパティが得られます。

Random.newしたがって、を使用する場合は、できるだけ呼び出さないでください。たとえば、MyApp::Random = Random.new。他のすべての場所で使用する必要があります。

場合 Random.newに便利ですが、以下のとおりです。

  • あなたは宝石を書いていて、そのシーケンスに干渉したくない rand /Random.randて、メインプログラムが依存しているかもしれない
  • 再現可能な乱数のシーケンスを個別にしたい(たとえば、スレッドごとに1つ)
  • 乱数の再現可能なシーケンスを保存して再開できるようにしたい(Randomオブジェクトをマーシャリングできるので簡単)

1
優秀な!+1。私はその新しい機能を反映するために自分自身の回答を完了しました(そして、バグ#3104での貢献について言及しました;))。
VonC、

1
@yar:私のbackportsgemは、単にRUby 1.8.7、1.9.1、1.9.2の新しいメソッドのコレクションですが、Rubyで実装されています。RubySpecを使用して、結果がRubyと互換性があることを確認します。
マルク=アンドレ・Lafortune

@Marc-AndréLafortune、ありがとう。速度要件のため、Rubyのどれだけが非Ruby(Cなど)に実装されているかは常に不思議でした。しかし、それは休憩です
Dan Rosenstark

5
Random.rand(10..42)動作しません。Random.randクラスメソッドは、範囲を受け付けません。(Ruby 1.9.2p180)
horseyguy

1
@banister:うわー、私は新しいapi(範囲、バイトなどを持つランド)がRandomオブジェクトを介して直接利用できると確信していました。範囲付きのrandは1.9.3になり、バイトの機能リクエストを作成します。私は自分の回答を編集しました
マルクアンドレラフォーチュン

46

数字だけでなく16進数やuuidも探しているのであれば、1.9.2以降でSecureRandomモジュールがActiveSupportrubyコアに到達したことを言及しておく価値があります。したがって、本格的なフレームワークは必要ありません。

require 'securerandom'

p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88

p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409

p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"

それはここに文書化されています:Ruby 1.9.3-モジュール:SecureRandom(lib / securerandom.rb)


4桁の乱数が必要な場合はどうなりますか?
onurozgurozkan、2014

1
onurozgurozkan私は推測しますSecureRandom.random_number(1000..9999)
JayTarka

1
SecureRandom.random_number()範囲をとらないので、いいえ。SecureRandom.random_number(10_000)(0から9999の場合)またはSecureRandom.random_number(9_000)+1_000(1000から9999の場合)のようなものが必要になるでしょう。
mwp 2015年

1
Random.rand(1000..9999)
ジェシーファーマー

37

randメソッドで乱数を生成できます。渡される引数rand方法がなければならないinteger、またはrange、その範囲内に対応する乱数を返します。

rand(9)       # this generates a number between 0 to 8
rand(0 .. 9)  # this generates a number between 0 to 9
rand(1 .. 50) # this generates a number between 1 to 50
#rand(m .. n) # m is the start of the number range, n is the end of number range

rand(1..6)トップの回答よりも明確なリードを使用すると思いますrand(6)+1
同型14年

21

さて、私はそれを理解しました。どうやら、randと呼ばれる組み込み(?)関数があります。

rand(n + 1)

誰かがより詳細な答えで答えた場合、私はそれを正しい答えとしてマークします。


2
はい、カーネルモジュールに組み込まれています。
Christoph Schiessl、2008年

17

これはどうですか?

n = 3
(0..n).to_a.sample

3
このソリューションのように数値の配列を生成するrandと、O(1)であるのにO(n)になるため、広い範囲でパフォーマンスが大幅に低下することに注意してください。
Travis


9

単純に使用できますrandom_number

正の整数がnとして指定されている場合、random_number整数を返します:0 <=random_number <n。

次のように使用します。

any_number = SecureRandom.random_number(100) 

出力は0から100までの任意の数値になります。


6
rand(6)    #=> gives a random number between 0 and 6 inclusively 
rand(1..6) #=> gives a random number between 1 and 6 inclusively

rangeオプションはrubyの新しいバージョン(1.9以上)でのみ使用できることに注意してください。


範囲オプションはでのみ使用できると思いますruby 1.9.3+1.9.2少なくとも私が試したときは機能しませんでした。
Batkins

6

範囲= 10..50

rand(範囲)

または

range.to_a.sample

または

range.to_a.shuffle(これは配列全体をシャッフルし、最初または最後の乱数をこの配列からランダムに選択してランダムに選択できます)


range.to_a.sampleサンプルが大きい場合はひどい考えです。
グジェゴルツ


4

このリンクは、これに関して役立つでしょう。

http://ruby-doc.org/core-1.9.3/Random.html

そして、以下のルビの乱数よりもいくつかの明確さ;

0から10までの整数を生成します

puts (rand() * 10).to_i

より読みやすい方法で0から10までの数を生成する

puts rand(10)

15を含む10から15までの数を生成します

puts rand(10..15)

非ランダムな乱数

プログラムが実行されるたびに同じ数列を生成する

srand(5)

10個の乱数を生成する

puts (0..10).map{rand(0..10)}

また、このブログをフォローして、Rubyのランダムなnoを非常に明確に把握できます。sitepoint.com/tour-random-ruby
サム

4

ルビーで乱数を取得する簡単な方法は、

def random    
  (1..10).to_a.sample.to_s
end

2

多分それはあなたを助ける。私はこれを自分のアプリで使用します

https://github.com/rubyworks/facets
class String

  # Create a random String of given length, using given character set
  #
  # Character set is an Array which can contain Ranges, Arrays, Characters
  #
  # Examples
  #
  #     String.random
  #     => "D9DxFIaqR3dr8Ct1AfmFxHxqGsmA4Oz3"
  #
  #     String.random(10)
  #     => "t8BIna341S"
  #
  #     String.random(10, ['a'..'z'])
  #     => "nstpvixfri"
  #
  #     String.random(10, ['0'..'9'] )
  #     => "0982541042"
  #
  #     String.random(10, ['0'..'9','A'..'F'] )
  #     => "3EBF48AD3D"
  #
  #     BASE64_CHAR_SET =  ["A".."Z", "a".."z", "0".."9", '_', '-']
  #     String.random(10, BASE64_CHAR_SET)
  #     => "xM_1t3qcNn"
  #
  #     SPECIAL_CHARS = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "=", "+", "|", "/", "?", ".", ",", ";", ":", "~", "`", "[", "]", "{", "}", "<", ">"]
  #     BASE91_CHAR_SET =  ["A".."Z", "a".."z", "0".."9", SPECIAL_CHARS]
  #     String.random(10, BASE91_CHAR_SET)
  #      => "S(Z]z,J{v;"
  #
  # CREDIT: Tilo Sloboda
  #
  # SEE: https://gist.github.com/tilo/3ee8d94871d30416feba
  #
  # TODO: Move to random.rb in standard library?

  def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"])
    chars = character_set.map{|x| x.is_a?(Range) ? x.to_a : x }.flatten
    Array.new(len){ chars.sample }.join
  end

end

https://github.com/rubyworks/facets/blob/5569b03b4c6fd25897444a266ffe25872284be2b/lib/core/facets/string/random.rb

私にとってはうまくいきます



1

array#shuffleランダム化の方法を試す

array = (1..10).to_a
array.shuffle.first

1
あなたがいる場合必要があります全体の配列を作る、少なくとも置き換える.shuffle.first.sample
Camille Goudeseune

0

最初にsrand()で RNGをシードすることを忘れないでください。


2
srand()を呼び出さないとどうなりますか?
Alex B

21
srandは、まだ呼び出されていなければ、シードは現在の時刻から自動的に呼び出されます。
ジュリアンH
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.