1

I am looking to pick 1 person from a list of people where each item in the list has a certain "weighting" to it. Let's assume the Person class has the necessary constructor.

public class Person {
    public string Name { get; set; }
    public float Weighting { get; set; }
}

public List<Person> People = new List<Person>();

People.Add(new Person("Tim", 1.0));
People.Add(new Person("John", 2.0));
People.Add(new Person("Michael", 4.0));

Now, I want to choose a person randomly from this list. But on average I want to pick Michael 4 times more often than Tim. And I want to pick John half (2/4) as often as Michael. And of course, I want to pick Michael double as often as John.

Does that make any sense?

I already have code in place to select people based on percentages. Wouldn't it work if I just multiplied the %chance of them by the weighting provided in this example?

Also, my current system only works with chances of up to 100%, nothing above. Any advice on how to overcome this limitation? I would probably have to scale every chance according to the largest factor in the list?

public static bool Hit(double pct) {
    if (rand == null)
        rand = new Random();

    return rand.NextDouble() * 100 <= pct;
}

Or am I missing something?

j8a2b0e7
  • 75
  • 6
  • Your questions are a bit vague, and not really suitable for this forum, but I can't see anything wrong with your suggested approaches. Suggest that you try something first, and then if it's not working you can come back here (or a more appropriate forum) and ask a specific question about a specific coding problem. – LordWilmore Nov 11 '16 at 09:33

1 Answers1

2

You are not keeping percentages to start with.

I would create a random number in the range of 0 to the sum of all Weighting values. Then just walk over the list and check if the value is lower than the current plus own weight.

So:

float r = YourRandomNumber(People.Sum(p => p.Weighting));
float sum = 0;

foreach (Person p in People)
{
    if (r < (sum + p.Weighting))
    {
        // hit
        // save the person somewhere
        break;
    }
    else
    {
        sum += p.Weighting;
    }
}
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325