I am trying to write a function that the returns one of the following multipliers randomly selected but following the frequency requirement. What below table defines is that for 1 Million calls to this function the 1500 will be returned once, 500 twice and so on.
|---------------------|------------------------------|
| Multiplier | Frequency Per Million |
|---------------------|------------------------------|
| 1500 | 1 |
|---------------------|------------------------------|
| 500 | 2 |
|---------------------|------------------------------|
| 200 | 50 |
|---------------------|------------------------------|
| 50 | 100 |
|---------------------|------------------------------|
| 25 | 20,000 |
|---------------------|------------------------------|
| 5 | 75,000 |
|---------------------|------------------------------|
| 3 | 414,326 |
|---------------------|------------------------------|
| 2 | 490521 |
|---------------------|------------------------------|
Wondering what would be the best way to approach implementing this.
CodePudding user response:
First, let's declare the model:
static Dictionary<int, int> multipliers = new Dictionary<int, int>() {
{1500, 1},
{ 500, 2},
{ 200, 50},
{ 50, 100},
{ 25, 20_000},
{ 5, 75_000},
{ 3, 414_326},
{ 2, 490_521},
};
Then you can easily choose random multiplier:
// Easiest, but not thread safe
static Random random = new Random();
...
private static int RandomMultiplier() {
int r = random.Next(multipliers.Values.Sum());
s = 0;
foreach (var pair in multipliers.OrderByDescending(p => p.Key))
if (r < (s = pair.Value))
return pair.Key;
throw new InvalidOperationException($"{r} must not reach this line");
}
...
int multiplier = RandomMultiplier();
CodePudding user response:
If the frequency and value that needs to be returned are set, then nothing complicated is needed. You just need to adjust for the previous numbers being handled in the if blocks by adding the frequency of the previous numbers.
private int GetRandomMultiplier()
{
var random = new Random();
var next = random.Next(1000000);
if (next < 1)
{
return 1500;
}
else if (next < 3)
{
return 500;
}
else if (next < 53)
{
return 200;
}
else if (next < 153)
{
return 50;
}
else if (next < 20153)
{
return 25;
}
else if (next < 95153)
{
return 5;
}
else if (next < 509479)
{
return 3;
}
return 2;
}
You don't want to create a new Random
every time though, so create one once and use that.