2008-10-13 8 views

Antwort

856

Was ist los mit rand(range)?

Von Ruby Random Numbers:

Wenn Sie eine Zufallszahl benötigt eine Rolle eines sechsseitigen Würfel zu simulieren, dann würden Sie verwenden: 1 + rand(6). Ein Wurf in Craps könnte mit 2 + rand(6) + rand(6) simuliert werden. Wenn Sie nur einen zufälligen Float benötigen, rufen Sie einfach rand ohne Argumente an.


Wie Marc-André Lafortune erwähnt in his answer below (go upvote it), Ruby 1.9.2 has its own Random class (das Marc-André selbst helped to debug, daher die 1.9.2 target für diese Funktion).

Zum Beispiel in diesem game where you need to guess 10 numbers, können Sie sie mit initialisieren:

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

Hinweis:

Aus diesem Grund ist das Äquivalent von Random.new.rand(20..30)20 + Random.rand(11) sein würde, da Random.rand(int) returns „eine zufällige ganze Zahl größer oder gleich Null und weniger als das Argument.“ 20..30 30, ich brauche zu kommen mit eine zufällige Zahl zwischen 0 und 11, ausgenommen 11.

+2

Ist das nicht schrecklich nicht-Rubin-ähnlich? Ich dachte, alles ist ein Objekt, wenig Überraschung und das ... –

+1

@yar: Es ist ein bisschen "perlish". Jetzt hat Ruby seine Random-Klasse (siehe meine Antwort) –

+3

@VonC: Es ist großartig, dass du deine Antwort editiert hast, um die neue 'Random' Klasse zu erwähnen, aber es ist eine schreckliche Idee,' Random.new' wie in deinem Beispiel zu nennen. Ich habe meine Antwort bearbeitet, um das zu sagen. –

19

Nun, ich habe es herausgefunden. Offenbar gibt es eine eingebaute Funktion namens rand (?):

rand(n + 1) 

Wenn jemand mit einer detaillierteren Antwort beantwortet, ich das als die richtige Antwort markieren werden.

+2

Ja, es ist im Kernel-Modul eingebaut. –

+0

Ahh, danke Chrisoph. –

0

Vergessen Sie nicht, den RNG mit srand() zuerst zu säen.

+2

Was passiert, wenn Sie nicht srand() aufrufen? –

+20

srand wird automatisch mit dem Seed aufgerufen von der gegenwärtigen Zeit zu sein, wenn es nicht bereits genannt wurde –

555

Während Sie rand(42-10) + 10 zu bekommen eine Zufallszahl zwischen 10 und 42 (wo einschließlich 10 ist und 42 exklusiv), gibt es eine bessere Art und Weise, da Ruby 1.9 verwenden können.3, wo Sie in der Lage zu nennen sind:

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

verfügbar für alle Versionen von Ruby von meinem backports gem erfordern.

Rubin 1.9.2 führte auch die Random Klasse, so dass Sie Ihre eigenen Zufallszahlengenerator Objekte erstellen und hat eine schöne API:

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

Die Random Klasse selbst fungiert als Zufallsgenerator, so dass Sie direkt anrufen :

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

Hinweise zu Random.new

In den meisten Fällen ist es am einfachsten, rand oder Random.rand zu verwenden. Erstellen Sie einen neuen Zufallsgenerator jedes Mal, wenn Sie eine Zufallszahl möchten, ist eine wirklich schlechte Idee. Wenn Sie dies tun, erhalten Sie die zufälligen Eigenschaften des ursprünglichen Seeding-Algorithmus, die im Vergleich zu den Eigenschaften der random generator itself grausam sind.

Wenn Sie Random.new verwenden, sollten Sie so nennen es so selten wie möglich, zum Beispiel einmal als MyApp::Random = Random.new und es überall benutzen.

Die Fälle, in denen Random.new hilfreich ist, sind folgende:

  • Sie ein Juwel schreiben und wollen nicht mit der Sequenz von rand/Random.rand, die die wichtigsten Programme auf
  • könnte unter Berufung einzumischen Sie möchten separate reproduzierbare Folgen von Zufallszahlen (z. B. eine pro Thread)
  • möchten Sie in der Lage sein, eine reproduzierbare Folge von Zufallszahlen zu speichern und wieder aufzunehmen (einfach wie Random Objekte gemarshallt werden können)
+1

