【问题标题】:Get random element in list, where the first elements have higher chance to be chosen than the last elements获取列表中的随机元素,其中第一个元素比最后一个元素有更高的机会被选中
【发布时间】:2020-12-07 13:28:51
【问题描述】:

想象一个按降序排列的元素列表:

List<T> list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];

如何实现 Random,以便第一个元素比其他元素更有可能被选中?所以说,20% 得到索引 1,17.5% 得到索引 2,15% 得到索引 3,等等。但是,机会不应该那么严重,因为它需要加起来 100%。还需要注意的是,列表可以是任意长度,因此不能硬编码。

总结:我如何实现随机,以便可以从 n 个元素的列表中选择索引,其中前几个 n 元素比最后几个元素有更高的机会被选择,所以按降序排列?

【问题讨论】:

  • "比如说,20% 得到索引 1,...",这就是你定义一个函数来处理基于索引和长度的权重的部分。然后你在上面拍weighted random numbers

标签: c# .net statistics


【解决方案1】:

您可以使用不同大小的数字段来使用概率分布。

public sealed class Distribution
{
    public int Index { get; set; }
    public float From { get; set; }
    public float To { get; set; }

    public override string ToString()
    {
        return $"{Index}:{From}-{To}";
    }
}
static void Main(string[] args)
{
    var list = new List<int>()
    {
        10, 9, 8, 7, 6, 5, 4, 3, 2, 1
    };
    var percents = new List<Distribution>();
    var start = 0f;
    var size = 20f;
    var step = 20f/ (list.Count-1);
    for (int j = 0; j < list.Count; j++)
    {
        var distribution = new Distribution()
        {
            Index = j,
            From = start,
            To= start + size,
        };

        percents.Add(distribution);
        start = start + size;
        size -= step;
    }

    var rnd = new Random();
    var frequency = new int[list.Count];
    for (int j = 0; j < 100000; j++)
    {
        var randomValue = rnd.NextDouble() * 100;
        var found = percents.FirstOrDefault(x => x.From <= randomValue && x.To > randomValue);
        frequency[found.Index] = frequency[found.Index] + 1;
    }
    Console.WriteLine(string.Join(System.Environment.NewLine , frequency.Select(x => $"{x}->{((float)x)/1000}%")));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多