Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Make Selection Random Based On Percentage

Tags:

c#

random

math

I have a bunch of items than range in size from 1-10.

I would like to make the size that the item is to be determined by the percentage or chance of the object being that size..

For example:

Items chance of being size 1 = 50% chance

Items chance of being size 5 = 20% chance

Items chance of being size 10 = 5% chance

I know I would need to use a Random generator for this of course.

But just wondering how would some of you go about the logic of this in C#?

like image 926
coder4life22 Avatar asked Nov 24 '15 08:11

coder4life22


People also ask

How do I randomize a percentage in Excel?

If you want to use RAND to generate a random number but don't want the numbers to change every time the cell is calculated, you can enter =RAND() in the formula bar, and then press F9 to change the formula to a random number.

How do you select a random item with a given distribution?

RAND() is an Excel function with no input parameters that will return a uniformly distributed random number between 0 and 1. We use this random number between 0 and 1 as the value to lookup in our DistTable. Since this lookup value is random, the result returned from the List column will also be random.


2 Answers

First of all: the probabilities provided don't add up to 100%:

50% + 20% + 5% = 75%

So you have to check these values. You may want to generate these per cents:

// Simplest, but not thread safe
private static Random s_Random = new Random();

...
int perCent = s_Random.Next(0, 100);

if (perCent < 50)               //  0 .. 49
{
    // return Item of size 1
}
else if (perCent < 50 + 20)     // 50 .. 69
{
    // return Item of size 5
}
else if (perCent < 50 + 20 + 5) // 70 .. 74 
{
    // return Item of size 10
} 
...
like image 90
Dmitry Bychenko Avatar answered Nov 03 '22 17:11

Dmitry Bychenko


Use my method. It is simple and easy-to-understand. I don't count portion in range 0...1, i just use "Probabilityp Pool" (sounds cool, yeah?) I make a list with all elements i want choose from. Every element has its own chance. It is useful to set the most common element chance = 100, so most rare elements would be 60 or 50.

At circle diagram you can see weight of every element in pool

Here you can see an implementing of accumulative probability for roulette

`

// Some c`lass or struct for represent items you want to roulette
public class Item
{
    public string name; // not only string, any type of data
    public int chance;  // chance of getting this Item
}

public class ProportionalWheelSelection
{
    public static Random rnd = new Random();

    // Static method for using from anywhere. You can make its overload for accepting not only List, but arrays also: 
    // public static Item SelectItem (Item[] items)...
    public static Item SelectItem(List<Item> items)
    {
        // Calculate the summa of all portions.
        int poolSize = 0;
        for (int i = 0; i < items.Count; i++)
        {
            poolSize += items[i].chance;
        }

        // Get a random integer from 0 to PoolSize.
        int randomNumber = rnd.Next(0, poolSize) + 1;

        // Detect the item, which corresponds to current random number.
        int accumulatedProbability = 0;
        for (int i = 0; i < items.Count; i++)
        {
            accumulatedProbability += items[i].chance;
            if (randomNumber <= accumulatedProbability)
                return items[i];
        }
        return null;    // this code will never come while you use this programm right :)
    }
}

// Example of using somewhere in your program:
        static void Main(string[] args)
        {
            List<Item> items = new List<Item>();
            items.Add(new Item() { name = "Anna", chance = 100});
            items.Add(new Item() { name = "Alex", chance = 125});
            items.Add(new Item() { name = "Dog", chance = 50});
            items.Add(new Item() { name = "Cat", chance = 35});

            Item newItem = ProportionalWheelSelection.SelectItem(items);
        }
like image 10
Oleksandr Martysh Avatar answered Nov 03 '22 15:11

Oleksandr Martysh