randomize() spinnt!
Results 1 to 20 of 20
  1. #1

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts

    randomize() spinnt!

    Ich versuche gerade einen Würfelwurf zu implementieren mit einem 6-seitigen Würfel. Dazu müsste ich doch zuerst randomize() verwenden, damit rand() eine Zufallszahl liefert. Das komische ist jetzt, das die ausgabe von

    cout << (rand()%6 + 1);

    bei mir zuerst einpaar mal eine 1 liefert, dann einpaar mal eine 2, dann paar 3er, 4er, 5er und dann ein paar 6er. Die genaue Anzahl ist immer unterschiedlich, aber immer in dieser Reihenfolge!

    Weiß jemand, was ich falsch mache?

    Ich hab auch den kleinen Quellcode und das kompilierte Programm upgeloaded, würd mich freuen, wenn sich jemand kurz die Zeit nimmt, es bei sich am PC zu testen, vielleicht liegts auch an meinem Rechner (kann mir sonst nichts vorstellen...)

  2. #2
    Zentor's Avatar
    Title
    CO-Administrator
    Join Date
    Dec 2001
    Location
    Wien???
    Posts
    1,156
    Thanks
    2
    Thanked 9 Times in 6 Posts
    ich kenn mich nicht so mit c++ aus aber gennerell liefert rand() doch einen Wert 0<= x <1
    wieso machst du dann rand()%6 +1 und nciht rand()*6+1 ?

  3. #3

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    in c++ liefert rand() einen Wert zwischen 0 und 32767 (siehe weiter unten)

    Ich habs inzwischen mit random(6) versucht, da schauts aber auch nicht viel besser aus: die Zahlen sind nachher schon zufällig, doch kommt für eine gewisse Zeitspanne immer die gleiche Zahl, auch wenn man randomize() verwendet.

    In der Library hab ich dann die Definitioni von random(int) und rand() gefunden:

    inline int _RTLENTRY random(int __num)
    { return __num ? (int)(_lrand()%(__num)) : 0; }

    /* Maximum value returned by "rand" function */
    #define RAND_MAX 0x7FFFU

    inline void _RTLENTRY randomize(void) { srand((unsigned) time(NULL)); }

    Mich wundert, dass in der Definition von randomize ein time-Objekt übergeben wird. NULL ahnung, wieso...
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  4. #4

    Title
    Principal
    Join Date
    Jan 2002
    Posts
    60
    Thanks
    0
    Thanked 0 Times in 0 Posts
    hi

    also das time-Objekt ist meines wissens dafür verantwortlich, daß die generierte zahl wirklich zufällig ist.
    Würde man immer den gleichen Startwert für nen randomizer verwenden, würde man immer die gleiche zahlenfolge erzeugen.

    i hoff das stimmt so

    mfg
    Roli
    Sex (female) is: grep; touch; unzip; touch; gasp; finger; gasp; mount; fsck; more; yes; gasp; umount; make clean; make mrproper

    Sex (male) is: grep; touch; strip; unzip; head; mount /dev/girl -t wet; fsck; fsck; yes; yes; yes; umount /dev/girl; zip; sleep or good

  5. #5

    Title
    Elite
    Join Date
    Dec 2001
    Posts
    340
    Thanks
    0
    Thanked 0 Times in 0 Posts
    schau auch auf http://www.cplusplus.com/ref/cstdlib/srand.html

    die seite ist überhaupt nicht so schlecht
    I invented ctrl-alt-del but Bill [Gates] made it famous
    Dave Bradly, IBM PC designer

  6. #6
    Zentor's Avatar
    Title
    CO-Administrator
    Join Date
    Dec 2001
    Location
    Wien???
    Posts
    1,156
    Thanks
    2
    Thanked 9 Times in 6 Posts
    ok, sorry hab gedacht das funktioniert so wie bei Java und Basic. Also auf der Seite ist ein Sample zum verwenden des rand():
    http://home1.gte.net/deleyd/random/crandom.html
    Kurz gesagt nimm einfach (double)rand()/(double)(RAND_MAX+1) um eine Zahl zw 0 und 1 zu erhalten. mit srand(seed) kann man den random number generator ein anderen seed zuweisen (seed vom Typ int). Da hilft sicher die System zeit (die Sache mit den Sekunden seit dem 1.1.1970) etwas herumtransformiert.

    p.s. es wird auf der Seite auch extra darauf hingewiesen das man nicht deine Methode verwenden soll:
    Note: Do NOT use

    y = rand() % M;

    as this focuses on the lower bits of rand(). For linear congruential random number generators, which rand() often is, the lower bytes are much less random than the higher bytes. In fact the lowest bit cycles between 0 and 1. Thus rand() cycles between even and odd (try it out). Be sure to do as above instead.
    mfg Zentor

  7. #7

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    @martin: Auf der Seite steht nur das, was das randomize() selber macht, hilft mir nicht viel, danke.

    @Roli: ist mir schon klar, nur frag ich mich, wiese gerade ein Time-Objekt übergeben wird (vor allem wenn wenn der Output immer für eine Zeitspanne der gleiche ist)

    @Zentor: Danke, hat auch nix genutzt, Ausgabe trotzdem genauso wie von (rand() % Zahl + 1).


    Nochmal das Problem: Mein Programm hat immer folgende Ausgabe:

    Code:
    for (unsigned int i = 0; i < 1000; i++)
        cout << rand()%6+1 << " ";
    2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 und noch uur viele 2er .... 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 dann verdammt viele 5er noch 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 usw...
    Last edited by Soulmerge; 11-05-2002 at 13:47.
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  8. #8

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Bis jetzt hab ich die "zufälligste" Ausgabe mit random(6)+1 erhalten, aber da wechselt die Zahl, die ausgegeben wird auch nur (ca.) sekündlich.

    Wie schauts denn bei den Leuten aus, die das zip runtergeladen haben? Da niemand was dazu gepostet hat, geh ich mal davon aus, dass es bei denen nicht anders war.

    Soweit ich das sehe, erstellt srand(Zahl) die Zufallszahlen, randomize() ist srand(time(NULL)) und man muss immer warten, bis time(NULL) etwas anderes zurückgibt, wenn man mehrere Zufallszahlen will.

    Vielleicht gibt es eine Möglichkeit, srand mit Tausendstelsekunden zu füttern? Das wäre sehr angenehm...
    Last edited by Soulmerge; 11-05-2002 at 13:57.
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  9. #9

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Nochmal ich:

    Hab das Problem folgendermaßen gelöst:

    clock(): Return number of clock ticks since process start.

    Ausgabe hatte aber immer noch zuviele wiederholungen, also hab ich immer etwas verzögert:

    Code:
    for (unsigned short i = 0; i < 100000; i++)
    {
        srand(clock());
        treturn = _lrand() % dice + 1;
        clock_t endwait = clock() + 0.1*CLK_TCK;
        while(clock() < endwait);
        cout << treturn << " ";
    }
    Liefert endlich *wirklich* zufällige Zahlen, zwar nur 6-8 pro Sekunde, aber das genügt, glaub ich.
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  10. #10

    Title
    Elite
    Join Date
    Feb 2002
    Posts
    482
    Thanks
    0
    Thanked 0 Times in 0 Posts
    du kannst alternativ zu

    #include < stdlib.h >

    srand(_irgendein_zufälliges_argument_);
    wuerfel = rand()%6;

    auch einfach aus /dev/random oder /dev/urandom lesen, wenn du unter Linux programmierst. Aber welchem Kernel das zur Verfügung steht bzw. obs andere Unices auch anbieten, weiß ich nicht genau, aber /dev/urandom liefert deutlich mehr (vorzeichenlose) Zufallszahlen als 6-8 pro Sekunde...

    aber wenn du als Argument für srand() was komplexeres wie ((time()%getpid())*getppid()) verwendest, solltest du eigentlich auch "echte" Zufallszahlen kriegen...

  11. #11

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Ich programmier grad in dos, aber der Obige Ausdruck hat mich auf eine andere Idee gebracht (der Ausdruck selber hat leider nicht viel geholfen, da ja der Wert des Ausdrucks ((time()%getpid())*getppid() nur von time() abhängt)

    Code:
    for (unsigned int i = 0; i < 10000000; i++)
    {
        srand(clock() * i * i);
        cout << random(6) + 1 << " ";
    }
    Frag mich, wieso ich nicht gleich drafgekommen bin??!?
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  12. #12
    MaxAuthority's Avatar
    Title
    Gewinner des Desktop-Contest 2002
    Join Date
    Feb 2002
    Location
    Wien
    Posts
    833
    Thanks
    0
    Thanked 6 Times in 4 Posts
    wenn du unter windows programmierst ist das einfachste:

    srand(GetTickCount());
    for(int i=0; i<1000; i++)
    {
    /*kann sein dass hier ein kleines argument fehlt, hab es selbst nicht kompiliert*/
    rand()%6+1;
    }


    das wichtige ist eigentlich srand(GetTickCount()); das du aber soweit ich weiß nur einmal ausführen musst, und nicht in jedem schleifenaufruf, hatte damit noch nie probleme
    http://vimperator.org - Make Firefox behave like Vim

  13. #13

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Das ist geil!! Wenn ich winbase.h include kommt folgende Compilermeldung:


    Code:
    Error E2303 C:\CPP\include\winbase.h 227: Type name expected
    Error E2139 C:\CPP\include\winbase.h 227: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 228: Type name expected
    Error E2238 C:\CPP\include\winbase.h 228: Multiple declaration for '_OVERLAPPED::ULONG_PTR'
    Error E2344 C:\CPP\include\winbase.h 227: Earlier declaration of '_OVERLAPPED::ULONG_PTR'
    Error E2139 C:\CPP\include\winbase.h 228: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 229: Type name expected
    Error E2139 C:\CPP\include\winbase.h 229: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 230: Type name expected
    Error E2238 C:\CPP\include\winbase.h 230: Multiple declaration for '_OVERLAPPED::DWORD'
    Error E2344 C:\CPP\include\winbase.h 229: Earlier declaration of '_OVERLAPPED::DWORD'
    Error E2139 C:\CPP\include\winbase.h 230: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 231: Type name expected
    Error E2139 C:\CPP\include\winbase.h 231: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 235: Type name expected
    Error E2139 C:\CPP\include\winbase.h 235: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 236: Type name expected
    Error E2139 C:\CPP\include\winbase.h 236: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 237: Type name expected
    Error E2139 C:\CPP\include\winbase.h 237: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 241: Type name expected
    Error E2139 C:\CPP\include\winbase.h 241: Declaration missing ;
    Error E2303 C:\CPP\include\winbase.h 242: Type name expected
    Error E2238 C:\CPP\include\winbase.h 242: Multiple declaration for '_PROCESS_INFORMATION::HANDLE'
    Error E2344 C:\CPP\include\winbase.h 241: Earlier declaration of '_PROCESS_INFORMATION::HANDLE'
    Error E2228 C:\CPP\include\winbase.h 241: Too many error or warning messages
    *** 26 errors in Compile ***
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  14. #14
    MaxAuthority's Avatar
    Title
    Gewinner des Desktop-Contest 2002
    Join Date
    Feb 2002
    Location
    Wien
    Posts
    833
    Thanks
    0
    Thanked 6 Times in 4 Posts
    muss man eigentlich die winbase.h direkt includen?
    also wenn ich windows anwendungen schreibe, reicht normalerweise < windows.h> aus, der header included dann soweit ich weiß eh selbstständig winbase.h.

    es kann aber auch sein dass ich mich irre....
    http://vimperator.org - Make Firefox behave like Vim

  15. #15

    Title
    Elite
    Join Date
    Feb 2002
    Posts
    482
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Original geschrieben von Soulmerge
    Ich programmier grad in dos, aber der Obige Ausdruck hat mich auf eine andere Idee gebracht (der Ausdruck selber hat leider nicht viel geholfen, da ja der Wert des Ausdrucks ((time()%getpid())*getppid() nur von time() abhängt)
    Ok, unter DOS hast du weder die /dev/ Devices, noch Pids...
    Aber in meinem Ausdruck hängt der Wert nicht nur von der momentanen Zeit, sondern auch von der Process ID deines Programmes, sowie von der PID dessen Vater-Prozesses... solche Ausdrücke kommen in vielen GNU Programmen als "random seed" vor...

    Btw, ich verstehe deinen code nicht ganz, eigentlich solltest du mit srand(long seed) den Zufallszahlengenerator initialisieren können, sofern "seed" eine "relativ zufällige" Zahl ist, und ab dann solle rand() vorzeichenlose Integerwerte von 0 bis RAND_MAX ausspucken, jedensfalls brauchst du srand() nicht in jedem Schleifendurchgang erneut aufrufen, bringt genau "void"

  16. #16

    Title
    Master
    Join Date
    Feb 2002
    Location
    Erde
    Posts
    123
    Thanks
    0
    Thanked 0 Times in 0 Posts
    AAAAAAAARRRRGH!!!

    Wie kann man nur so einen blöden Fehler machen??????!?

    Nicht nur, das srand() in jedem Schleifendurchlauf nichts bringt, sondern es bringt mich genau auf den Fehler, durch den ich diesen Thread eröffnet habe! srand() initialisiert eine Folge von Zufallszahlen, nicht nur eine!

    *ärger*

    Vielen dank für den Hinweis!

    PS: getpid() gibt Prozess-ID zurück...
    '100 little bugs in the code, 100 bugs in the code. Fix one bug, compile it again: 101 little bugs in the code.
    101 little bugs in the code . . .'
    Continue until 0 Bugs reached...

  17. #17
    Judas42's Avatar
    Title
    Elite
    Join Date
    Jul 2002
    Location
    Wien
    Posts
    360
    Thanks
    0
    Thanked 1 Time in 1 Post
    Die Sache ist folgende: Bei einem Zufallsgenerator wird irgendeine beliebige Zahl als Startwert genommen. Bei jedem rand() wird der aktuelle Inhalt dieser Variable ausgegeben. Dann werden bestimmte Bits über irgendeinen Algorithmus miteinander verknüpft und an bestimmten Stellen in der Variable eingefügt, was einen (mehr oder weniger) zufälligen Folgewert ergibt.

    Mit randomize() wird einfach dieser Startwert gesetzt, was bei einer time-Variable mit der aktuellen Systemzeit auch "zufällig" ist. Wenn man randomize() aber mehrmals pro Sekunde aufruft, wird der Zufallsgenerator immer mit der gleichen Zahl initialisiert sodaß das darauffolgende rand() innerhalb einer Sekunde immer den gleichen Wert liefert.

    Lösung: randomize() nur ein mal aufrufen...

    EDIT: Die Variable, die den aktuellen Zufallswert und damit die Berechnungsgrundlage für den Folgewert speichert, nennt man auch "random seed" (vielleicht weil daraus der Folgewert "wächst"?)
    Last edited by Judas42; 21-08-2002 at 23:22.
    "The letters are Hex, of an ancient mode, but the language is that of Microsoft, which I shall not utter here."

  18. #18
    jjan's Avatar
    Title
    Elite
    Join Date
    Feb 2002
    Location
    /home/jjan
    Posts
    267
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Hier noch die Standardantwort aus comp.lang.c zu diesem Thema ...

    http://www.eskimo.com/~scs/C-faq/q13.16.html

    [EDIT]:
    Für jeden nichttrivialen Anwendungsfall empfehle ich zur Generierung von Zufallszahlen, entweder, einen eigenen Generator zu schreiben, oder zumindest jenen aus der BOOST Bibliothek zu verwenden.

    http://www.boost.org/libs/random/index.html

    Die meisten Implementierungen von srand(), rand() und co. sind nämlich meistens miserabel.
    Last edited by jjan; 22-08-2002 at 14:43.
    Eins Zwei Gras Bär Hund Vier Muh Macht Die Kuh

  19. #19

    Title
    Veteran
    Join Date
    Jan 2008
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    standard-random

    moin!
    also zum thema random habe ich eine frage zum folgenen code:


    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>

    // for the random number generator
    #include <cstdlib>
    #include <ctime>

    using namespace std;

    class RandomNumber {
    public:
    RandomNumber() {
    srand(time(0));
    }

    int operator() ( int n) {
    return (int)((double)n * rand()/(RAND_MAX+1.0));
    }
    };

    int
    main(int argc, char **argv)
    {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    v.push_back(6);
    v.push_back(7);
    v.push_back(8);
    cout<<v[0]<<v[1]<<v[2]<<v[3]<<v[4]<<v[5]<<v[6]<<v[7]<<v[8]<<endl;
    RandomNumber r;
    random_shuffle(v.begin(), v.end(), r);
    // copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout<<v[0]<<v[1]<<v[2]<<v[3]<<v[4]<<v[5]<<v[6]<<v[7]<<v[8]<<endl;
    return 0;
    }


    der code soll einen bitstring liefern. allerdings kommt staendig eine fehelrmedlung - weiss jemand woran das liegt?

    lg

  20. #20

    Title
    Veteran
    Join Date
    Jan 2008
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts
    ah, alles klar, ich hab den fehler gefunden^^
    lag nicht am programm das funktioniert so

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •