使用c#从具有概率加权的列表中选择随机项?

时间:2011-11-28 10:19:05

标签: c# logic

我有一个场景,我正在从我的数据库中获取用户列表(20个用户),我在那里给予 为用户加权

前5个用户的概率因子为4 接下来5个用户的概率因子为3 接下来5个用户的概率因子为2 接下来的5个用户概率因子为1

因此,前5个用户中出现的用户数是其他用户的4倍 可能比过去5年的用户发生。

那么如何在c#中使用概率从列表中选择随机用户? 任何人都可以帮助我这样做吗?我完全被逻辑搞定了?

5 个答案:

答案 0 :(得分:4)

您可以在列表中添加使用次数的概率次数。所以5个第一用户在列表中是4次,接下来是5个用户3次,依此类推。然后从完整列表中选择一个用户。

答案 1 :(得分:4)

创建部分权重总和列表。在您的示例中,它将是

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

最后一个元素是所有权重的总和。选择0和此总和之间的随机数(不包括)。那么你的元素是第一个元素,其部分和大于随机数。所以如果你得到11,你需要第三个元素,如果你有16个,第五个元素等等。

答案 2 :(得分:1)

我有一个(有点hacky)解决方案:

创建一个包含用户的列表,其中每个用户的添加频率与其权重相同。 (例如,用户的权重为5,将其添加到列表中5次)。然后我们Random从该列表中获取用户,这将解决您的问题。

答案 3 :(得分:1)

一种解决方案是找到权重的最小公分母(或者只是将它们相乘)并创建一个包含第一个列表的键的新列表,但是多次,即:

USER1 USER1 用户2 用户3 用户3 用户3

然后只是newList.skip(Random.Next(newList.Count)).Take(1),你就被设定了!

答案 4 :(得分:1)

您可以使用字典在用户之间分配概率范围。例如

用户1有1-4(最多4个)

用户2有5-8(最多8个)等...

然后在选择随机数后,找到与其相关的词典中的哪个用户。你可以使用Linq这样做......

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

..其中usersDictionary<int,int>(键=用户号,值=最大值),choice是随机生成的值。

这显然比其他人提出的“多项”方法更复杂,但如果你

则有其优势

a)需要一个小数加权,这会使您的多次输入法的公分母非常小(导致许多条目)

b)需要大量支持特定用户(这将再次使多次输入方法非常大)。

Working Example at ideone.