Hoe random is Random?

PDF version

Random, het Engelse woord voor willekeurig. Maar hoe random is random nu eigenlijk? Als je honderd mensen vraagt een getal onder de 10 te kiezen, komt dan ieder getal even vaak voor? Ik moet je helaas het antwoord verschuldigd blijven, maar het is wel een leuk psychologisch spelletje. Sommige getallen zijn nu eenmaal populairder dan andere getallen, zoals 3.
Bij computers zouden voorkeuren geen rol moeten spelen. Computers kunnen namelijk (nog) niet zelf denken. Alles wat ze doen wordt gevraagd door hun gebruiker. Die gebruiker kan een mens zijn, maar ook software of andere hardware, zoals we vaak zien in de meet- en regeltechniek. Een computer kan hierdoor ook nooit een random getal selecteren. Een onwetende programmeur zal nu direct van z’n stoel springen, maar het is echt waar.

Random bestaat niet

Wanneer een computer om een random getal wordt gevraagd, levert dat een probleem op. Zoals gezegd, kan een computer niet uit zichzelf iets doen en dus geen willekeurig nummer selecteren. Om toch random nummers te kunnen gebruiken, hebben bijna alle programmeertalen een trucje ingebouwd. In de random-functie, worden getallen gegenereerd op basis van hun voorganger.

Eigen random functie

Een vrij eenvoudig voorbeeld van een random functie is:

int last = 1;
function random ( int max ) {
last = last * 7 % max;
return last;
}

In dit voorbeeld wordt het laatst gegenereerde getal steeds met 7 vermenigvuldigd. Om te zorgen dat het getal niet hoger is dan de aangegeven max, wordt er een modulus op los gelaten. Met modulus haal je een getal zo vaak mogelijk van een ander getal af en geef je vervolgens de restwaarde. 100 % 33 = 1, want 100 – 33 – 33 – 33 = 1.
Bij dit voorbeeld lopen we tegen twee problemen aan.
1. We beginnen met 1, dus de gegenereerde random lijst, is niet random, maar zal iedere keer na het opstarten een zelfde reeks geven. Visual Basic had hier altijd last van. De makkelijkste oplossing was om niet te beginnen met 1, maar met een timestamp. Die is namelijk altijd anders.
2. Wanneer we een max van 100000 nemen, zullen we altijd een stijgende lijn zien in de reeks nummers. We beginnen bijvoorbeeld met:
1 7 49 343 2401 16807
Het getal daarna wordt 117649, maar dat zou de max overschreiden, dus wordt het:
17649 23543 64801 53607 75249 26743 87201 10407
er is duidelijk een patroon te herkennen en voor een Hoger-Lager-spelletje is zoiets natuurlijk funest. Om dit probleem op te lossen, zouden we een veel groter priemgetal moeten gebruiken dan 7.

Random in Java

Om random getallen te genereren in Java, kun je gebruik maken van java.util.Random. Deze klasse, kun je random getallen laten genereren met nextInt(max). Om te bewijzen dat de gekozen nummers echt random zijn en bovendien gelijk verdeeld, heb ik een paar testjes gedaan.

Test 1: 50-50

import java.util.Random;
 
public class HogerLager {
	public static void main ( String[] args ) {
		System.out.println ( "+--------------------------------------------+" );
		System.out.println ( "+ Zijn random getallen gelijk verdeeld?      +" );
		System.out.println ( "+--------------------------------------------+" );
 
		int above = 0;
		int beneath = 0;
		double n = 100000.0;
		Random r = new Random ( );
		for ( int i = 0; i < n; i++) {
			int x = r.nextInt ( 10 ) + 1;
			if ( x > 5 )
				above++;
			else
				beneath++;
		}
		System.out.println ( "Van de " + (int)n + " random getallen (1 t/m 10), was" );
		System.out.println ( "- " + ((above/n)*100) + "% 6 of hoger" );
		System.out.println ( "- " + ((beneath/n)*100) + "% 5 of lager" );
	}
}

Ik heb de percentages bewust niet afgerond, omdat ik geïnteresseerd ben in het meest precieze data. Wanneer ik het programma draai, krijg ik de volgende uitkomst:

