如何随机选择具有权益**的列表项的一半*?

时间:2018-07-05 13:37:31

标签: c# random

如何准确选择 * 列表中的 * 项的一半?

(*)一半为n / 2,其中int部分足够。

列表中的项目数大于10 ^ 9。因此,n / 2-1与n的接近度不足以引起明显的近似。

(**)公平和公正的原则意味着列表中的每个项目都具有相同的蜜蜂挑选概率。

我有一个这样的股票选择器:

 myList.Where(i => rand.NextDouble() >= 0.5);

但是有了这个,我可以拥有超过/少于一半的数量,而所有这些人/没有一个的机会很小。

免责声明:这不是家庭作业,而是围绕Thanos Random Picker的反思和建模。能够公平地挑选每个人口的一半的能力。

1 个答案:

答案 0 :(得分:1)

如果您知道序列中的项目数,则可以使用以下代码随机且公平地选择count项:

public static IEnumerable<T> RandomlySelectedItems<T>(IEnumerable<T> sequence, int count, int sequenceLength, Random rng)
{
    int available = sequenceLength;
    int remaining = count;

    using (var iterator = sequence.GetEnumerator())
    {
        for (int current = 0; current < sequenceLength; ++current)
        {
            iterator.MoveNext();

            if (rng.NextDouble() < remaining / (double)available)
            {
                yield return iterator.Current;
                --remaining;
            }

            --available;
        }
    }
}

其优点是它不复制序列,并且是O(N)操作。

例如,您将count传递为n / 2。