Выбор случайного элемента из списка с вероятностным весом с помощью c #? - PullRequest
2 голосов
/ 28 ноября 2011

У меня есть сценарий, в котором ia брал список пользователей (20 пользователей) из моей базы данных, где я давал весовые коэффициенты для пользователей

первые 5 пользователей, коэффициент вероятности 4, следующие 5 пользователей, коэффициент вероятности 3вероятностный коэффициент следующих 5 пользователей равен 2 вероятностный коэффициент следующих 5 пользователей равен 1

Таким образом, вероятность появления пользователя из первых 5 пользователей в 4 раза выше, чем у пользователя из последних 5.

Так как же я могу выбрать случайного пользователя из списка, используя вероятность в c #?Кто-нибудь может мне помочь в этом, я полностью застрял в логике?

Ответы [ 5 ]

4 голосов
/ 28 ноября 2011

Создать список частичных сумм весов. В вашем примере это будет

[4, 8, 12, 16, 20, 23, ...]

Последний элемент - это сумма всех весов. Выберите случайное число от 0 до этой суммы (исключая). Тогда ваш элемент - это первый элемент с частичной суммой, большей случайного числа. Итак, если у вас есть 11, вам нужен третий элемент, если у вас есть 16, пятый и т. Д.

4 голосов
/ 28 ноября 2011

Вы можете добавить количество использованных вероятностей в список. Таким образом, 5 первых пользователей находятся в списке 4 раза, следующие 5 пользователей - 3 раза и так далее. Затем просто выберите одного пользователя из полного списка.

1 голос
/ 28 ноября 2011

Вы можете распределить диапазон вероятностей среди пользователей, используя словарь.Например,

Пользователь 1 имеет 1-4 (максимум 4)

Пользователь 2 имеет 5-8 (максимум 8) и т. д. и т. д.

Затем после выбораслучайное число определяет, к какому пользователю в словаре оно относится.Вы можете сделать это, используя Linq, например, так ...

int iUser = users.Where(p => (choice <= p.Value)).First().Key;

.., где users - это Dictionary<int,int> (Ключ = номер пользователя, Значение = максимальное значение), а choice - это случайно сгенерированныйvalue.

Это, очевидно, более сложный метод, чем «множественные записи», предложенный другими, но имеет свои преимущества, если вам

a) требуется дробное взвешивание, которое делаетобщий знаменатель вашего метода многократного ввода очень мал (в результате чего много записей) или

b) необходимо сильно повлиять на конкретных пользователей (что опять-такиэффект создания метода многократного ввода очень большой).

Рабочий пример в ideone.

1 голос
/ 28 ноября 2011

Одним из решений было бы найти наименьший общий знаменатель весов (или просто умножить их вместе) и создать новый список, который содержит ключи первого списка, но несколько раз, т.е.:

user1 user1 user2 user3 user3 user3

Тогда просто к newList.skip(Random.Next(newList.Count)).Take(1) и все готово!

1 голос
/ 28 ноября 2011

У меня есть (немного хакерское) решение для вас:

Создайте список, содержащий пользователей, где каждый пользователь будет добавлен так часто, как его вес. (например, пользователь имеет вес 5, добавьте его 5 раз в список). Затем нам Random, чтобы выбрать пользователя из этого списка, который должен решить вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...