Zufallsgenerator



  • Hallo!
    ich bin neu hier...
    bin ich in der richtigen "gruppe" mit mefiner frage?
    Danke

    also
    wie schreibe ich eine zufallszahl in ein programm? 😕
    also 0-x
    kann ich bei x jede beliebige zahl einsetzen?
    das in eine Variable zu schreiben kann ich doch hoffendlich mit

    xyz = %code zur zahl%
    

    gibt es noch was wichtiges dazu?
    ich bedanke mich für alle antworten!
    Elefunty





  • Hallo
    so, ich hab jez die links getestet.
    den2ten hab ich nich so kapiert?
    aber egal!
    der linke is schon sehr richtig.
    dumm nur, dass wie auch dort gesagt, dass (bei mir jedenfalls) die zahlen von null bis 99 "hochlaufen" und es so aussieht, als ob nur einige zahlen verschwunden sind!
    dann hab ich (mit gleicher nicht so guter erfolg) folgendes probiert:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int sr,sr1;
        srand(time(NULL));
        sr1=time(NULL)*rand();
        srand(sr1);
        sr=time(NULL)/rand();
        srand(sr);
        int i;
        i = rand()%101;
        cout<<i<<endl;
        getchar();
        return 0;
    }
    

    aber wirklich zufälliger sind die zahlen auch nicht 😞 .
    hilft es wenn ich öfter diese variablen in srand verwende, und vorher mit einer zufallszahl belege?
    oder funzt srand nur das erste mal und bleibt dann auf time(NULL)?
    oder kann man das noch irgendwie ganz anders machen........
    Aber schon mal danke!
    Elefunty



  • Hallo

    Du musst srand nur einmal aufrufen und zwar am Programmbeginn:

    srand(time(NULL));
    int Zufallszahl = rand()%100 //bringt Zhalen zwischen 0 und 99
    int Zufallszahl2 = rand()%50 //bringt Zahlen zwischen 0 und 49
    

    chrische



  • srand(...) erzeugt den "seed" ("set random seed"), rand() erzeugt die Folge.

    rand() ergibt bei jedem Aufruf eine Zahl aus einer Folge ganzzahliger Pseudozufallszahlen aus dem Bereich von 0 bis zum Wert RAND_MAX.

    Hier noch eine grundlegendere Bemerkung zu diesem Thema, falls Du selbst mal Hand anlegen willst:

    Aus der Informatik-Literatur sind Zufallszahlen-Generatoren bekannt, die sich in vielen Versuchen als "sehr zufällig" erwiesen haben. Sie gründen auf dem gleichen Prinzip, denn aus einer Zufallszahl n wird eine neue Zufallszahl nach folgendem Schema berechnet:

    n = (a * n + c) % m
    

    Hierbei kommt es darauf an, die Zahlen a, c und m optimal zu wählen. Es ist klar, dass sich die generierten Zufallszahlen wiederholen, sobald die erste Zufallszahl n erneut auftritt. Deswegen wählt man a und c so, dass die Wiederholung soweit wie möglich nach hinten geschoben wird. Neben dieser Forderung an a und c sind statistische Tests entscheidend für die Qualität eines Zufallszahlengenerators.

    Einen sogenannten "minimum standard" liefert der Zahlengenerator

    a = 7 hoch 5 = 16807
    c = 0
    m = 2 hoch 31 - 1 = 2147483647
    

    der von Lewis, Goldman und Miller im jahre 1969 vorgeschlagen wurde.
    Hierbei wird noch folgendes beachtet:

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

    Ersteres kann man leicht testen. Der zweite Punkt ist auch nicht bedenklich, 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 <0 sein sollte, muss man noch m addieren, um das richtige Resultat zu bekommen! Damit sieht also der "minimum standard" Zufallsgenerator so aus:

    #include <time.h>
    
    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<0) 
            n+= 2147483647;
        return n; 
    }
    

    Hiermit erhält man eine Zufallszahl zwischen 1 und 2147483646. Leider ist diese Realisierung langsam, denn die Divisionen kosten zu viel Zeit. Man kann die Modulo-Division einsparen, indem man wie folgt vorgeht:

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

    Aber viel bringt das nicht. Daher entwickelte man einen Zahlengenerator, der zwar nicht ganz so zufällig ist, dafür jedoch deutlich schneller ist.
    Die Parameter lauten:

    a = 1664525
    c = 1013904223
    m = 2 hoch 32
    

    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; 
    }
    

    Der erste Aufruf erfolgt mit "random(time(0))", damit n "zufällig" initialisiert wird. Sonst bekommst du immer die gleiche Folge von Zufallszahlen, weil static-Variablen standardmäßig mit 0 initialisiert werden. Jeder weitere Aufruf passiert dann mittels "random(0)" ...



  • ja gut, ok!
    aber dann sind die zahlen nicht wirklich zufällig.
    kann mann da nich irgendwie mit ner formel oder sowas die zahl zufälliger machen?
    irgendwie mit ner formel

    zahl+y-x*xy/yx oder so
    

    gibts da irgendetwas was man da am besten macht?
    oder geht das nicht?
    naja bis dann
    Elefunty



  • Elefunty schrieb:

    aber dann sind die zahlen nicht wirklich zufällig.

    Was stellst du dir denn unter "wirklich zufällig" vor? Woran machst du fest, dass die Zahlen, die dir rand liefert, nicht "wirklich zufällig" sind?



  • uuups hab zu lange getippt 😮

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int y;
        y+=time(NULL);
        y+=time(NULL);
        y+=time(NULL);
        y+=time(NULL);
        y*=time(NULL);
        y-=time(NULL);
        y+=time(NULL);
        y/=time(NULL);
        y+=time(NULL);
        y+=time(NULL);
        y*=time(NULL);
        y-=time(NULL);
        y+=time(NULL);
        y-=time(NULL);
        y+=time(NULL);
        y+=time(NULL);
        y*=time(NULL);
        y-=time(NULL);
        srand(y);
        int i,a;
        i = rand()%11;
        a=i*rand()%11;
        a=a/rand()%11;
        cout<<i<<endl;
        getchar();
        return 0;
    }
    

    so funzt es jez, es sind ziemlich zufällige zahlen!
    das das n umständlicher code is weiß ich, aber es is für mich totall ok!!!! 😉

    MFK schrieb:

    Elefunty schrieb:

    aber dann sind die zahlen nicht wirklich zufällig.

    Was stellst du dir denn unter "wirklich zufällig" vor? Woran machst du fest, dass die Zahlen, die dir rand liefert, nicht "wirklich zufällig" sind?

    daran das die zahlen hochlaufen, in der richtigen reihenfolge und das stört mich!...
    naja bis dann
    Elefunty



  • Schau Dir erst mal folgende Seiten an, damit Du auf Stand bist, bevor Du weiter solchen "Müll" produzierst:
    http://de.wikipedia.org/wiki/Zufall
    http://de.wikipedia.org/wiki/Zufallsgenerator
    http://de.wikipedia.org/wiki/Mersenne_Twister
    http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html

    Beispiel-Code

    <edit>Quellcode durch Link ersetzt</edit>



  • Hallo

    Elefunty schrieb:

    MFK schrieb:

    Elefunty schrieb:

    aber dann sind die zahlen nicht wirklich zufällig.

    Was stellst du dir denn unter "wirklich zufällig" vor? Woran machst du fest, dass die Zahlen, die dir rand liefert, nicht "wirklich zufällig" sind?

    daran das die zahlen hochlaufen, in der richtigen reihenfolge und das stört mich!...
    naja bis dann
    Elefunty

    Dann hast du irgendwo einen Fehler. Normalerweise reicht es vollkommen aus, wenn du srand einmal ausrufst und dann loslegst. Das was du da machst ist unnötig und hat auch keinen Sinn.

    chrische


Anmelden zum Antworten