Archived

This topic is now archived and is closed to further replies.

Choosing a Non-Uniform Random Integer

This topic is 5332 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can somebody out there help me with this problem? Say I have an object which performs some action with some given average of frequency. For example, say you have a swordsman, and you want him to take on average 3.2 hacks to kill an enemy over the course of many, many attacks. Say you are allowed anywhere from 1 to 10 hacks per attack ... 1 hack minimum to kill an enemy, 10 hacks maximum to kill any enemy, and you want to choose from 1-10 randomly to decide how many hacks are used in each attack. However, you don''t want this to be a uniform distrubtion because you want to center the average around 3.2 hacks. Additionally, the average hacks (3.2 in this example) can vary depending on character attributes. Some swordsmen might take on average 3.0 hacks, others 3.5, some 4.0, etc. Does anybody have some ideas for how I can choose this random number (1-10) and still get averages near the appropriate levels for the characters attributes? I''ve thought about using a Gaussian random number generator with the mean at the level I want, but since my overall range (1-10) is not centered around the average I want (in the 3.x range), I don''t think this will work. Another thought I had is to have some sort of feedback where I choose 1-10 with a uniform random generator and monitor the current average to make outcomes more or less likely in future events. But I''m sure there are more elegant solutions out there. Any ideas?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I guess you could use a binomial distribution. Bin(9, 0.266) + 1 should give you integers 1 to 10 with mean 3.4.

Share this post


Link to post
Share on other sites

  
double random_in_range_with_mean(double a, double b, double mean){
double normalized_mean = (mean-a)/(b-a);
double exp = -1 + 1/normalized_mean;
double r = pow((double)rand()/RAND_MAX,exp);
return a+r*(b-a);
}

double round_preserving_mean(double x){
double i = floor(x);
double m = x-i;
if(rand()<=RAND_MAX*m)
i+=1;
return i;
}

int number_you_need = round_preserving_mean(random_in_range_with_mean(1,10,3.2));


This is generating a uniform distribution, raising the result to some power to distort the mean (like in gamma correction for colours) and scaling the result to fit in the range. If you need your number to be an integer, you can round randomly so that the mean is preserved.

Share this post


Link to post
Share on other sites
For a quick n'' dirty method: rand() - rand() will give you a triangle-shaped distribution from -RAND_MAX to RAND_MAX, with the mean at 0.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites