Random Generator, seed not working - c++

I want to create a class that will return a random number whenever I call it. But when I put it into a loop it returns the same random number each time. I am seeding it once but it still returns the same one over and over again. Its only when I close out of the program and open it again itll be different. Any help would be much appreciated.
**EDIT
When I cant see how I am calling it every time.
RadomGenerator rg = new...
for(int i =0; i<10; i++){
rg.createRandomNumber(1,5);}
Is this not instansiating the seed only once then calling the method createRandomNumber several times?
RandomGenerator::RandomGenerator()
{
seed = time(0);
}
int RandomGenerator::createRandomNumber(int start, int end)
{
std::function<int()> randomNumber = std::bind(std::uniform_int_distribution<int>(start,end),
mt19937(seed));
qDebug()<< "result" << randomNumber() ;
return randomNumber();
}

You're seeding it every single time.
#include <random>
struct RandomGenerator {
std::mt19937 _engine;
std::uniform_int_distribution<int> _dist;
RandomGenerator(int start, int end)
: _engine { std::random_device{} () },
_dist(start, end)
{
}
int createRandomNumber()
{
return _dist(_engine);
}
};
Note that it's actually not useful to create an instance of uniform_*_distribution for a single call either.
Let alone, wrapping that in a function<>.
You can usually use a
auto mygen = bind(, );
Instead of that whole class, and use it:
int this_is_random = mygen();
In C++14:
auto mygen = [ _engine = mt19937{ random_device{}() }, _dist = uniform_int_distribution<>(12, 42) ]() mutable {
return _dist(_engine);
};
See it Live On Coliru

Is this not instansiating the seed only once then calling the method createRandomNumber several times?
No. In this line you instantiate a mt19937 each time with the same seed:
std::function<int()> randomNumber = std::bind(std::uniform_int_distribution<int>(start,end),
mt19937(seed));

Related

Generating and printing random numbers using threads in C++

I'm currently working on a project which requires the use of threads. However, before tackling the project, I want to create a simple exercise for myself to test my understanding of threads.
What I have are 2x functions; one for infinitely generating random numbers and the other for printing the output of this function.
The value of this random number will be continuously updated via a pointer.
From my understanding, I will need a mutex to prevent undefined behavior when reading and writing values to this pointer. I would also need to detach the random number generator function from the main function.
However, I'm having issues trying to build the project in Visual Studio Code which I suspecting due to a flaw in my logic.
#include <bits/stdc++.h>
#include <iostream>
#include <thread>
#include <mutex>
std::mutex global_mu;
void generateRandomNum(int min, int max, int *number)
{
while (true) {
global_mu.lock();
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(min, max);
*number = uni(rng);
global_mu.unlock();
}
}
int main()
{
int *int_pointer;
int number = 0;
int_pointer = &number;
std::thread t1(generateRandomNum, 0, 3000, int_pointer);
t1.detach();
while(true) {
global_mu.lock();
std::cout << int_pointer << std::endl;
global_mu.unlock();
}
}
This looks wrong:
std::cout << int_pointer << std::endl;
You're trying to print the value of the pointer instead of printing the value of the int variable to which it points. You either should do this:
std::cout << *int_pointer << std::endl;
or this:
std::cout << number << std::endl;
This also looks like it maybe does not do what you want:
while (true) {
...
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(min, max);
*number = uni(rng);
...
}
You are constructing and initializing a new random number generator for each iteration of the loop. You probably should move the PRNG out of the loop:
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(min, max);
while (true) {
...
*number = uni(rng);
...
}
Finally, you probably should not ever do this:
while(true) {
global_mu.lock();
...
global_mu.unlock();
}
What's the very next thing that the thread does after it calls unlock()? The next thing it does is, it re-locks the same mutex again.
I don't want to get too technical, but the problem in this situation is that the thread that is most likely to acquire the mutex will be the one that just released it, and not the one that's been waiting for a long time. Whichever thread gets in to the mutex first, is going to starve the other thread.
The way out of the starvation problem is to only lock the mutex for the least amount of time necessary. E.g.,:
void generateRandomNum(int min, int max, int *number)
{
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(min, max);
while (true) {
int temp = uni(rng);
global_mu.lock();
*number = temp;
global_mu.unlock();
}
}
int main()
{
int *int_pointer;
int number = 0;
int_pointer = &number;
std::thread t1(generateRandomNum, 0, 3000, int_pointer);
t1.detach();
while(true) {
int temp;
global_mu.lock();
temp = number;
global_mu.unlock();
std::cout << temp << std::endl;
}
}
If this feels like you're writing a lot of extra lines, you're right. Multi-threading is hard to get right. And, in order to get high performance from a multi-threaded program, you are going to have to write extra lines of code, and maybe even make the program do more work per CPU than a single threaded program would do.

