6 Richtige Berechner optimieren
-
Hi,
Ich wollt malwieder ein bisschen in die Vectorgeschichte reinkommen und habe daher ein kleines Progrämmchen gebaut:Es generiert solange 6 Zufallszahlen von 1 - 49 bis es 15 mal mit vorher eingegebenen 6 übereinstimmt.
Sprich es berechnet wielange man mit den Zahlen brauchen würde bis man 6 richtige im Lotto hat.
Das Programm scheint zu funktionieren, zumindest bekomme ich am Ende immer einen Durchschnitt so um die 14 Millionen raus, was rein rechnerisch richtig ist.
Allerdings braucht das Programm fast 5 Minuten auf meinem 1,8 ghz Rechner und ich wollt mal zwecks Lerneffekt fragen wie ich das ganze beschleunigen kann.#define WIE_OFT_GEWINNEN 15 // wie oft 6 richtige bekommen um zu beenden #include <conio> #include <vector> #include <iostream> #include <algorithm> // Include algorithms using namespace std; int main(int argc, char* argv[]) { randomize(); vector<char> zahlen; zahlen.clear(); // Die 6 Zahlen mit denen geraten wird zahlen.push_back(34); zahlen.push_back(2); zahlen.push_back(45); zahlen.push_back(12); zahlen.push_back(8); zahlen.push_back(27); sort(zahlen.begin(), zahlen.end()); bool done = false; vector<char> ziehung; unsigned long versuche = 0; vector<long> versuche_puffer; for(char k = 0; k < WIE_OFT_GEWINNEN; k++) { done = false; while(!done) { ziehung.clear(); for(char i = 0; i < 6; ++i) { ziehung.push_back(random(49)+1); // Zufallszahlen von 1 - 49 } sort(ziehung.begin(), ziehung.end()); bool doppelt = false; for(char i = 0; i < 5; ++i) { if(ziehung[i] == ziehung[i+1]) // eine Zahl ist doppelt vorhanden { doppelt = true; break; } } if(!doppelt) { bool gleich = 1; ++versuche; for(int i = 0; i < 6; ++i) { if(ziehung[i] != zahlen[i]) { gleich = 0; break; } } if(gleich) { done = 1; } } } long alles_schnitt = 0; versuche_puffer.push_back(versuche); for(unsigned int i = 0; i < versuche_puffer.size();i++) { alles_schnitt += versuche_puffer[i]; } alles_schnitt = alles_schnitt / versuche_puffer.size(); cout << "Versuche: " << versuche << ", Schnitt: " << alles_schnitt << endl; versuche = 0; } getch(); return 0; }
-
1. Leg Dir ein bool-Array mit 49 Werten, wo du reinschreibst, welche random-Zahl schon gezogen wurde. Das erspart Dir die sowieso falsche Suche nach doppelten Werten.
2. Leg Dir ein 2. bool-Array mit den zu testenden Werten an.
3. Du kannst einen Vergleich auf Treffer sogar mit memcmp erledigen[ Dieser Beitrag wurde am 17.06.2003 um 12:27 Uhr von RenéG editiert. ]
-
gute Idee
aber mehr als 10% hat das auch nicht gebracht:#define WIE_OFT_GEWINNEN 15 // wie oft 6 richtige bekommen um zu beenden #include <conio> #include <vector> #include <iostream> #include <algorithm> using namespace std; int main(int argc, char* argv[]) { randomize(); vector<char> zahlen; zahlen.clear(); // Die 6 Zahlen mit denen geraten wird static bool vorgabe[50]; vorgabe[34] = true; vorgabe[2] = true; vorgabe[45] = true; vorgabe[12] = true; vorgabe[8] = true; vorgabe[36] = true; bool done = false; bool ziehung[50]; unsigned long versuche = 0; vector<long> versuche_puffer; for(char k = 0; k < WIE_OFT_GEWINNEN; ++k) { done = false; while(!done) { ++versuche; //for(int i = 0; i < sizeof(ziehung);++i)ziehung[i] = false; memset(ziehung,0,sizeof(ziehung)); for(char i = 0; i < 6; ++i) { int zahl = random(49)+1; if(ziehung[zahl] == true) { --i; // zahl doppelt } else ziehung[zahl] = true; } if(memcmp(ziehung, vorgabe, sizeof(ziehung)) == 0) { done = true; } } long alles_schnitt = 0; versuche_puffer.push_back(versuche); for(unsigned int i = 0; i < versuche_puffer.size();++i) { alles_schnitt += versuche_puffer[i]; } alles_schnitt = alles_schnitt / versuche_puffer.size(); cout << "Versuche: " << versuche << ", Schnitt: " << alles_schnitt << endl; versuche = 0; } getch(); return 0; }
-
Mit fast keiner Textausgabe und einem Durchschnitt von 12,6Mio und ein wenig Optimierung komme ich auf ca. 15 Sekunden auf einem Athlon 1,2GHz
-
na ok 10% war vieleicht etwas untertrieben der war nur beim ersten Durchlauf etwas hoch gelaufen, aber 3 Minuten braucht der bei mir wirklich für die 15 Versuche locker wenn er nicht grad verdammt viel Lottoglück hat.
-
Probier mal folgendes:
#include <stdlib.h> #include <time.h> #define WIE_OFT_GEWINNEN 15 // wie oft 6 richtige bekommen um zu beenden typedef unsigned long ULONG; #define PROGRESS //#define LPROGRESS int main(int argc, char* argv[]) { bool zahlen[49], ziehung[49]; char cZiehung[6]; ULONG versuche_puffer[WIE_OFT_GEWINNEN]; // Die 6 Zahlen mit denen geraten wird memset( zahlen, 0, 49*sizeof(bool)); memset( ziehung, 0, 49*sizeof(bool)); memset( cZiehung, 0, 6*sizeof(char)); zahlen[34] = zahlen[2] = zahlen[45] = zahlen[12] = zahlen[8] = zahlen[27] = true; randomize(); for(ULONG k=1; k<=WIE_OFT_GEWINNEN; k++) { ULONG versuche = 0; while( true) { bool bFound = true; for( int i=0; i<6; i++) { loop: const char rd = (rand()*49)>>15; // Zufallszahlen von 0 - 48 if( ziehung[rd] == true) goto loop; if( zahlen[rd] == false) { bFound = false; break; } ziehung[rd] = true; cZiehung[i] = rd; } // rücksetzen ziehung[cZiehung[0]] = ziehung[cZiehung[1]] = ziehung[cZiehung[2]] = ziehung[cZiehung[3]] = ziehung[cZiehung[4]] = ziehung[cZiehung[5]] = false; versuche++; #ifdef LPROGRESS if( (versuche%3000000) == 0) printf( "Versuche: %d\n", versuche); #endif if( bFound) break; } versuche_puffer[k-1] = versuche; #ifdef PROGRESS ULONG alles_schnitt = 0; for(ULONG i=0; i<k; i++) alles_schnitt += versuche_puffer[i]; alles_schnitt /= k; printf( "Versuche: %d, Schnitt: %d\n", versuche, alles_schnitt); #endif } ULONG alles_schnitt = 0; for(ULONG i = 0; i < k; i++) alles_schnitt += versuche_puffer[i]; alles_schnitt /= k; printf( "Schnitt: %d\n", alles_schnitt); return 0; }
Musst halt bloss printf wieder durch cout ersetzen.
-
jo, rattert fleissig runter *beeindrucktsei*.
Und was wars jetzt? das ich jedesmal memset auf die 64 gemacht hab? Sonst war da doch auch nimmer viel was Leistung kostet ausser dem rand auf das man ja nicht verzichten kann.
-
Und was wars jetzt?
Zur richtigen Zeit ein break wirkt öfter Wunder als man denken mag!
-
noch schneller sollte es gehen, wenn man statt eines array die bit aus 2 32bit integer oder einen 64bit integer nutzt.