我有一个包含四个项目(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集合中的值已排序)

09-13 01:53
查看更多