Zufalls zahl (c++)

hallo!

wie kann ich eine zufalls zahl generieren und dann in einer integer variablen abspeichern?

danke für eure hilfe

paul

Moin,

wie kann ich eine zufalls zahl generieren und dann in einer
integer variablen abspeichern?

Auf INT_MAX verschiedene Arten. Wäre schön, wenn wir etwas mehr Details bekämen. Eine Möglichkeit:

srand(time(NULL) + getpid());
int zufall = rand() % INT_MAX;

(Bin jetzt zu faul nachzusehen, ob rand() int oder long ist)

Thorsten

also schonmal danke für deine hilfe…
kannst du mir vielleicht noch sagen welches include file ich dafür brauche und wie ich einen zahlen raum bestimmen kann?

paul

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moin,

srand(time(NULL) + getpid());
int zufall = rand() % INT_MAX;

kannst du mir vielleicht noch sagen welches include file ich
dafür brauche

man rand

wie ich einen zahlen raum bestimmen kann?

Was für’n Ding?

Thorsten

hallo!

include

int rand(void)/*von o bis RAND_MAX(min. 32767)*/

Das ist aber einfach es C

Alternativ zu den implementierten Funktionen srand und rand sei hier noch einer der populärsten (Pseudo)Zufallsalgorithmen gegeben:
Die „Methode der linearen Kongruenz“, die auch zur XOR-verschlüsselung von wichtigen Dokumenten benutzt wird.

In der Klasse Random wird der Zufallsgenerator im Konstruktor mit der Zahl seed initialisiert (am besten mit Sytemzeit)
Die Methode next liefert eine Zufallszahl zwischen 0 und r-1

#include

const long m =100000000L;
const long m1=10000L;

class Random
{
long a;
long mult(long p, long q)
{
long p1,p0, q1, q0;
p1 = p/m1;
p0 = p%m1;
q1 = q/m1;
q0 = q%m1;
return (((p0*q1+p1*q0)%m1)*m1+p0*q0)%m;
}
public:
Random (long seed){ a=seed;}
long next(long r)
{
const long b=31415821L;
a=(mult(a,b)+1)%m;
return ((a/m1)*r)/m1;;
}
};

void main(void)
{
long i, N;
Random x(1234567);
cin >> N;
for (i=1; i

Sehr viel mehr Zufall
Hi Paul :smile:

Die in C/C++ eingebauten Zufallszahlen-Generatoren sind sehr schlecht. Sie erweisen sich bei jeder anspruchsvolleren Anwendung als unbrauchbar. In der Informatik-Literatur sind einige hervorragende Zufallszahlen-Generatoren bekannt, die sich in vielen Versuchen als sehr zufällig erwiesen haben. Sie basieren alle auf dem gleichen Prinzip. Bestehend aus einer Zufallszahl n wird eine neue Zufallszahl nach folgendem Schema berechnet:

n = (a * n + c) % m

wobei % die Modulo-Division ist (wie in C). Die riesige Kunst dabei ist, die Zahlen a, c und m richtig zu wählen. Es ist klar, dass sich alle deine Zufallszahlen wiederholen, sobald die erste Zufallszahl n das zweite Mal auftritt. Deswegen versucht man, a und c so zu wählen, dass dies erst nach so vielen Aufrufen wie möglich passiert, also nach genau m Aufrufen. Daraus folgt schon, dass m recht groß sein sollte. Neben dieser Forderung an a und c gelten noch einige statistische Tests als maßgeblich für die Qualität eines Zufallszahlengenerators.

Als „minimum standard“ bezeichnet man den Generator mit

a = 75 = 16807
c = 0
m = 231-1 = 2147483647

der von Lewis, Goldman und Miller bereits 1969 vorgeschlagen wurde. Hierbei muss man jedoch auf 2 Effekte achten:

(1) n darf nie Null sein, weil dann nur noch Nullen folgen.
(2) Der Überlauf bei 32-bit-Maschinen.

Punkt (1) kann man leicht testen. Punkt (2) ist auch nicht so wild, weil man zeigen kann, dass für obiges a und m Folgendes gilt:

(a * n) % m = a * (n % 127773) - 2836 * (n / 127773)

Wenn der Term auf der rechten Seite
#include
long random (long init) {
static long n;
if (init>0) n= init;
else if (0==n) n= (long)time(0);
n = a * (n % 127773) - 2836 * (n / 127773);
if (n
Er liefert dir eine Zufallszahl zwischen 1 und 2147483646. Dir dürfte sofort klar sein, warum man diesen Generator in der Praxis nur selten benutzt: Die Divisionen dauern recht lange. Man kann zwar noch die Modulo-Division einsparen, indem man etwa so was einfügt:

 long div= n / 127773;
 long mod= n - 127773 \* div;
 n = a \* mod - 2836 \* div;

Aber so viel schneller ist das auch nicht. Daher hat man einen Generator entwickelt, der zwar nicht ganz so zufällig ist (aber dennoch alle statistischen Tests sehr gut besteht), dafür aber extrem schnell ist. Seine Parameter lauten:

a = 1664525
c = 1013904223
m = 232

Das Schöne hieran ist, dass man keine Probleme mit der Null hat und dass man keine Modulo-Division benötigt, weil ein 32-Bit-Rechner diese intrinsisch durchführt. Implementiert sieht das so aus:

unsigned long random (unsigned long init) {
 static unsigned long n;
 if (init\>0) n= init;
 return n = 1664525 \* n + 1013904223; }

Schneller geht’s wohl kaum noch. Und der Generator ist wirklich ausgezeichnet, viel besser als alles, was in C/C++ „eingebaut“ ist. Den ersten Aufruf solltest du mit „random(time(0))“ machen, damit n initialisiert wird. Sonst bekommst du immer die gleiche Folge von Zufallszahlen, weil static-Variable standardmäßig mit Null initialisiert werden. Jeder weitere Aufruf passiert dann mittels „random(0)“ …

So, ich hoffe, das ist genug Zufall, und dass ich mich halbwegs verständlich machen konnte :smile:))

cu Stefan.

Die in C/C++ eingebauten Zufallszahlen-Generatoren sind sehr
schlecht.

Wie jetzt, sind das etwa keine Implementierungen von ‚/dev/random/‘?

Thorsten

Hi Thorsten :smile:

Die in C/C++ eingebauten Zufallszahlen-Generatoren sind meistens sehr schlecht. Der ANSI-Standard schreibt nämlich vor, dass eine Zufallszahl nur mindestens short zu sein braucht. Daher kannst du nach 32767 Zufallszahlen mit dem Beginn des Wiederholungszyklus rechnen. Es kann sein, dass einige Compiler-Hersteller gute Generatoren mitliefern. Um aber auf Nummer sicher zu gehen, sollte man sich mit ein paar Zeilen Code schnell selber einen guten Generator schreiben :smile:

cu Stefan.