С# и "взвешенная вероятность"

91
8

Я ищу, чтобы выбрать 1 человека из списка людей, где каждый элемент в списке имеет определенное "взвешивание". Предположим, что класс Person имеет необходимый конструктор.

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));

Теперь я хочу случайно выбрать человека из этого списка. Но в среднем я хочу выбрать Майкла в 4 раза чаще, чем Тим. И я хочу выбрать Джон половину (2/4) так же часто, как Майкл. И, конечно же, я хочу выбрать Майкла вдвое чаще, чем Джон.

Имеет ли это смысл?

У меня уже есть код для выбора людей по процентам. Не будет ли это работать, если бы я просто умножил% шансов на них по весу, представленному в этом примере?

Кроме того, моя текущая система работает только с шансами до 100%, ничего выше. Любые советы о том, как преодолеть это ограничение? Вероятно, мне нужно было бы масштабировать каждый шанс в соответствии с самым большим фактором в списке?

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

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

Или я чего-то не хватает?

спросил(а) 2016-11-11T12:26:00+03:00 3 года, 11 месяцев назад
1
Решение
58

Вы не ведете проценты для начала.

Я бы создал случайное число в диапазоне от 0 до суммы всех значений Weighting. Затем просто перейдите по списку и проверьте, меньше ли значение, чем текущий плюс собственный вес.

Так:

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;
}
}

ответил(а) 2016-11-11T12:41:00+03:00 3 года, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема