QT C++ Random Zahlen / Koordinaten
-
Viele Dinge die ich als C++ Anfänger noch nicht gesehen habe.
Zeile 5 und 6 verstehe ich, dann 9 dann sozsagen nur das durchmischen aber warum am Ende nochmal rng? Kann mir aus der C++ doku gerade nichts sinnvolles zusammenreimen.
Aber wird die rnd Zahl jetzt in rng gespeichert?
-
@karooooo1234
Dieshuffle()
Funktion braucht noch einen RNG, um Zufallszahlen für´s Mischen zu ziehen. Sie erzeugt selbst keinen, sondern erwartet, dass der Aufrufer den RNG als Parameter übergibt. Die Zufallszahl wird nicht in rng gespeichert, sondern rng wird benutzt, um die nächste Zufallszahl zu erzeugen.
-
Wie speichere ich dann die Zufallszahl in einer varibalen? Ziehe ich mir einfach raus mit
int index = v[rng]?
Irgendwie checke ich es einfach nicht. Langer Tag..
-
eigentlich kann ich mit bei v[1] ja dann irgendeine stelle ausgeben lassen oder?
-
@karooooo1234
Nein, das machtshuffle
für dich. Nehmen wir mal wob´s Code:// globaler Generator std::mt19937 rng(std::random_device{}()); // globaler vector std::vector<int> v; void start_cycle() { v.resize( 100 ); std::iota(begin(v), end(v), 0); // durchmischen std::shuffle(begin(v), end(v), rng); } // der vector enthält jetzt alle Zahlen von 0-99 in zufälliger Reihenfolge. void fire() { if( v.empty() ) { // der Vektor ist leer -> neuen Zyklus beginnen start_cycle( v ); } // erstes Element benutzen int val = v.front(); v.erase( v.begin() ); // oder letztes Element benutzen int val = v.back(); v.erase( v.rbegin() ); // tu was mit val }
Jetzt solltest du nur noch zusehen, dass du die globalen Variablen loswirst.
-
vector::pop_back
anyone? Und es gibt bestimmt einen Grund, wieso vector nurpop_back
kennt, und nicht, wie manche andere Container,pop_front
…
-
@DocShoe sagte in QT C++ Random Zahlen / Koordinaten:
Jetzt solltest du nur noch zusehen, dass du die globalen Variablen loswirst.
Vielleicht mit einer Klasse?
struct FirepointGenerator { FirepointGenerator(size_t n_fields) : v(n_fields), current_pos(end(v)) { std::iota(begin(v), end(v), 0); } template <typename URBG> int next(URBG &rbg) { if (current_pos == end(v)) { std::shuffle(begin(v), end(v), rbg); current_pos = begin(v); } return *current_pos++; } private: std::vector<size_t> v; std::vector<size_t>::const_iterator current_pos; } int main() { std::mt19937 rng(std::random_device{}()); FirepointGenerator fpg(10); for (int i = 0; i < 25; ++i) cout << fpg.next(rng) << " "; }
-
Ja, vielleicht. Ich wollte TE jetzt nicht alles auf´m Silbertablett servieren.
Du solltest noch´n Test auf n_fields > 0 machen.
-
#include <random> std::random_device random_device; std::uniform_int_distribution<> uniform_int_distribution(min, max); int random_number = uniform_int_distribution(random_device);
-
Ich hab sowas: (?)
template <typename T> T createRandomReal(const T begin, const T end) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<T> rnd(begin, end); return rnd(gen); } template <typename T> T createRandomInt(const T begin, const T end) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<T> rnd(begin, end); return rnd(gen); }
-
@zeropage Ständig neue random devices und -generators zu erzeugen ist sicher nicht die feine Englische Art.
-
Also lieber sowas:?
namespace random { std::mt19937 randomGenerator; void setRandomDevice() // muss einmalig aufgerufen werden { std::random_device rd; std::mt19937 gen(rd()); randomGenerator = gen; } template <typename T> T createRandomReal(const T begin, const T end) { std::uniform_real_distribution<T> rnd(begin, end); return rnd(randomGenerator); } template <typename T> T createRandomInt(const T begin, const T end) { std::uniform_int_distribution<T> rnd(begin, end); return rnd(randomGenerator); } }
-
@zeropage sagte in QT C++ Random Zahlen / Koordinaten:
std::mt19937 randomGenerator; void setRandomDevice() // muss einmalig aufgerufen werden { std::random_device rd; std::mt19937 gen(rd()); randomGenerator = gen; }
Vielleicht wäre der mt19937 sogar Kandidat für ein Meyer-Singleton. (Nein, ich bin sonst generell kein riesiger Fan von Singletons.)
-
@Swordfish
Fehlt da nicht noch zweimal static? Ansonsten generiere ich pro Aufruf zwei Instanzen von std::random_device und std::mt19937.std::mt19937 randomGenerator; void setRandomDevice(std::mt19937) // muss einmalig aufgerufen werden { static std::random_device rd; static std::mt19937 gen(rd()); randomGenerator = gen; }
-
@Quiche-Lorraine sagte in QT C++ Random Zahlen / Koordinaten:
Fehlt da nicht noch zweimal static? Ansonsten generiere ich pro Aufruf zwei Instanzen von std::random_device und std::mt19937.
Kann du das genauer erklären? Verstehe nicht, wozu das static bei dir gut sein soll - das setRandomDevice soll hier ja nur 1x aufgerufen werden. Wozu musst du also das rd und eine Kopie des mt19937 behalten? Und wo generierst du "pro Aufruf zwei Instanzen von std::random_device und std::mt19937"? Und warum hast du (im Gegensatz zu @Swordfish vorher) jetzt einen unbenutzten Parameter in dem setRandomDevice?
Andererseits: ich verstehe den Vorteil dieses gesamten Codes sowieso nicht: man setzt fest mt19937 ein. Der ist zwar oftmals gut und ausreichend, aber vielleicht möchte man einen anderen Generator nutzen? Oder den mt19937 anders initialisieren? Und dann muss man sich für jede exisiterende Distribution hier jetzt eine eigene weitere Funktion mit anderem Namen merken? Also createRandomInt statt uniform_int_distribution. Ich würde gerne den Vorteil verstehen.
-
@Swordfish sagte in QT C++ Random Zahlen / Koordinaten:
@zeropage sagte in QT C++ Random Zahlen / Koordinaten:
std::mt19937 randomGenerator; void setRandomDevice() // muss einmalig aufgerufen werden { std::random_device rd; std::mt19937 gen(rd()); randomGenerator = gen; }
Vielleicht wäre der mt19937 sogar Kandidat für ein Meyer-Singleton. (Nein, ich bin sonst generell kein riesiger Fan von Singletons.)
Öm. Thread-safety?
Wobei das natürlich bei der Variante von @zeropage auch schon ein Problem ist.
Aber man könnte ein "thread local singleton" machen.
-
@wob @Quiche-Lorraine Das war nicht mein Code sondern ein Zitat von @zeropage s Post.
https://www.modernescpp.com/index.php/thread-safe-initialization-of-a-singleton
-
@Swordfish sagte in QT C++ Random Zahlen / Koordinaten:
https://www.modernescpp.com/index.php/thread-safe-initialization-of-a-singleton
War der Teil auf meinen Beitrag bezogen? Falls ja: Initialisierung reicht nicht, die Verwendung muss ja auch thread-safe werden.
-
@wob sagte in QT C++ Random Zahlen / Koordinaten:
Kann du das genauer erklären?
Sagen wir es mal so. Der Code in Kombination mit dem Schlagwort Singleton hat mich ein wenig verwirrst. Die Funktion setRandomDevice() hat eine gewisse Ähnlichkeit mit der Singleton::GetInstance() Funktion. Von daher kam der Gedanke mit static.
Und warum hast du (im Gegensatz zu @Swordfish vorher) jetzt einen unbenutzten Parameter in dem setRandomDevice?
Sorry, Copy & Paste Fehler vom Testen.