我有一个包含四个项目(A,B,C,D)的列表。每个项目都有被选择的可能性。举例来说,假设A有74%的机会被选中,B有15%的机会,C有7%的机会,D有4%的机会。
我想创建一个函数,根据其概率随机选择一个项目。
有什么帮助吗?
最佳答案
为您的商品定义一个类,如下所示:
class Items<T>
{
public double Probability { get; set; }
public T Item { get; set; }
}
然后初始化
var initial = new List<Items<string>>
{
new Items<string> {Probability = 74 / 100.0, Item = "A"},
new Items<string> {Probability = 15 / 100.0, Item = "B"},
new Items<string> {Probability = 7 / 100.0, Item = "C"},
new Items<string> {Probability = 4 / 100.0, Item = "D"},
};
那么您需要将其转换为总计从0到1的概率之和
var converted = new List<Items<string>>(initial.Count);
var sum = 0.0;
foreach (var item in initial.Take(initial.Count - 1))
{
sum += item.Probability;
converted.Add(new Items<string> {Probability = sum, Item = item.Item});
}
converted.Add(new Items<string> {Probability = 1.0, Item = initial.Last().Item});
现在,您可以从
converted
集合中选择关于概率的项目:var rnd = new Random();
while (true)
{
var probability = rnd.NextDouble();
var selected = converted.SkipWhile(i => i.Probability < probability).First();
Console.WriteLine($"Selected item = {selected.Item}");
}
注意:我的实现具有
O(n)
复杂性。您可以使用二进制搜索对其进行优化(因为converted
集合中的值已排序)