srand() will nicht so wie ich will
-
Schönen Nachmittag an euch alle
Ich muss für die Uni etwas in C++ programmieren und komme an einer Stelle echt nicht weiter, deswegen dachte ich ich frage mal hier nach.
Es geht um eine Funktion die zufällig Flugzeuge generieren soll, eben mit zufälligem Tankinhalt und einer zufälligen Flugnummer. Diese soll dann als Vektor übergeben werden:vector<int> hilfsv::gzeit(int o) { srand(time(NULL)); vector<int> flugzeug; flugzeug.clear(); if(flip(20) == true){ flugzeug.push_back(zufall(20000)); flugzeug.push_back(zufall(99)+1); flugzeug.push_back(o); } return flugzeug; }Dabei sieht die Funktion zufall so aus:
int hilfsv::zufall(int z) { srand(time(NULL)); int zufallszahl = 0; zufallszahl = rand()%z; return zufallszahl; }flip ist einfach nur eine Funktion die einen Münzwurf simuliert. Die Idee dahinter ist dass in der main eine Schleife durchläuft die die Zeit darstellt. Bei jedem Schleifendurchlauf wird mit einer (in diesem Fall 20%igen) Wahrscheinlichkeit ein Flugzeug generiert, welches danach eben übergeben wird.
Das Problem ist, dass bei jedem Schleifendurchlauf nur einmal ein Flugzeug entsteht (oder eben nicht) und wenn es entsteht bei jedem Durchlauf die selben Eigenschaften (also Tank und FlugNr. hat)
Weiß einer von euch weiter?

-
Die Funktion
srand(..)soll nur ein einziges Mal (am besten irgendwo am Anfang in dermainFunktion) aufgerufen werden, dennsrandinitialisiert dein Random Seed.Allgemein ist
randnicht die beste Methode, um Zufallszahlen zu generieren. Schau dir mal Pseudo-random number generation an.Deine if-Abfrage ist auch etwas merkwuerdig. Wenn du ganze Zufallszahlen im Bereich [1,..,N] erzeugen willst kannst du eifach
rand() % N + 1verwenden (sind dann allerdings nicht wirklich uniform verteilt, ist fuer dein Programm aber wohl kein Problem).
-
Die if Abfrage sorgt einfach nur dafür dass nicht bei jedem Schleifendurchlauf ein Flugzeug generiert wird.
Das srand(time(NULL)) sollte also in die main? Wieso kann ich es nicht in der Klasse lassen?
Und es müsste doch eigentlich auch erstmal mit der rand() Funktion funktionieren (auch wenn die Zufallszahlen dann nicht wirklich zufällig verteilt sind, aber das sei mal dahingestellt). Aber selbst wenn ich innerhalb der Funktion eine Schleife erzeuge sind die Zufallszahlen immer gleich:vector<int> hilfsv::gzeit(int o) { int i; vector<int> flugzeug; flugzeug.clear(); for(i=0; i<10; i++) { flugzeug.push_back(rand()%20000); flugzeug.push_back(rand()%100 + 1); flugzeug.push_back(o); cout << "8:00" << ": Ein Flug mit der Flugnummer " << flugzeug[0] << " und " << flugzeug[1] << "% Tankfuellung kommt an!" << endl; } return flugzeug; }(Die Funktion wird gerade in der main aufgerufen. Das srand(time(NULL)) steht gerade ganz am Anfang in der main.)
Aber danke schonmal für die schnelle Hilfe

-
MrMeikkel schrieb:
Die if Abfrage sorgt einfach nur dafür dass nicht bei jedem Schleifendurchlauf ein Flugzeug generiert wird.
Ach, haette deine Frage genauer lesen sollen.
MrMeikkel schrieb:
Das srand(time(NULL)) sollte also in die main? Wieso kann ich es nicht in der Klasse lassen?
Wie bereits gesagt soll
srandnur einmal aufgerufen werden. Gibt keinen Grund das in die Klasse zu stecken (was wenn du mehrere Klassen hast, dierandbrauchen, in welcher Klasse rufst du dannsrandauf?).MrMeikkel schrieb:
Und es müsste doch eigentlich auch erstmal mit der rand() Funktion funktionieren (auch wenn die Zufallszahlen dann nicht wirklich zufällig verteilt sind, aber das sei mal dahingestellt).
Ja klar, hier ist das sicher kein Problem. Aber ist immer gut zu wissen, dass es noch im Allgemeinem bessere Moeglichkeiten gibt

