Hoe willekeurige getallen in Ruby te genereren

Hoewel geen enkele computer echt willekeurige getallen kan genereren, biedt Ruby wel toegang tot een methode die terugkeert pseudorandom cijfers.

Geen enkele computer kan echt genereren willekeurige nummers puur door berekening. Het beste wat ze kunnen doen is genereren pseudorandom getallen, die een reeks getallen zijn die verschijnen willekeurig maar niet.

Voor een menselijke waarnemer zijn deze getallen inderdaad willekeurig. Er zullen geen korte herhalende sequenties zijn, en althans voor de menselijke waarnemer zullen ze geen duidelijk patroon vertonen. Echter, gegeven voldoende tijd en motivatie, het origineel zaad kan worden ontdekt, de reeks opnieuw worden gemaakt en het volgende nummer in de reeks geraden.

Om deze reden mogen de in dit artikel besproken methoden waarschijnlijk niet worden gebruikt om getallen te genereren die cryptografisch veilig moeten zijn.

Pseudorandom-nummergeneratoren moeten zijn gezaaid om reeksen te produceren die telkens verschillen wanneer een nieuw willekeurig getal wordt gegenereerd. Geen enkele methode is magisch - deze schijnbaar willekeurige getallen worden gegenereerd met behulp van relatief eenvoudige algoritmen en relatief eenvoudige rekenkunde. Door de PRNG te plaatsen, begint u deze elke keer op een ander punt. Als je het niet zou uitzetten, zou het elke keer dezelfde reeks getallen genereren.

instagram viewer

In Ruby, de Kernel # srand methode kan zonder argumenten worden aangeroepen. Het zal een willekeurig nummer kiezen op basis van de tijd, de proces-ID en een volgnummer. Gewoon door te bellen schande ergens aan het begin van uw programma, genereert het elke keer dat u het uitvoert een andere reeks schijnbaar willekeurige getallen. Deze methode wordt impliciet aangeroepen wanneer het programma opstart en stuurt de PRNG met de tijd en proces-ID (geen volgnummer).

Zodra het programma wordt uitgevoerd en Kernel # srand werd impliciet of expliciet genoemd, de Kernel # rand methode kan worden opgeroepen. Deze methode, zonder argumenten genoemd, retourneert een willekeurig getal van 0 tot 1. In het verleden werd dit aantal meestal geschaald naar het maximale aantal dat u zou willen genereren en misschien to_i opgeroepen om het te converteren naar een geheel getal.

Ruby maakt het echter een beetje eenvoudiger als u Ruby 1.9.x gebruikt. De Kernel # rand methode kan een enkel argument bevatten. Als dit argument een is Numeriek van welke aard dan ook, Ruby genereert een geheel getal van 0 tot (en niet inclusief) dat aantal.

Wat als u echter een nummer van 10 tot 15 wilt genereren? Normaal gesproken genereert u een nummer van 0 tot 5 en voegt u dit toe aan 10. Ruby maakt het echter gemakkelijker.

Let op de twee soorten bereiken. Als je belde rand (10..15), dat zou een getal van 10 tot 15 genereren inclusief 15. Terwijl rand (10... 15) (met 3 punten) zou een getal van 10 tot 15 genereren Niet inclusief 15.

Soms heb je een willekeurig uitziende reeks getallen nodig, maar moet je elke keer dezelfde reeks genereren. Als u bijvoorbeeld willekeurige getallen in een eenheidstest genereert, moet u elke keer dezelfde reeks getallen genereren.

Een eenheidstest die in één reeks mislukt, zou de volgende keer dat hij wordt uitgevoerd opnieuw moeten mislukken. Als hij de volgende keer een andere reeks genereerde, zou hij niet kunnen mislukken. Bel daarvoor Kernel # srand met een bekende en constante waarde.

De implementatie van Kernel # rand is nogal on-Ruby. Het abstraheert de PRNG op geen enkele manier, noch staat het u toe de PRNG te instantiëren. Er is een algemene staat voor de PRNG die alle code deelt. Als u de seed wijzigt of op een andere manier de status van de PRNG wijzigt, heeft dit mogelijk een groter bereik dan u had verwacht.

Omdat programma's echter verwachten dat het resultaat van deze methode willekeurig is - dat is het doel! - dit zal waarschijnlijk nooit een probleem zijn. Alleen als het programma een verwachte reeks nummers verwacht, zoals wanneer het had gebeld schande met een constante waarde, mocht het onverwachte resultaten zien.