Sign in to follow this  
GLGunblade

Rand() and for loops

Recommended Posts

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[i].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 ^^

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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:


//pseudocode
PRNG(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.

Share this post


Link to post
Share on other sites
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";
}
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this