MrMeikkel schrieb:
Aber selbst wenn ich innerhalb der Funktion eine Schleife erzeuge sind die Zufallszahlen immer gleich:
vector<int> hilfsv::gzeit(int o) { int i; vector<int> flugzeug; flugzeug.clear(); for(i=0; i<10; i++) { flugzeug.push_back(rand()%20000); flugzeug.push_back(rand()%100 + 1); flugzeug.push_back(o); cout << "8:00" << ": Ein Flug mit der Flugnummer " << flugzeug[0] << " und " << flugzeug[1] << "% Tankfuellung kommt an!" << endl; } return flugzeug; }(Die Funktion wird gerade in der main aufgerufen. Das srand(time(NULL)) steht gerade ganz am Anfang in der main.)
Der Code sieht eigentlich in Ordnung aus. Kannst du ein minimales, kompilierbares Beispiel posten? (Im Notfall den ganzen Code, wenns nicht zu viel ist).
*Edit
Dasflugzeug.clearbrauchst du uebringens nicht.
-
MrMeikkel schrieb:
vector<int> hilfsv::gzeit(int o) { int i; vector<int> flugzeug; flugzeug.clear(); for(i=0; i<10; i++) { flugzeug.push_back(rand()%20000); flugzeug.push_back(rand()%100 + 1); flugzeug.push_back(o); cout << "8:00" << ": Ein Flug mit der Flugnummer " << flugzeug[0] << " und " << flugzeug[1] << "% Tankfuellung kommt an!" << endl; } return flugzeug; }Du schiebst hier 30 Werte in den Vektor (10 mal 3), aber mittels cout gibst Du immer nur dieselben (die ersten beiden) aus ...

-
Also im Prinzip wird gerade nur folgendes aufgerufen:
#include <iostream> #include <cstdlib> #include <time.h> #include <vector> #include <queue> using namespace std; int main() { srand(time(NULL)); int i; vector<int> flugzeug; flugzeug.clear(); for(i=0; i<10; i++) { flugzeug.push_back(rand()%20000); flugzeug.push_back(rand()%100 + 1); flugzeug.push_back(1); //normalerweise wird hier die globale Zeit übergeben bei der das Flugzeug generiert wurde cout << "8:00" << ": Ein Flug mit der Flugnummer " << flugzeug[0] << " und " << flugzeug[1] << "% Tankfuellung kommt an!" << endl; } return 0; }Erzeugt bei mir immer dieselben Tankfüllungen und Flugnummern.
-
Ach Gott, natürlich kann das nicht funktionieren, danke Belli

Und gerade wollte ich den Code posten und habe alle Änderungen die ich zum testen gemacht hab rückgängig gemacht, jetzt funktioniert alles wie es soll

Danke für eure Hilfe auf alle Fälle
-
Mach mal ein flugzeug.clear() in die Schleife rein

*Edit
Wups, zu spaet.
-
MrMeikkel schrieb:
Das srand(time(NULL)) sollte also in die main? Wieso kann ich es nicht in der Klasse lassen?
Weil damit der Generator auf einen Startwert gesetzt wird.In diesem Fall ist es eine Anzahl Sekunden seit einem Startpunkt.
Also änderst sich der Startwert nur jede Sekunde. Das Programm ist aber viel schneller und erzeugt somit viele gleiche Werte.
Da es sehr selten ist, dass das Programm mehrmals innerhalb von derselben Sekunde gestartet wird, gibt es bei jedem Programmlauf eine andere Reihenfolge der Zufallswerte (so der Idealzustand).
-
Schau dir dieses Video an, wenn du wissen willst, warum du am besten auf rand verzichtest du wie es besser geht: https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful