Choose random array element satisfying certain property

后端 未结 5 1592
隐瞒了意图╮
隐瞒了意图╮ 2020-12-16 15:34

Suppose I have a list, called elements, each of which does or does not satisfy some boolean property p. I want to choose one of the elements that

5条回答
  •  我在风中等你
    2020-12-16 16:31

    Yes, I believe so.

    The first time you encounter a matching element, you definitely pick it. The next time, you pick the new value with a probability of 1/2, so each of the two elements have an equal chance. The following time, you pick the new value with a probability of 1/3, leaving each of the other elements with a probability of 1/2 * 2/3 = 1/3 as well.

    I'm trying to find a Wikipedia article about this strategy, but failing so far...

    Note that more generally, you're just picking a random sample out of a sequence of unknown length. Your sequence happens to be generated by taking an initial sequence and filtering it, but the algorithm doesn't require that part at all.

    I thought I'd got a LINQ operator in MoreLINQ to do this, but I can't find it in the repository... EDIT: Fortunately, it still exists from this answer:

    public static T RandomElement(this IEnumerable source,
                                     Random rng)
    {
        T current = default(T);
        int count = 0;
        foreach (T element in source)
        {
            count++;
            if (rng.Next(count) == 0)
            {
                current = element;
            }            
        }
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty");
        }
        return current;
    }
    

提交回复
热议问题