I originally posted this on StackOverflow but was requested to post it here instead as it relates to optimization/performance of the code rather than a specific problem.
TL;DR: Get-Random produces an even distribution of numbers where every number in the pool has an even chance of appearing. I’m looking for a way to generate random numbers where every individual number appears with a frequency that I myself specify.
If I run
for($i=1;$i -le 1000;$i++){
Get-Random -Minimum 0 -Maximum 10
}
I get a very evenly distributed count for each number (roughly 100 for each number between 0 and 9). Using Get-Random allows me to get a random number every time but on average, every individual result will appear roughly an equal amount of times. I want to decide the frequency for how often any specific number appears, and then generate random numbers that fit that distribution. As an example:
Number Probability
0 10
1 11
2 19
3 12
4 3
5 10
6 6
7 7
8 4
9 18
I’m looking for a way to use the above list to randomly generate a number between 0 to 9, but with the probability of each individual number appearing using the Probability column.
My very hard-coded and not so generic solution so far is that I thought of doing something like adding a cumulative percentage column:
Number Probability CumulativeProbability
0 10 10
1 11 21
2 19 40
3 12 52
4 3 55
5 10 65
6 6 71
7 7 78
8 4 82
9 18 100
And from here, run the object through a filter. Something like:
$RandomNumber = Get-Random -Minimum 0 -Maximum 100
$MyProbabilityObject | Where-Object {$RandomNumber -ge $_.CumulativeProbability}
This gives me all numbers with a lower Cumulative probability than the random number. Let’s say the $RandomNumber was 42, that would result in:
Number Probability CumulativeProbability
0 10 10
1 11 21
2 19 40
From here, I could pipe the result to
Select-Object CumulativeProbability | Measure-Object -Property CumulativeProbability -Maximum
Which gives me the highest value, and then use that column as a reference to find the number with
Where-Object {$_.CumulativeProbability -eq $TheNumberIGetAbove}
While this kinda works, it feels like I’m doing several laps around a problem that should be easier and more straightforward to solve. Are there any better ways of generating random numbers that fit a distribution you specify yourself instead of using an even distribution such as Get-Random?