Random occurrences
I am not quite sure how to go about this.
I need to generate 14,296 random numbers with different levels of probability.
so for example I need an array containing the numbers 18, 1, and 17. Each number has a different percent probability of occuring. So:
55% = 18
(7,862.8 times)30% = 1
(4,288.8 times) 开发者_Go百科15% = 17
(2,144.4 times)
the result would be something like new Array () { 18, 18, 1, 17, 1, 18...}
If you'll always have the values as integer percentages, I'd fill a 100-element array with values according to the probability, so in this case your array would have 55 occurrences of 18, 30 occurrences of 1, and 15 occurrences of 17. Then you just need to pick 14,296 random values from that array. (i.e. pick an integer in the range [0, 100) and take that element.)
For different ways of expressing the probabilities, there are different approaches, of course. But if you're given integer percentages, this is an easily-understood option. (Another way is to scale all of the probabilities by the total, i.e. into a range of [0, 1), and then take a random double in that range.)
Divide the range of random generator into proportional segments, and, judging to which segment the next random number has fallen into, select the corresponding number from your set.
Something like (simplified):
const int numbers[3] = { 1, 17, 18 };
const int borders[2] = { 0.30*MAX_RANDOM, (0.30 + 0.15) * MAX_RANDOM };
int i = random.next(), num;
if (i < borders[0]) num = number[0];
else if (i < borders[0]) num = number[1];
else num = number[2];
Of course, if there's more numbers than three, it's better to use a loop.
Note: unlike Jon Skeet's solution, this one can provide any desired granularity up to 1/(MAX_RANDOM+1) (which is often up to 2^32 on 32-bit machines), rather than strictly 1%.
Random r = new Random();
// for each number to generate
int nextNumber;
double probability = r.NextDouble();
if (probability < 55.0 / 100.0)
nextNumber = 18;
else if (probability < (55.0 + 30.0) / 100.0)
nextNumber = 1;
else
nextNumber = 17;
How about something like this (untested):
struct np
{
int n;
int p;
}
Create a List<np>
and will it with value/percentage pairs (e.g. n = 18, p = 55
).
Then just do the following to pick a number:
List<np> npl = new List<np>();
// (fill the list here)
int r = rnd.next(total_of_all_p_values); // get random number
int res = 0; // result
for(int i = 0; i < npl.Length(); r -= npl[i++].n)
{
if(r < npl[i].p) // remaining vlaue is smaller than current percentage
{
res = npl[i].n;
break;
}
}
You could populate a List<T>
with the appropriate number of each of the 3 numbers, and then randomize the List.
精彩评论