Ausgezeichnet! +1. Ich habe meine eigene Antwort abgeschlossen, um dieses neue fe zu reflektieren (und erwähnt Ihren Beitrag mit Bug # 3104;)). – VonC

+0

Wie funktioniert das "backports" Juwel in großen Zügen? –

+1

@yar: Mein 'Backports'-Juwel ist einfach eine Sammlung von Methoden, die neu in RUby 1.8.7, 1.9.1, 1.9.2 sind, aber in Ruby implementiert sind. Ich verwende RubySpec, um sicherzustellen, dass die Ergebnisse mit Ruby kompatibel sind. –

18

Was ist damit?

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

Es sollte angemerkt werden, dass die Generierung einer Reihe von Zahlen wie diese Lösung hat eine schreckliche Leistung in großen Bereichen, wie es ist O (n), während "Rand" ist O (1). – Travis

42

Wenn Sie sich nicht nur für eine Reihe suchen, sondern auch hex oder uuid es wert ist zu erwähnen, dass das SecureRandom Modul seinen Weg von ActiveSupport zum Rubin Kern in 1.9.2+ gefunden. Also ohne die Notwendigkeit für einen ausgewachsenen Rahmen:

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" 

Es dokumentiert ist: Ruby 1.9.3 - Module: SecureRandom (lib/securerandom.rb)

+0

Was ist, wenn Sie 4 Ziffern Zufallszahl benötigen? – onurozgurozkan

+1

onurozgurozkan Ich nehme an 'SecureRandom.random_number (1000..9999)' – JayTarka

+1

'SecureRandom.random_number()' nimmt keinen Bereich, also nein. Sie möchten wahrscheinlich etwas wie 'SecureRandom.random_number (10_000)' (für 0-9999) oder 'SecureRandom.random_number (9_000) + 1_000' (für 1000-9999). – mwp

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

Beachten Sie, dass der Bereich Option in neueren nur verfügbar ist (1.9+ glaube ich) Versionen von Rubin.

+0

Ich glaube, die Range-Option ist nur in 'Ruby 1.9.3 +' verfügbar. Es funktionierte nicht in '1.9.2', als ich es zumindest versuchte. – Batkins

31

Sie können eine Zufallszahl mit der Methode rand generieren.Das Argument für die rand Methode übergeben soll ein integer oder ein range und gibt eine entsprechende Zufallszahl innerhalb des Bereichs:

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 
+3

Es kann auch ein '' Float'' sein. '' rand (1.1..2.7) '' funktioniert. – pisaruk

+0

Ich denke, mit Ihrem 'rand (1..6)' liest klarer als die Top-Antwort 'rand (6) + 1'. – isomorphismes

+0

warum Rand ist keine Methode der Range .... –

3

Dieser Link hilfreich sein wird in Bezug auf diese;

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

Und einige mehr Klarheit unten über die Zufallszahlen in Rubin;

Generieren eine Zahl von 0 bis 10

puts (rand() * 10).to_i 

Generieren eine Zahl von 0 bis 10 In einer lesbaren Weise

puts rand(10) 

Generieren eine Zahl von 10 bis 15 darunter 15

puts rand(10..15) 

Nicht Zufall Zufall Zahlen

Generieren Sie die gleiche Zahlenfolge jedes Mal das Programm ausgeführt wird

srand(5) 

generieren 10 Zufallszahlen

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

Sie können auch folgen Sie diesem Blog für Schritt für Schritt sehr klares Bild über zufällige Nos in Ruby; http://www.sitepoint.com/tour-random-ruby/ –

2

Versuchen array#shuffle Verfahren zur Randomisierung

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

Simplest Antwort auf die Frage:

rand(0..n) 
3

Sie können rand (Bereich)

x = rand(1..5) 
2

es Ihnen vielleicht helfen, tun. Ich benutze dies in meiner app

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

Es funktioniert gut für mich

1

Wie wäre es mit diesem?

num = Random.new 
num.rand(1..n) 
3

range = 10..50

rand (range)

oder

range.to_a.sample

oder

range.to_a.shuffle (dies wird das ganze Array mischen und Sie können eine zufällige Zahl nach dem ersten oder letzten oder aus diesem Array wählen, um zufällige auszuwählen)

5

Sie können einfach random_number verwenden.

Wenn eine positive Ganzzahl als n angegeben wird, gibt random_number eine ganze Zahl zurück: 0 = random_number < n.

Benutzen Sie es wie folgt aus:

any_number = SecureRandom.random_number(100) 

Der Ausgang wird eine beliebige Zahl zwischen 0 und 100.

1

einfache Möglichkeit, Zufallszahl zu erhalten in Ruby ist,

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