random number generator that doesn't repeat it self (cpp/c++)

I want to make a function that generates numbers but doesn't repeat it self. If every number is generated the array can be emptied and it can start over again.
This is the code I made but it doesn't work.
The comments in the code explains the code a little.
The largest number that is allowed is "howManyWords".
This is used to display words which are stored in an array
I want to use it like this: array\[random()\]
#include <stdio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
//public scope
int howManyWords; // how many words you have enter
int random(){
int random;
int numbers[howManyWords];
srand(time(0)); //changing the algorithm
random = rand() % howManyWords;
numbers[random] = random; // store the digit in the position in the array equal to the digit that is generated
for(int i=0; i<howManyWords; i++){ // going through every element in the array
if(numbers[i] == random){ // if the number is already generated, generate a different number
random = rand() % howManyWords;
}
}
return random;
}
Rather than your function, which discards the state of which numbers it has returned each time it is called, you should use a function object.
struct random_t {
random_t(int max) : values(max), current(max) {
std::iota(values.begin(), values.end(), 0);
}
template<typename URBG = std::random_device &>
int operator()(URBG&& urbg = default_random) {
if (current == values.size()) {
shuffle(std::forward<URBG>(urbg));
}
return values[current++];
}
private:
template<typename URBG>
void shuffle(URBG&& urbg) {
std::shuffle(values.begin(), values.end(), std::forward<URBG>(urbg));
current = 0;
}
std::vector<int> values;
std::vector<int>::size_type current;
static thread_local std::random_device default_random;
};
See it live

Improper usage of mutex c++

i have problem with my code. This function pushes a product into queue.
void producent(bool &cont,std::queue<std::string> &queue,std::mutex &mtx, int &milliseconds)
{
while (cont)
{
mtx.lock();
if (queue.size() >= MAX_QUEUE_SIZE)
{
mtx.unlock();
std::cerr << "buffor full " << std::endl;
}
else
{
std::string product = generate();
std::cerr << "producent: " << product << " " << std::endl;
queue.push(product);
mtx.unlock();
}
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
}
}
this function generates a string of 10 signs, which are pushed by void producent function().
std::string generate() {
std::string temp;
temp.resize(10);
for (int i = 0; i < 10; i++) {
temp[i] = rand() % ('z' - 'a' + 1) + 'a';
}
return temp;
}
My question is: why, when i create 2 threads like this:
std::thread prod(producent, std::ref(wykonuj),std::ref(kolejka), std::ref(kolejka_mtx),std::ref(t));
std::thread prod1(producent, std::ref(wykonuj), std::ref(kolejka), std::ref(kolejka_mtx), std::ref(t));
both of them give me same result, for example the outcome is:
producent: qweasdzxca
producent: qweasdzxca
i wanted those outcomes to be different, thats why i used mutex, but it didnt work. Can someone give me some advices?
rand doesn't share a seed between threads. Each thread has its own seed - but without explicitly setting it differently in both threads via srand(), it's going to be the same.
Hence, generate invoked by both threads will produce the same string.
The docs suggest rand_r is the thread safe version, but both functions are threads safe in modern implementations.
Assuming your implementation has a thread-safe rand() (probably unwise), both threads are using the same initial random seed (the default of 1, in this case), and thus producing the same sequence. Rather than doing that, embrace the the C++ <random> offerings, and as far as that goes, the uniform distribution offerings as well.
#include <algorithm>
#include <random>
#include <string>
std::string generate(int n=10)
{
std::mt19937 prng{ std::random_device{}() };
std::uniform_int_distribution<int> dist('a', 'z');
std::string result;
std::generate_n(std::back_inserter(result), n, [&]() { return dist(prng); });
return result;
}
Executed 10x on 10x threads, this produced:
ysudtdcaeq
hwpeyiyyav
dlsdshltyo
pkfafhooxr
nmoxerbqpy
ydauzdvoaj
brjqjgxrgg
ezdsmbhygb
fpdgbkxfut
elywaokbyv
That, or something similar, should produce what you seek.
Note: the above will not work as-expected on platforms where a..z is non-contiguous. If you're on such a beast (typically OS/400 or OS/390 EBCDIC), an alternate solution is required.

How to design a function with an optional random seed argument to be passed to mt19937 [duplicate]

