в постоянном пространстве? Конечно, Отбор проб резервуара , постоянное пространство, линейное время
Некоторый слегка проверенный код
import numpy as np
def stream(size):
for k in range(size):
yield k
def resSample(ni, s):
ret = np.empty(ni, dtype=np.int64)
k = 0
for k, v in enumerate(s):
if k < ni:
ret[k] = v
else:
idx = np.random.randint(0, k+1)
if (idx < ni):
ret[idx] = v
return ret
SIZE = 12
s = stream(SIZE)
q = resSample(1, s)
print(q)
Я вижу, что есть вопрос в отношении RNG. Предположим, у меня есть настоящий RNG, аппаратное устройство, которое возвращает один бит за раз. Мы используем его только в коде, где получаем индекс.
if (idx < ni):
Единственное условие-условие будет вызвано для выбора одного элемента.
это когда ni=1
и, следовательно, idx
может быть только НОЛЬ.
Таким образом, np.random.randint (0, k + 1) с такой реализацией будет выглядеть примерно так:
def trng(k):
for _ in range(k+1):
if next_true_bit():
return 1 # as soon as it is not 0, we don't care
return 0 # all bits are zero, index is zero, proceed with exchange
КЭД, такая реализация возможна, и поэтому этот метод отбора проб будет работать
UPDATE
@ kyrill, вероятно, прав - мне нужно вести подсчет (журнал 2 (k) хранения), поэтому пока не вижу способа избежать этого. Даже с помощью трюка с ГСЧ мне нужно сэмплировать 0 с вероятностью 1/k
, и это k
увеличивается с размером потока.