Zufallszahlen (Pseudo Random Numbers) mit Bordmitteln erzeugen

Veröffentlicht von Thomas Fahle am (Permalink)

Zufallszahlen erzeugen mit Bordmitteln

Perl stellt die Funktion rand(x), welche eine Zufallszahl zurück liefert, die größer oder gleich 0 und kleiner als x ist, zur Verfügung.

Beispiel: Zufallszahl zwischen 0 und 9,99

#!/usr/bin/perl
use warnings;
use strict;

# Ganzzahlige Zufallszahl zwischen 0 und 9,99
my $zufallszahl = rand(10);
print "Zufallszahl: $zufallszahl\n";

Das Programm erzeugt folgende Ausgabe:

Zufallszahl: 5.26864530825154

Ganzahlige Zufallszahlen erhalten Sie durch Kombination von int() und rand(x). Falls Sie eine Zufallszahl im Bereich 1 bis einschließlich x benötigen, addieren Sie einfach 1 zur Zufallszahl.

Beispiel: Ganzzahlige Zufallszahlen erzeugen

#!/usr/bin/perl
use warnings;
use strict;

# Ganzzahlige Zufallszahl zwischen 0 und 9
my $zufallszahl = int(rand(10));
print "Zufallszahl: $zufallszahl\n";

# Ganzzahlige Zufallszahl zwischen 1 und 10 
$zufallszahl = int(rand(10) +1 );
print "Zufallszahl: $zufallszahl\n";

Das Programm erzeugt folgende Ausgabe:

Zufallszahl: 5
Zufallszahl: 2

Beispiel: Ein Element aus einem Array zufällig auswählen

#!/usr/bin/perl
use warnings;
use strict;

my @Numbers = qw(0 1 2 3 4 5 6 7 8 9);

my $ausgewaehlt;

$ausgewaehlt = int(rand(scalar(@Numbers)));

print "Auswahl: $ausgewaehlt\n";

Das Programm erzeugt folgende Ausgabe:

Auswahl: 2

Beispiel: Ziehen ohne Zurücklegen

Wenn Sie mehrere Elemente zufällig auswählen möchten, bietet sich eine for-Schleife an.

Doppelte Elemente können Sie mit redo in Kombination mit einem Hash entfernen.

Jedes gezogene Element wird in einem Hash getrackt. Falls es bereits gezogen wurde, wird die for Schleife mit redo (Mach's noch einmal) wiederholt. redo erhöht den Schleifenzähler im Gegensatz zu next nicht.

#!/usr/bin/perl
use warnings;
use strict;

# Beispiel Ziehen ohne Zurücklegen (3 aus 16)

my @Numbers = qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);

my $ziehung = '';

my %bereits_gezogen = ();
my $gezogen;


for ( 1 .. 3 ) {
	$gezogen = int(rand(scalar(@Numbers)));
        	print "Auswahl: $gezogen\n"; 

        redo if exists $bereits_gezogen{$gezogen};
        $bereits_gezogen{$gezogen}++;
        $ziehung .= $gezogen;	
}

print "Ziehung: $ziehung\n";

Das Programm erzeugt folgende Ausgabe:

Auswahl: 8
Auswahl: 3
Auswahl: 8
Auswahl: 7
Ziehung: 837

Zufallszahlengenerator initialisieren mit srand()

srand() initialisiert den Zufallszahlengenerator, der von rand() verwendet wird. Diese zufällige Initialisierung dient der Erzeugung verschiedener Zufallszahlen bei jedem Aufruf Ihres Programms.

Oder andersherum betrachtet, wenn stets das selbe Seed verwendet wird, werden auch immer die selben Zufallszahlen erzeugt, d.h. wenn jemand das Seed kennt oder erraten kann, kann er auch die nachfolgenden Zufallszahlen erraten.

Zur Verdeutlichung ein einfaches Beispiel:

#!/usr/bin/perl
use warnings;
use strict;

# Sechs Seeds erstellen
my @seeds = (15 .. 20);

# Dreimal "Zufallszahlen" erzeugen
for ( 1 .. 3 ) {
     &generate_pin($_);
     print "\n";
}
exit(0);
###############################################################################
sub generate_pin {
	my $n = shift;
	my $counter = 0;
        my @Numbers = qw(0 1 2 3 4 5 6 7 8 9);
	foreach my $seed (@seeds) {
		############
		srand $seed;
		############
		++$counter;
		my $pin = '';
		my $x;
		for (1 .. 5) {
			$x = int(rand(scalar(@Numbers)));
			$pin .= $Numbers[$x];
		}
		print "PIN Nr: $counter in Runde $n: $pin\n";
	}
}
###############################################################################

Ausgabe.

PIN Nr: 1 in Runde 1: 23184
PIN Nr: 2 in Runde 1: 10933
PIN Nr: 3 in Runde 1: 97673
PIN Nr: 4 in Runde 1: 84323
PIN Nr: 5 in Runde 1: 71173
PIN Nr: 6 in Runde 1: 58813

PIN Nr: 1 in Runde 2: 23184
PIN Nr: 2 in Runde 2: 10933
PIN Nr: 3 in Runde 2: 97673
PIN Nr: 4 in Runde 2: 84323
PIN Nr: 5 in Runde 2: 71173
PIN Nr: 6 in Runde 2: 58813

PIN Nr: 1 in Runde 3: 23184
PIN Nr: 2 in Runde 3: 10933
PIN Nr: 3 in Runde 3: 97673
PIN Nr: 4 in Runde 3: 84323
PIN Nr: 5 in Runde 3: 71173
PIN Nr: 6 in Runde 3: 58813

Es werden jedesmal die selben (!) Zufallszahlen erzeugt.

Rufen Sie niemals srand() auf, wenn Sie nicht genau wissen, was Sie tun.

Perl ruft srand() automatisch für Sie mit einem geeignetem Seed auf, sobald rand() verwendet wird.

Siehe auch

Weitere Posts