This question already has an answer here:
Default NULL parameter Rcpp
(1 answer)
Closed 4 years ago.
In R I can build the following roll_die(seed = NULL) function that returns a random integer between 1 and 6, and it allows the option of specifying a seed for the RNG.
roll_die_r <- function(seed = NULL){
# Returns a random number between 1 and 6
# Optionally specify a RNG seed
set.seed(seed)
return(sample(x = 1:6, size = 1L))
}
This is nice because I can call it with the default seed = NULL and get back a random value or I can call it with a specified seed value so that I can get reproducible results.
roll_die_r() # random
roll_die_r(seed = 0) # always returns 6
How do I implement the same thing in c++ using mt19937? The best I can come up with is
#include <Rcpp.h>
#include <random>
using namespace Rcpp;
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
int roll_die_cpp(int seed = -1){
// Returns a random integer between 1 and 6
// Optionally specify a RNG seed
std::mt19937 mt;
// Seed the RNG
if(seed == -1) seed = std::random_device{}();
mt.seed(seed);
std::uniform_int_distribution<int> dist(1, 6);
int result = dist(mt);
return result;
}
But this is not ideal because the user might accidentally call roll_die_cpp(seed = -1) and expect to get back a reproducible result which is not the case.
roll_die_cpp() # random
roll_die_cpp(seed = 0) # always returns 5
roll_die_cpp(seed = -1) # random
My question is not specifically about the roll_die() method or random number generators - it's more about the function design. In R I often use functions with default parameters set to NULL but I don't know how to accomplish the same thing in c++.
UPDATE:
Here's another example of what I'm getting at.
R function
return_0 <- function(msg = NULL){
if(!is.null(msg)) print(msg)
return(0L)
}
return_0() # doesn't print a message
return_0("hello world") # prints hello world
cpp function
// [[Rcpp::export]]
int return_0_cpp(std::string msg = "don't print"){
if(msg != "don't print") Rcpp::Rcout << msg;
return(0);
}
return_0_cpp() # doesn't print a message
return_0_cpp(msg = "hello world") # prints hello world
return_0_cpp(msg = "don't print") # doesn't print a message
Notice how awkward return_0_cpp() is. What's a clean way of doing in cpp what I've created in R?
In R I often use functions with default parameters set to NULL but I don't know how
to accomplish the same thing in c++.
std::optional (since C++17) is made for optional values:
#include <iostream>
#include <optional>
void fun(std::optional<int> v = std::nullopt) {
if (v) {
std::cout << "value passed = " << v.value();
} else {
std::cout << "no value passed";
}
}
int main(){
fun();
fun(4);
}
As a sidenote: I would be careful with making the same function do two different things depending on the number of parameters passed. One could argue that
dice.seed(0);
auto x = dice.roll();
is more explicit and readable than
auto x = dice.roll(0);
I often use a header only library that works something like this (much much simplified):
namespace ran {
inline std::mt19937& generator()
{
thread_local static std::mt19937 mt{std::random_device{}()};
return mt;
}
template<typename Integral>
void seed(Integral n)
{
generator().seed(std::mt19937::result_type(n));
}
template<typename Integral>
Integral number(Integral min, Integral max)
{
using dist_type = typename std::uniform_int_distribution<Integral>;
thread_local static dist_type dist;
return dist(generator(), typename dist_type::param_type(min, max));
}
} // namespace ran
Using thread_local static ensures thread safety while keeping performance. It reuses the same random number generator seeding it just once at the beginning or you can re-seed it at any time with a specific value.
int main()
{
for(auto i = 0; i < 10; ++i)
std::cout << ran::number(3, 9) << ' ';
std::cout << '\n';
ran::seed(5);
for(auto i = 0; i < 10; ++i)
std::cout << ran::number(3, 9) << ' ';
std::cout << '\n';
}

Execute code x percent of the time

I have an animal that lives in a while loop for many days.
At the end of the day, there is a 40% chance she gives birth,
class Animal
{
public:
double chance_of_birth;
...
public Animal(..., int chance)
{
this.chance_of_birth = chance;
...
}
}
// create this animal
Animal this_animal = new Animal(..., .50);
Given that every animal I create can have a specific chance of giving birth,
how can I write a condition that evaluates true only chance_of_birth percent of the time?
I know I want to use rand(), but I never used it like this before.
Along the lines of
if(this_animal->chance_of_birth ???)
{
//will give birth
}
Since c++11 you can use the library <random>. In the example below I'm using std::uniform_real_distribution<> to generate a random floating point value within the range 0 - 1
#include <iostream>
#include <random>
using namespace std;
double random(int min, int max)
{ // we make the generator and distribution 'static' to keep their state
// across calls to the function.
std::random_device rd;
static std::mt19937 gen(rd());
static std::uniform_real_distribution<> dis(min, max);
return dis(gen);
}
int main()
{
double f = random(0,1); // range 0 - 1
cout << f << '\n';
}
Now you can use that random floating point value in an if statement to run only when a condition is true.
if (f <= 0.40) { ... }