Zufallszahlen für einen Lottogenerator



  • hallo alle,

    ich benutze folgenden Code für meinen lottogenerator

    int richtige=0;
    		int cur=0;
    		int moeglich[49]; 
                    //m_moeglich: array mit den zahlen von 1 - 49
                    //m_zahlen  : array mit dem von user eingegebenen zahlen
    		while(!beenden())
    		{	
    			memcpy(moeglich,m_moeglich,sizeof(moeglich));
    			for(int upbond=49;upbond>43;upbond--)
    			{
    				//Zufallszahl ermitteln
    			  int ignoreBoundary = (RAND_MAX/(upbond-1) ) * (upbond);
    			  do
    				{
    				 cur = std::rand();
    				} 
    				while (cur > ignoreBoundary); 
    			  cur=cur%(upbond);
    			  swap(&moeglich[cur],&moeglich[upbond-1]);	 
    				//wurde diese Zahl getippt?
    				for(int k=0;k<6;k++)
    					if(m_zahlen[k]==moeglich[upbond-1])
    						richtige++;
                }
    			  result[richtige]++;
    			  if(richtige==6)
    				return 1;
    			  richtige=0;
    		}
    

    Wie ihr sicher bemerkt hab benutze ich teilweise Code hier aus dem C++ Magazin (Artikel: "zufälle gibt's")

    Mein Problem:
    wenn ich die wikipedia hier http://de.wikipedia.org/wiki/Lotto#Gewinnwahrscheinlichkeit
    richtig verstanden hab, müßte im schnitt bei ca. 14 Mio Ziehungen zum ersten mal 6 richtige gezogen werden.

    Bei mir geschieht dies allerdings meist schon bei 6-8 Mio Ziehungen.
    Außerdem erhalte ich sehr unterschiedliche Ergebnisse wenn ich bei einem Durchlauf 1,2,3,4,5,6 nehme und beim anderen 44,45,46,47,48,49

    Wo liegt mein(e)Fehler?

    danke schon mal und fröhliche weihnachten allen :xmas1:



  • is zwar lange her aber: hat da keiner eine idee? 🙂



  • müssten das nicht 49*48*47...*44 möglichkeiten sein?! also weit mehr als 14mio?!

    for(int upbond=49;upbond>43;upbond--)
    

    boa ist das kacke.... unglaublich!

    //wurde diese Zahl getippt?
                    for(int k=0;k<6;k++)
                        if(m_zahlen[k]==moeglich[upbond-1])
                            richtige++;
    

    habs nur überflogen, aber kennst du da so eine anspielung, wo ein affe auf einer schreibmaschiene einhämmert bis mal ein satz aus shakespeare herauskommt?!
    ich denke du solltest 6 zahlen auf einmal in ein array schreiben und alle 6 danach seperat überprüfen. dann müsste es klappen.



  • dgrat schrieb:

    müssten das nicht 49*48*47...*44 möglichkeiten sein?! also weit mehr als 14mio?!

    nur, wenn die Reihenfolge eine Rolle spielt

    in dem Fall musst du danach noch durch 720 (6!) teilen, um auf die knapp 14Mio. Möglichkeiten zu kommen

    @Topic: du brauchst maximal 14Mio durchläufe, nicht im Schnitt. Von daher dürfte dein Ergebnis schon stimmen



  • @zwutz thx. das ich darauf nicht gekommen bin 🙂 *schäm*

    @dgrat kein grund beleidigend zu werden. 😞



  • das geht mit c++ doch eleganter, oder?

    #include <iostream>
    #include <iterator>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    void lotto(vector<int> &ergebnis)
    {
        vector<int> kugeln(49);
        for (int i = 1; i <= 49; ++i) kugeln[i] = i;
        random_shuffle(kugeln.begin(), kugeln.end());
    
        ergebnis.resize(6);
        copy(kugeln.begin(), kugeln.begin() + 6, ergebnis.begin());
        sort(ergebnis.begin(), ergebnis.end());
    }
    
    int main()
    {
        srand(time(0)); //Zufallsgenerator initialisieren
    
        vector<int> lottozahlen;
        lotto(lottozahlen);
        copy(lottozahlen.begin(), lottozahlen.end(), ostream_iterator<int>(cout, " "));
    }
    


  • also es wären in seinem fall nicht maximal 14 mio durchgänge, weil nicht jede kombination durchgezählt wird.



  • komplikator schrieb:

    das geht mit c++ doch eleganter, oder?

    möglich 😉



  • komplikator schrieb:

    das geht mit c++ doch eleganter, oder?

    #include <iostream>
    #include <iterator>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    void lotto(vector<int> &ergebnis)
    {
        vector<int> kugeln(49);
        for (int i = 1; i <= 49; ++i) kugeln[i] = i;
        random_shuffle(kugeln.begin(), kugeln.end());
    
        ergebnis.resize(6);
        copy(kugeln.begin(), kugeln.begin() + 6, ergebnis.begin());
        sort(ergebnis.begin(), ergebnis.end());
    }
    
    int main()
    {
        srand(time(0)); //Zufallsgenerator initialisieren
    
        vector<int> lottozahlen;
        lotto(lottozahlen);
        copy(lottozahlen.begin(), lottozahlen.end(), ostream_iterator<int>(cout, " "));
    }
    
    int main(int argc, char** argv) {
    	srand(time(0));
    	std::set<int> bla;
    	for(int i=0; i<6; ){
    		if(bla.insert(rand()%49+1).second) {
    			i++;
    		}
    	}
    	std::copy(bla.begin(), bla.end(), std::ostream_iterator<int>(std::cout, " "));
    
    	return 0;
    }
    


  • shorter schrieb:

    …

    Es ging um eleganter, nicht kürzer.



  • Und was is warum eleganter? Ne Funktion kann ich auch noch draus machen, wenns sein muss...



  • shorter schrieb:

    Und was is warum eleganter?

    Eine effiziente Lösung. Deine ist nicht effizient, weil sie keine definitiv berechnenbare Laufzeit besitzt. Wenn man Pech hat, dauert Deine Lösung ewig, weil immer wieder dieselbe Zahl erwürfelt wird. Die Lösung von „komplikator“ hingegen hat definitiv lineare Laufzeit … was hier nicht sonderlich interessant ist, da die Eingabegrößen fest sind, aber es ist eben dadurch garantiert, dass jeder Funktionsaufruf gleichlange braucht.



  • Wenn du nicht gerade nen total beschissenen Zufallszahlengenerator hast, der immer nur das gleichen Muster liefert, dann kommt meine auch immer zu ner Lösung.



  • shorter schrieb:

    Wenn du nicht gerade nen total beschissenen Zufallszahlengenerator hast, der immer nur das gleichen Muster liefert, dann kommt meine auch immer zu ner Lösung.

    Du scheinst das Konzept von „Zufall“ nicht verstanden zu haben. 😉

    Es geht ja auch gar nicht darum, dass der Code tatsächlich „ewig“ läuft, aber ein paar Sekunden, statt ein paar Millisekunden für den anderen Code, sind schon realistisch. Außerdem geht es hier ja auch ums Prinzip (Eleganz …), und vom Prinzip her ist Dein Code eben mangelhaft, weil er sich auf trial & error verlässt.



  • Konrad Rudolph schrieb:

    shorter schrieb:

    Wenn du nicht gerade nen total beschissenen Zufallszahlengenerator hast, der immer nur das gleichen Muster liefert, dann kommt meine auch immer zu ner Lösung.

    Du scheinst das Konzept von „Zufall“ nicht verstanden zu haben. 😉

    Es geht ja auch gar nicht darum, dass der Code tatsächlich „ewig“ läuft, aber ein paar Sekunden, statt ein paar Millisekunden für den anderen Code, sind schon realistisch. Außerdem geht es hier ja auch ums Prinzip (Eleganz …), und vom Prinzip her ist Dein Code eben mangelhaft, weil er sich auf trial & error verlässt.

    Nicht mal sowas verrücktes braucht Sekunden, sondern nur Millisekunden

    srand(time(0));
    	std::set<int> bla;
    	for(int i=0; i<49; ){
    		if(bla.insert(rand()%49+1).second) {
    			i++;
    		}
    	}
    	std::copy(bla.begin(), bla.end(), std::ostream_iterator<int>(std::cout, " "));
    

    So ein verrücker Zufall 😃


Anmelden zum Antworten