I have a for loop, and inside it I'm generating random numbers and seeding it with time(msecs),but it's not generatin them randomly, what can I do to solve that?
note:
I know why rand() is not generating them randomly, I'm asking for the solution, and I'm using Qt creator if that will help.
for(int j=0;j<5;j++){
qsrand(QDateTime::currentDateTime().time().msec());//for every j itteratio i must
for(int i=1;i<s;i++){ //have new sequence and ret is
ret.push_back(rand()%s); //vector i'm using Qt
} //s=4 for now,but s=[1;50]
qDebug()<<"new sequence ...";
}
it generates
[2,1,1],[2,1,1],[2,1,1],[2,1,1],[2,1,1];
Depends of what is you application.
If you need to generate secure random numbers that can't be guessed, then you should use CSPRNG https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator.
For this purpouse there is /dev/urandom availabe for unix clones.
In case you need random numbers for simulation or something similar where you need random numbers you should use high quality super fast, random and large PRNG called mersenne twister.
It is available in standard library of c++11 or in boost. (headers only)
http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_random.html
As many other said, make sure you seed only once.
If you want a long sequence of random numbers, like here, then you probably want to use a pseudo-random number generator (unless this is for cryptography!). C++11 brought support for random and pseudo-random numbers into the standard library, which makes it very easy to use. Just seed the PRNG with a true random number before the loop, then just use the output from that to get (pseudo-)random numbers. You will also need to include the random header.
std::random_device rd;
std::default_random_engine e1{rd()};
std::cout << e1(); // random number
std::cout << e1(); // another random number
std::uniform_int_distribution<> dist{1, 6};
std::cout << dist(e1); // random integer between 1 and 6
If this is for cryptographical uses, see what Luka Rahne said.
Related
I want to use a random-number-generator in c++ to make a maths quiz with randomly-generated numbers.
My problem is that using time(0) is only accurate to a single second. In the IDE that I am using (NetBeans 8.2), a message appeared when hovering over srand(time(0)) with the message:
This is a weak random number generator; it is not useful for security purposes. Alternative: getrandom(void *buf,size_t buflen, unsigned int flags);/dev/urandom;
I could not find anything online about getrandom. I was wondering if anyone could shed some light on the syntax of getrandom? How to use it?
You should stop using srand / rand since these are old ways of generating random numbers. Since C++11, there is a random standard library:
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 100);
// To generate a number:
dis(gen);
Quick explanation:
std::random_device is a random generator that can produce non-deterministic random numbers.
std::mt19937 is a specific instantiation of a Mersenne Twister engine to generate pseudo-random numbers.
std::uniform_int_distribution is a uniform number distribution. Here I generate number between 0 and 100 (included).
std::rand is also a pseudo-random number generator, but the random engine is implementation-defined, and you need to use srand to initialize it:
// Call srand once at the beginning of the program:
srand(time(0));
// Then you use rand() without (usually) calling srand() again:
rand();
rand();
But as you noticed, std::time usually returns a number of seconds, so if you run your program twice in a second, you will probably get the same output.
getrandom is a non-standard function (maybe POSIX?), there is really no needs to use it for a game now that the random standard library is available.
I am writing a code for a game with seven dices and I have a problem. If I use a random function(dice = rand()%6 + 1) I realized the probability to get for instance a sequence such as 123456 (a sequence that makes points in my game) has a much higher probability to get out.
Mathematically, this sequence has 1.54% probability to show up but When I use a random function with 100 millions iterations it appears up to 5.4% of the time!
That leads me to my question. Do you know another way I could randomize the dice so that they would respect the probability? Or a way to fix that problem anyway?
Thanks in advance!
The problem you are facing is well known and a very natural result of using the modulo operator with random.
C++11 solves these problems by providing not only uniformly distributed random numbers but several different types of distributions like the Bernoulli distribution, the normal distribution and the Poisson distribution.
The new header providing all these generators and distributions is random.
Let's do an example: We want do have a random number generator that gives us some numbers and we want to have a distribution that shapes these numbers as we want them (uniformly, Bernoulli ...).
#include <iostream>
#include <random>
int main(){
std::mt19937(6473); // The random number generator using a deterministic seed
std::uniform_int_distribution<int> dist(1,6); // The distribution that gives us random numbers in [1, 6)
for(int i=0;i<10;i++){
std::cout << dist(mt) << std::endl;
}
}
This gives us pseudo-random numbers uniformly distributed into an interval we chose! But C++11 provides even more! It provides a real random number generator (see implementations for more details) which we can use as follows:
#include <iostream>
#include <random>
int main(){
std::random_device rd;
std::mt19937 mt(rd()); // The random number generator using a non-deterministic random device
std::uniform_int_distribution<int> dist(1,6); // The distribution that gives us random numbers in [1,6)
for(int i=0;i<10;i++){
std::cout << dist(mt) << std::endl;
}
}
It is this easy to provide real high quality random numbers distributed as you want into and interval you want using C++11. I got the knowlege about this topic from a talk of Stephen T. Lavavej (STL) held at GoingNative 2013 that you can watch on Channel 9 and that is called rand() Considered Harmful.
Fun fact: The title is a reference to an essay from the great Edsger Wybe Dijkstra called "Go to considered harmful." in which Dijkstra explained why no programmer should use the goto statement.
If you want some good random numbers using the boost library random function is a good place to start. Also has the example of working with dice like you are asking. http://www.boost.org/doc/libs/1_61_0/doc/html/boost_random.html
I used default_random_engine to generate a list of different numbers, but they happen to be the same. I wonder to generate different numbers? I know srand() does. But can I use this default engine?
default_random_engine engine{ static_cast<unsigned int>(time(0)) };
uniform_real_distribution<double>randomNumber{ 50,100 };
for(int i=0; i<10;i++){
a[i]= randomNumber(engine);
}
That behavior is by design for random number generators. You need to set the 'seed' for the random generator when you start your program.
If you have the C++ extensions #WhozGraig recommends they're best. It's very sloppy but many people use the time() function to get a different number each time the program runs.
I'm trying to find a random number generator that will give me a single random number each time I run it. I have spent a week trying dozens of different ones, both from this site and others. Every time I run it, it gives me the same number! The only time it changes is if I change the range, and then it just gives me the new number over and over.
I am running Code::Blocks ver. 16.01 on Windows 7. Can anyone help?? I'm at my wits' end!
This code gives me a decently ramdom string of numbers, but still the same string each time!
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 eng(rd()); std::uniform_int_distribution<> distr(0, 10);
for(int n=0; n<100; ++n)
std::cout << distr(eng) << '\t';
}
I have tried the code on my compiler app on my phone as well.
Every pseudo random number generator will return the same sequence of numbers for the same initial seed value.
What you want to do is to use a different seed every time you run the program. Otherwise you'll just be using the same default seed every time and get the same values.
Picking good seeds is not as easy as you might think. Using the output from time(nullptr) for example still gives the same results if two copies of the program run within the same second. Using the value of getpid() is also bad since pid values wrap and thus sometimes you'll get the same value for different runs. Luckily you have other options. std::seed_seq lets you combine multiple bad sources and returns a good (or rather, pretty good) seed value you can use. There is also std::random_device which (on all sane implementations) returns raw entropy - perfect for seeding a pseudo random generator (or you can just use it directly if it is fast enough for your purpose) or you can combine it with std::seed_seq and the bad sources to seed a generator if you are worried it might be implemented as a prng on your implementation.
I would advice you to read this page: http://en.cppreference.com/w/cpp/numeric/random for an overview of how to deal with random number generation in modern C++.
The standard allows std::random_device to be implemented in terms of a pseudo-random number generator if there is no real random source on the system.
You may need to find a different entropy source, such as the time, or user touch co-ordinates.
I've been searching for a better solution than my own and I haven't really been able to find one that I understand or that works for me.
I have made the simple game where the computer randomly generates a number which you then guess a number and if it is higher the computer says higher and so on..
The problem is my randomly generated number, after looking up alot of information regarding the <random>, uniform_int_distribution and default_random_engine. I have found out that the computer generates a random number, but if you run the program again the same random number will be generated.
My solution:
uniform_int_distribution<unsigned> u(0,100); // code to randomly generate numbers between 0 and 100
default_random_engine e; // code to randomly generate numbers
size_t userInput; // User input to find out where to look in the vector
vector<int> randomNumbers; //vector to hold the random numbers
unsigned start = 0, ending = 101, cnt = 0; // used in the game not important right now
cout << "Please enter a number between 1 and 1000 for randomness" << endl;
cin >> userInput;
for(size_t i = 0; i < 1000; ++i){ //for loop to push numbers into the vector
randomNumbers.push_back(u(e));
}
unsigned guess = randomNumbers[userInput]; // finally the number that the user will have to guess in the game
My solution right now is to use a vector where I push alot of randomly generated numbers in then ask the user to type a number which then the computer uses for the game. But there should be a better way of doing this. And my question is therefore
Is there a better way to randomly generate numbers to use in the game?
Either use std::random_device in place of std::default_random_engine, or else think of a way to provide a different number to the engine each time it is run.
This number is called a "seed" and can be passed as an optional parameter to the constructor. Since std::default_random_engine is implementation-specific, and different engines do different things about seeding, you generally want to choose a specific engine if you're providing a seed. A deterministic pseudo-random number generator will produce the same sequence of outputs for any given seed, so you want to use a different seed each time.
For no-security uses like a guessing game, the most "obvious" thing to use as a seed is the current time. Generally speaking this is different each time the program is run, although obviously if you can run the program twice in less than the granularity of the clock then that's not the case. So using the time to seed your random engine is pretty limited but will do the job for a toy program.
That's because your random number is actually what we call a pseudorandom number generator
It's just a machine that given a starting number generates a large list of seemingly random numbers. As you don't provide a starting number, the generated list of random numbers is thus always the same. One easy way to fix this is to use the current time as a starting value or 'seed', which is an argument of the constructor of std::default_random_engine.
You can also use your machines real random number generator std::random_device as a replacement for std::default_random_engine
Why not simply:
#include <ctime> // for time()
#include <cstdlib> // for srand()
srand(time(NULL)); // Initializes the rand() function
int randomNumber = rand()%100; // Random number between 0 and 99.
What this does is the rand() seed is set at the current time, meaning that every execution of the program will have a different seed for rand().
Still just pseudo-random solution, though suitable for your purposes.