+--------------------------------------------+
+ Zijn random getallen gelijk verdeeld? +
+--------------------------------------------+
Van de 100000 random getallen (1 t/m 10), was
- 49.695% 6 of hoger
- 50.305% 5 of lager

Er is dus een lichte voorkeur voor de onderste helft van de mogelijke getallen. Hoe hoger de n (aantal tests), hoe dichter de percentages tegen de 50 aan zullen liggen. Bij een n van 10000000, zien we pas verschil bij het derde getal achter de komma. Daarom kunnen we zeggen dat de verdeling tussen hoge en lage getallen gelijk is wanneer we veel testen.

Test 2: Gemiddelde

Om een goed beeld te krijgen hoe precies de verdeling is, heb ik een test onwikkeld, dat het gemiddelde van de gekozen nummers kan bepalen.

import java.util.Random;
import java.math.BigInteger;
 
public class HogerLager {
	public static void main ( String[] args ) {
		System.out.println ( "+--------------------------------------------+" );
		System.out.println ( "+ Zijn random getallen gelijk verdeeld?      +" );
		System.out.println ( "+--------------------------------------------+" );
		System.out.println ( );
		System.out.println ( "+--------------+" );
 
		double z = 0.0;
		int n = 100;
		int n2 = 10000000;
 
		for ( int j = 0; j < n; j++ ) {
			System.out.print ( (j+1) + " ");
			if ( j < 9 )
				System.out.print ( " " );
			if ( j < 99 )
				System.out.print ( " " );
			int total = 0;
			Random r = new Random ( );
			for ( int i = 0; i < n2; i++) {
				int x = r.nextInt ( 10 ) + 1;
				total += x;
				if ( i % ( n2 / 10 ) == 0 )
					System.out.print ( "*");
			}
			System.out.println ( " |" );
			z += total / (double)n2;
		}
		System.out.println ( "+--------------+" );
		System.out.println ( "Gemiddelde: " + (z/(double)n) );
	}
}

En het resultaat:

Gemiddelde: 5.499953607999998
Test 3: Getalverdeling

En dan nu de laatste test. Ik ga de computer vragen om een getal onder de 10 en kijk of de verdeling over de getallen van 1 t/m 10 gelijk is.

import java.util.Random;
 
public class GetalVerdeling {
	public static void main ( String[] args ) {
		int x[] = new int[10];
		Random r = new Random ( );
		int n = 100000000;
 
		for ( int i = 0; i < n; i++ ) {
			int y = r.nextInt ( 10 );
			x[y]++;
		}
 
		for ( int i = 0; i < 10; i++) {
			System.out.println ( (i+1) + ": " + ( x[i] / (double) n ) * 100 + "%" );
		}
	}
}

En natuurlijk het resultaat:

1: 9.996597999999999%
2: 10.00047%
3: 9.998962%
4: 10.000429%
5: 10.000429%
6: 10.000235%
7: 10.000811%
8: 10.000245000000001%
9: 10.003157999999999%
10: 9.998663%

Na 100 miljoen getallen is de verdeling nog steeds niet gelijk. Opvallend is, dat 1 en 10 de laagste scores hebben gehaald. Dit berust echter op toeval, want de vier tests die ik daarna heb uitgevoerd, vertoonden dit niet.

Conclusie

Computers kunnen niet denken, maar zijn wel waanzinnig goed in het genereren van random getallen. Hoe meer tests je uitvoert, hoe preciezer het resultaat wordt. Uit de laatste test kunnen we concluderen dat alle getallen even vaak voorkomen. Wanneer je een RaadHetGetal-spelletje speelt en alleen 8 is nog niet geweest, dan is de kans groot dat dit de volgende zal zijn.
De random-functie in Java is goed te gebruiken voor een party-mode in een mp3-speler. Deze zal at random mp3'tjes selecteren en op de langere termijn zal ieder nummer gespeeld worden, zonder dat er een patroon te vinden is. Wel zal de MP3-speler altijd een voorkeur hebben voor een bepaald nummer. Uit alle tests bleek, dat pas na een miljoen getallen, het verschil te verwaarlozen is. Doe je Test 3 met n=10, dan zul je merken dat sommige nummers helemaal niet zijn voorgekomen en andere wel 3 keer. Toch is het algoritme erop gebaseerd om het gelijk op te laten gaan. Zeker voor bijvoorbeeld kaartenschudmachines kan dit een risico vormen. Maar bij handmatig schudden loop je weer tegen andere problemen aan, zoals clusters van kaarten.
Echt random bestaat dus niet bij computers, maar het is al een stuk beter dan wat mensen presteren.

