Hausaufgabe komm net mehr weiter

  • hi ihr da,


    sitz jetzt schon seit 4 tagen an der aufgabe und hab das programm auch fertig und es läuft aber bei mir macht das lottospiel, wenn es eine doppelte zahl generiert eine erneute ziehung und das wil mein prof nicht! könnt ihr mir vielleicht helfen? Wichtig ist halt, das die Wahrscheinlichkeit gleich sein muss und das nur 6 Ziehungen gemacht werden dürfen.


    Lottozahlen: Erzeugen sie ein Programm, das Lottozahlen per Zufallsgenerator zieht. Dabei soll sichergestellt sein, dass bei jedem einzelnen Ziehungsschritt nur die Zahlen benutzt werden, die bisher noch nicht gezogen wurden, dass die verbleibenden Zahlen also alle mit der gleichen Wahrscheinlichkeit gezogen werden. Verwenden Sie also keine Lösung, bei der ein erneuter Ziehungschritt durchgeführt werden muss, falls die gezogene Zahl bereits gezogen wurde.


    Wenn sich irgendjemand die mühe macht und einen programmcode schreibt, könnte er mir dann bitte auch erklären warum?


    gruss goldie

  • Hi,


    du könntest ein array mit den zahlen von 1 bis 49 machen.


    Danach wählst du per Zufall eine Stelle des arrays aus (0-48), merkst dir die zahl an der Stelle in einem anderen array und schreibst in das 49er an die stelle eine 0.


    Danach wählst du wieder per zufall eine zahl aus dem 49er aus, wenn sie aber eine 0 ist, d.h., schon mal gezogen wurde, wählst du einfach nochmal eine aus.


    Somit wählst du immer aus dem restlichen "Zahlenbestand" aus.

  • Hallo !


    Leider kenne ich mich damit nicht so gut aus, aber ich habe das gleiche Programm für Visual B gefunden, vielleicht kann man daraus etwas nutzen:


    Zitat

    Beschreibung
    Aus gegebenem Anlass (wir hatten diesbezüglich eine an uns gerichtete Anfrage) möchten wir Ihnen heute einen Routine zum Generieren von Lotozahlen 6 aus 49 vorstellen. Beim Erzeugen der Zufallszahlen muss sich die Zahl immer zwischen 1 und 49 befindet. Außerdem darf eine bereits ermittelte Zahl nicht doppelt "gezogen" werden.


    Siehe (Quelle) und Lösung: http://www.vbarchiv.net/archiv/tipp_details.php?pid=222



    Viele Grüße !
    Janine

    Montag früh, 8:00 Uhr und die Woche nimmt einfach kein Ende

  • ok, ich glaub ich weiß was gemeint ist


    also bei http://www.paules-pc-forum.de/phpBB2/topic,34267.html
    hatten wir das so gelöst, wie in dem VB Beispiel


    mit

    Code
    lottotrommel[zufallszahlen] = 1+(rand()%49);

    wird bei jeder Ziehung mit einer Wahrscheinlichkeit von 1/49 gezogen, auch wenn schon Ziehungen gemacht wurden, was aber in der Realität anders aussieht, da ändert sich die Wahrscheinlichkeit ja mit jeder Ziehung: 1/49 -> 1/48 -> 1/47 -> 1/46 -> 1/45 -> 1/43


    d.h. wir müssen unser Modulo immer eins kleiner machen (...%(50-nZiehung)), was aber zur Folge hat, dass dann nicht mehr die letzten Ziffern gezogen werden können, da zur zweiten Ziehung maximal 48 gezogen werden kann, zur dritten maximal 47 usw.


    man könnte das so lösen, indem man ein 49er Array (Array[49]) anlegt mit den Zahlen von 1 bis 49 (Array[0]=1;Array[1]=2;...mit Schleife machen)
    mit "Index=(rand()%49)" erzeugt man sich den Index und gibt den Inhalt des zugehörigen Feldes als Ziehung aus (AktZiehung=Array[Index]), nun muss man das Letzte Feld in dieses kopieren (bei der ersten Ziehung: Array[Index]=Array[49-nZiehung] .... nZiehung ist Zähler der Ziehungen) und macht die nächste Ziehung


    korrigiert mich wenn da n Denkfehler drin ist :|


    Edit: wobei das bei der bisherigen Methode (wenn schon gezogen, dann Ziehung wiederholen) alles nicht so schlimm ist mit der Wahrscheinlichkeit bei den weiteren Zügen, denn die Wahrscheinlichkeiten der einzelnen "Kugeln" sind ja immer gleichverteilt

    Zitat

    dass die verbleibenden Zahlen also alle mit der gleichen Wahrscheinlichkeit gezogen werden

    ist dort also auch gewährleistet

  • Hallo,
    tja die Frage habe ich gestern auch gelesen,mir viel dazu folgendes ein:
    um zu ereichen das ich 6 Ziehungen mit der Wahrscheinlichkeit von 1 aus 49 habe,und NICHT (1 aus 49)-1,(1 aus 49)-2 usw.
    (Sorry,wie nenntt man dieses Zahl? bin kein Matematiker ;) )
    fällt mir nur folgendes ein:

    Code
    int a[10],b[6];//dürfte reichen
    int i;
    for(i=0;i<10;i++)
    a[i]=1+(rand()%49); 
    
    
    for(i=0;i<6;i++)
    b[i]=a[rand()%10];


    Aber wahrscheinlich ist das um zu viele Ecken gedacht und totaler Unsinn,es findet auch keine Prüfung statt ob in b eine Zahl 2.mal vorkommt... ;)


    Peter

  • ich bins nochma,


    hab jetzt alles versucht aber weiss einfach net wie ich das schreiben soll, bin langsam total am verzweifeln. mein programm war doch so perfekt und mein prof ...arghhhhh... will das net so.
    hab das mit den array das zahlen von 1-49 beinhaltet hinbekommen aber weiss jetzt einfach net mehr weiter. und jetzt?


    gruss goldie

  • #include <conio.h>
    #include <iostream.h>
    #include <stdlib.h>
    #include <dos.h>


    /*goldie007 klappe 23, 3201 Versuch*/



    void main(void)
    {
    const int n = 49;
    const int k = 6;
    int Lottotrommel1[n];
    int Lottotrommel2[k];
    int Index1;
    int Index2;
    int zaehler;


    for (Index1 = 0; Index1 < 49; Index1++)
    {
    Lottotrommel1[Index1] = ++zaehler;
    }
    getch();
    }



    und wie muss ich jetzt weitermachen das ich 6 zahlen aus dem array lottotrommel1 herausbekomme????


  • habs nicht getestet

  • danke jamo für deine schnelle antwort und dazu noch ein programm!


    hab das ausprobiert und mir nochmal den kopf zerbrochen, weil er trotzdem immernoch doppelziehungen drin hat:




    würde das was bringe, wenn ich anstatt "Index1 = (rand() % n-1-Index2)", nicht lieber "Index1 = (rand() % n- irgendwie die entsprechende gezogene Zahl aus dem Lottotrommel1 array abzieh)" damit der keine Doppelziehungen mehr drin sind?
    warum kann man net einfach delete und dann die gezogene zahl schreiben?


    gruss goldie

  • also


    ich hab mein Programm mal getestet
    es war ein Fehler beim füllen der Lottotrommel

    Code
    Lottotrommel1[Index1] = Index+1;

    da fehlt die 1 beim Index hinten

    Code
    Lottotrommel1[Index1] = Index1+1;

    und das fehlende randomize(), ohne das immer die gleichen Zufallszahlen gezogen werden
    und

    Code
    Index1=(rand()%n-Index2);

    sollte besser so aussehen

    Code
    Index1=(rand()%(n-Index2));


    jetzt zu deinem:
    weil "zaehler" nicht initialisiert ist füllt der bei mir die Trommel mit sonstwas (ich verwende Borland C++ 3.1, dein Compiler initialisiert wahrscheinlich automatisch mit 0, da das bei dir wohl net passiert ist)


    und klar, Doppelziehungen kommen noch vor weil

    Code
    if(Index1 != (n-1-Index2))Lottotrommel1[Index1] = Lottotrommel1[n-1-Index2];//Bedingung kann man auch weglassen

    fehlt
    ich meinte hier, die if-Bedingung kann man weglassen, nicht die ganze Zeile
    denn hier wird die gerade gezogene Kugel überschrieben mit der Kugel aus dem letzten Feld, welches ja bei der nächsten Ziehung nicht mehr gezogen werden kann, da wir die Auswahl ja immer um eins verkleinern


    und dann kann man natürlich nicht mehr

    Code
    Lottotrommel1[Index1]

    ausgeben, sondern muss

    Code
    Lottotrommel2[Index2]

    ausgeben


    und

    Code
    Index1 = (rand() % (n-Index2));

    ist schon richtig so, und nicht

    Code
    Index1 = (rand() % (n-1-Index2));

    oder liege ich da falsch?


    der gesamte Code also:

  • hi ihr lieben,


    jamo kann dir gar net genug danken! war schon total am verzweifeln!!! selbst wenn ich das programm abgebe, werd ich immer im hinterkopf haben, das du das programm programmiert hast. und dafür dank ich dir, weil ich blödes huhn das net hinbekommen hab. deswegen werd ich am wochenende erstmal viele bücher einkaufen gehen, irgendwelche vorschläge für c/c++ (<- für anfänger wohlbemerkt!)??


    könntest du mir trotzdem noch was erklären, versprech dir auch das ich das letzte mal für dieses jahr belästigen werde ;)



    was macht der genau in den 3 schritten?



    Code
    Index1 = (rand() % (n-Index2));
    
    
          Lottotrommel2[Index2] = Lottotrommel1[Index1];
    
    
          Lottotrommel1[Index1] = Lottotrommel1[n-1-Index2];


    liebe grüsse goldie

  • ok 007


    1.)

    Code
    Index1 = (rand() % (n-Index2));


    % ist der Modulo Operator, a % b heißt: die ganze (int) Zahl a wird durch die ganze Zahl b geteilt und der Rest wird zurückgegeben


    Bsp.: 34 % 10 -> Ergebnis 4
    weil 34 : 10 = 3 Rest 4


    rand() liefert uns eine Zufallszahl in einem ziemlich großen Wertebereich mit gleichverteilter Wahrscheinlichkeit (jede Zahl in diesem Werteberich wird zur gleichen Wahrscheinlichkeit gezogen)
    mit dem Modulo können wir uns den Ergebnisbereich der Zufallszahl einschränken weil ja der Rest immer kleiner ist als der Dividend (Teiler)
    teilen wir also die Zufallszahl durch n (49) erhalten wir einen Wert zwischen 0 und 48 als Index für unser Array
    da wir aber bei jeder Ziehung eine Kugel rausnehmen müssen wir unser Array jedesmal um 1 verkürzen (kommt gleich) und müssen dann natürlich auch den Ergebnisbereich der Zufallszahl um 1 verkürzen, also (n-Index2), Index2 ist ja bei der ersten Ziehung 0 -> Wert 0 bis 48, bei der zweiten Ziehung 1 -> Wert 0 bis 47 usw.



    2.)

    Code
    Lottotrommel2[Index2] = Lottotrommel1[Index1];


    jetzt holen wir uns den Wert der in unserem Array an der zufällig ermittelten Stelle liegt und merken ihn uns



    3.)

    Code
    Lottotrommel1[Index1] = Lottotrommel1[n-1-Index2];


    nun müssen wir noch das Array "verkürzen"
    dazu kopieren wir die letzte Kugel (der Auswahl) an die Stelle wo die gezogene Kugel war
    damit ist die Lücke geschlossen und die gezogene Kugel raus aus dem Array
    die letzte Kugel ist zwar zwei mal da, aber das Element hinten kann ja bei der nächsten Ziehung nicht mehr gezogen werden
    wenn die letzte Kugel aus der Auswahl gezogen wurde braucht man diesen Kopiervorgang nicht


    kannst dir ja immer das Array ausgeben lassen, dann siehst du wie die Kugeln verschoben werden und die Auswahl verkleinert (siehe printf Ausgaben in meinem Programm)


    so, alles klar jetzt? :wink:

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!