水库采样

Jon*_*ony 24 random algorithm

为了从未确定大小的数组中检索k个随机数,我们使用称为储层采样的技术.任何人都可以通过示例代码简要介绍它是如何发生的吗?

Lar*_*rry 35

我实际上没有意识到这有一个名字,所以我从头开始证明并实现了这个:

import random
def random_subset( iterator, K ):
    result = []
    N = 0

    for item in iterator:
        N += 1
        if len( result ) < K:
            result.append( item )
        else:
            s = int(random.random() * N)
            if s < K:
                result[ s ] = item

    return result
Run Code Online (Sandbox Code Playgroud)

来自:http://web.archive.org/web/20141026071430/http : //propersubset.com : 80/2010/04/choosing-random-elements.html

随着证据接近结束.


sam*_*sam 11

按照Knuth(1981)的描述,储层采样(算法R)可以实现如下:

import random

def sample(iterable, n):
    """
    Returns @param n random items from @param iterable.
    """
    reservoir = []
    for t, item in enumerate(iterable):
        if t < n:
            reservoir.append(item)
        else:
            m = random.randint(0,t)
            if m < n:
                reservoir[m] = item
    return reservoir
Run Code Online (Sandbox Code Playgroud)

  • @user76284 正确,应该如此。让“iterable”包含 11 个项目,我们要从中采样“n”=10。对于第 11 个项目,“t”将为 10(因为“enumerate”从 0 开始),我们生成一个 0 到 10 之间的随机整数(即 11 种可能性),这样将第 11 个项目添加到“reservoir”的概率` 为 n/t = 10/11。 (2认同)