Rand() and for loops

Started by
5 comments, last by Bregma 15 years, 11 months ago
Yeah i know rand as a random number generator sucks. It really, really does but i'm not looking for true random numbers just something give's me something appears random. Have this rather convulated code.

for (int i=0; i<5; i++)
{
   AI.ptype= agents.agentPersonality();
}
which leads to

int agent::agentPersonality() {

	personalityType=emote.eStates();

	happiness=emote.emotionPass.happiness;
	sadness=emote.emotionPass.sadness;
	anger=emote.emotionPass.anger;
	fear=emote.emotionPass.fear;
	surprise=emote.emotionPass.surprise;
	disgust=emote.emotionPass.disgust; 
	
	return personalityType;
	
}
when then leads to


int emotions::eStates() {

	switch (Type.MBTI())
	{
		case 1: //ISTJ
			emotionPass.happiness=0.05;
			emotionPass.sadness=0.04;
			emotionPass.anger=0.05;
			emotionPass.fear=0.04;
			emotionPass.surprise=0.02;
			emotionPass.disgust=0.03;
			return Type.MBTI();
			break;
.
.
.
and finally from there to here


int personality::MBTI() {


	srand ( time(NULL) );


	EI = rand()%2;
	SN = rand()%2;
	TF = rand()%2;
	JP = rand()%2;

<code that creats type here>

return type;
So as we see it's jumps from one class to the next and at the end gives me the exact same number for for loops. I tried incresing the time but it's still rather poor. I'm looking for anything that'll just give me 5 "random" numbers, don't care about true random, and preferably I'd rather not use some kind of sleep function. Any help would be appreciated ^^
Advertisement
The answer is simple. Only call srand once in your program. This is usually done early on in your main function before you get to loops.

edit: and now that I ensured I answered first here's an explanation.

As you may know the result of calling rand is deterministic based on the seed. If you give a seed of 456765 then the next set of random numbers returned will always be the same. So in order to prevent the same numbers being called we give a seed that will be different every time we run the program. However, you are giving new seeds probably several(hundred) times a second. But what are you seeding the number generator with? The time, right? The time only updates once a second so you keep getting the same seed.

Hope that helps.

edit2: if you want to know exactly how rand works, just read this.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

...

I'm an idiot.

your a Legend.

Thanks.
Yep. :)


More specifically, srand seeds the random generator. Every time you seed with the same value, you get the same sequence of "random" numbers.

So if you call srand before every time you call rand, you're restarting the sequence before you read a number from it.

Now, if you seed with a different number every time this might be tolerable (it's still a bad idea, for all sorts of reasons, but it might give you somewhat random-looking numbers out still).

But time() usually has a resolution of 1 second. Which means that for an entire second, every call to time() returns the same, which means you seed the random generator with the same value every iteration for an entire second.

You're "supposed" to seed it once, and then just call rand() from that point on.

Only call srand again if you need to "reset" the sequence (for example if you want to play back a recording of the last 5 minutes, you might seed with the same value used 5 minutes ago, so you "replay" the same sequence of pseudorandom numbers.
Any "decent" random number generators out there that isn't a whole program in itself?
i.e. less that 10 lines of code :p
Quote:Original post by GLGunblade
Any "decent" random number generators out there that isn't a whole program in itself?
i.e. less that 10 lines of code :p


There are several pseudorandom number generators out there, and the development of true random number generators is an entire discipline of its own. Unless you're doing cryptology for the government, rand() is going to be good enough for most purposes.

Typically PRNGs use a pattern like this:

//pseudocodePRNG(x=seed) {  seed = f(x);  return seed;}


Where f(x) is usually some polynomial function of x where the coefficients are very large numbers. Prime numbers are preferred because they reduce periodicity. There's really no reason to write your own unless you need a specialized function that takes more than one seed number, or you require more than one sequence of random numbers.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Quote:Original post by GLGunblade
Any "decent" random number generators out there that isn't a whole program in itself?
i.e. less that 10 lines of code :p

I can recommend the suite of PRNGs that come with C++ tr1. The (optional) standard tr1 library is available for most important C++ compilers now (at least, GCC, MSVC++, and the EDG-based compilers all provide it). The PRNGs that come with GCC's tr1 were loving coded and ardently tested by someone who frequently reads this very forum, so there's an off chance you could even get free support if there's a problem.

Usage is simple.
  #include <iostream>  #include <tr1/random>  int main(int, char*[])  {    std::tr1::mt19937 mersenneTwister;    for (int i = 0; i < 100; ++i)    {      std::cerr << mersenneTwister() << "\n";    }  }

Stephen M. Webb
Professional Free Software Developer

This topic is closed to new replies.

Advertisement