148 Comments

RickyJanuary 19th, 2015 at 01:35

.

ñïñ….

williamJanuary 20th, 2015 at 06:14

.

ñïñ!…

JavierJanuary 20th, 2015 at 11:31

.

thanks for information….

walterJanuary 20th, 2015 at 16:29

.

ñïñ!!…

FernandoJanuary 21st, 2015 at 08:25

.

thank you….

BrettJanuary 21st, 2015 at 08:58

.

good info….

jasonJanuary 21st, 2015 at 09:31

.

ñïñ çà èíôó….

JoseJanuary 23rd, 2015 at 02:06

.

tnx for info!!…

jamieJanuary 23rd, 2015 at 16:57

.

ñïñ!…

manuelJanuary 23rd, 2015 at 17:32

.

tnx for info!…

felixJanuary 23rd, 2015 at 18:04

.

ñïàñèáî….

DonaldJanuary 23rd, 2015 at 18:38

.

thanks….

reginaldJanuary 23rd, 2015 at 19:11

.

good….

walterJanuary 23rd, 2015 at 19:45

.

tnx for info….

EverettJanuary 23rd, 2015 at 21:27

.

ñïñ!…

RalphJanuary 23rd, 2015 at 23:52

.

good!!…

AdamJanuary 24th, 2015 at 04:47

.

ñýíêñ çà èíôó….

MathewJanuary 24th, 2015 at 05:20

.

tnx for info!!…

cameronJanuary 24th, 2015 at 07:11

.

tnx for info….

DuaneJanuary 25th, 2015 at 15:10

.

tnx for info!…

SalvadorJanuary 26th, 2015 at 00:36

.

tnx for info!!…

PaulJanuary 26th, 2015 at 01:08

.

ñïàñèáî!…

normanJanuary 27th, 2015 at 05:37

.

tnx!!…

willardJanuary 30th, 2015 at 03:10

.

hello!!…

michaelJanuary 30th, 2015 at 10:08

.

ñïñ çà èíôó!…

floydJanuary 30th, 2015 at 10:40

.

áëàãîäàðñòâóþ….

EdwardJanuary 31st, 2015 at 09:14

.

ñýíêñ çà èíôó….

michealJanuary 31st, 2015 at 21:52

.

ñïñ çà èíôó….

ChesterJanuary 31st, 2015 at 22:24

.

good info!!…

harryFebruary 2nd, 2015 at 06:17

.

ñïñ!!…

LynnFebruary 4th, 2015 at 02:56

.

ñïàñèáî!…

LynnFebruary 6th, 2015 at 12:19

.

ñïñ!!…

JohnnieFebruary 6th, 2015 at 14:21

.

good!!…

alfonsoFebruary 7th, 2015 at 01:52

.

tnx for info!…

hectorFebruary 7th, 2015 at 09:24

.

ñýíêñ çà èíôó….

RexFebruary 7th, 2015 at 09:56

.

ñïñ çà èíôó!!…

andreFebruary 7th, 2015 at 10:13

.

ñïàñèáî çà èíôó….

charlieFebruary 8th, 2015 at 09:23

.

ñïñ!…

wallaceFebruary 9th, 2015 at 06:40

.

tnx for info….

BradleyFebruary 9th, 2015 at 08:03

.

ñïñ çà èíôó….

RodneyFebruary 10th, 2015 at 20:01

.

ñïñ!…

jeffreyFebruary 10th, 2015 at 20:40

.

ñýíêñ çà èíôó!!…

AngeloFebruary 10th, 2015 at 21:19

.

ñïñ….

OscarFebruary 11th, 2015 at 01:01

.

tnx!…

MarioFebruary 12th, 2015 at 06:28

.

thanks….

GaryFebruary 13th, 2015 at 08:57

.

ñýíêñ çà èíôó….

hughFebruary 14th, 2015 at 11:55

.

thank you….

miltonFebruary 14th, 2015 at 14:25

.

ñïñ….

Leave a comment

Your comment