Live data from Hacker News

Vitter's reservoir sampling algorithm D: randomly selecting unique items

getkerf.wordpress.com

41–50 of 83 posts

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#41

> The first obstacle that makes the “dealing” (without replacement) hard is that the “draw” method doesn’t work. If you draw (with replacement) over and over again, ignoring cards you’ve already picked, you can simulate a deal, but you run into problems. The main one is that eventually you’re ignoring too many cards and the algorithm doesn’t finish on time (this is the coupon collector’s problem). I don't think this…

This crossing out is, of course, not possible if you have a stream coming in, which is the case for which these sampling algorithms are used the most.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#42
post #22

Here is an alternative: Use a multiplicative linear congruential generator with a period 2^n , where n is ceil(log2(m)), where m is the size of the list. Seed the generator, start generating values and drop all values that are larger than m. In the worst case you will have to drop half of the values, in the best case you will drop none. This depends on how close to a power of 2 m is. The generator is very short, one…

This works, and is so much simpler. It's not quite the same problem though; the algorithm described returns samples in sequential order . They mention performance reasons for this (C-f "tape sampling"). It also has the limitation that you need to know the sample size in advance.

MLCG is sequential. No value will be repeated within the period.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#43

This may be a stupid question, but why not store cards/tweets in a hashmap and add a .contains() check before adding?

Say you need to draw a 100 bilion samples without replacement from a dataset with a trillion plus rows, the resource requirements for hashmap would become enormous.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#44

> The first obstacle that makes the “dealing” (without replacement) hard is that the “draw” method doesn’t work. If you draw (with replacement) over and over again, ignoring cards you’ve already picked, you can simulate a deal, but you run into problems. The main one is that eventually you’re ignoring too many cards and the algorithm doesn’t finish on time (this is the coupon collector’s problem). I don't think this…

This is not correct as written: "But we have k < N, so if we are O(N) we are also O(k) or better."

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#45
post #42

Earlier quoted context omitted.

This works, and is so much simpler. It's not quite the same problem though; the algorithm described returns samples in sequential order . They mention performance reasons for this (C-f "tape sampling"). It also has the limitation that you need to know the sample size in advance.

MLCG is sequential. No value will be repeated within the period.

He means: outputs are sorted.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#46

I can't believe this article doesn't explain how it works. Especially after stating "after reaching Vitter’s papers it again takes a concentrated effort to figure out what you need".

Yeah, the article was pretty dense so I just slogged through it hoping I would get to the explanation part.

Nope, it just gave me ugly c code at the end.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#47
post #42

Earlier quoted context omitted.

This works, and is so much simpler. It's not quite the same problem though; the algorithm described returns samples in sequential order . They mention performance reasons for this (C-f "tape sampling"). It also has the limitation that you need to know the sample size in advance.

MLCG is sequential. No value will be repeated within the period.

"sequential" in the sense that if returned values are i1, i2, ..., in, then 0 A MLCG will return numbers all over the place; sorting them will take an additional O(n log n) time.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#48
post #22

Here is an alternative: Use a multiplicative linear congruential generator with a period 2^n , where n is ceil(log2(m)), where m is the size of the list. Seed the generator, start generating values and drop all values that are larger than m. In the worst case you will have to drop half of the values, in the best case you will drop none. This depends on how close to a power of 2 m is. The generator is very short, one…

This is very practical, but the result is not uniform; in fact it only returns a tiny fraction of the possible combinations.

There are "N choose k" combinations, which in the worst case (k = N/2) grows as ~ 2^N. The number of combinations quickly outstrips the number of possible states of the LCG, and most combinations will never be found. For example, we have a list of length 16 and wish to choose 8. We have a choice of 16 distinct seeds, so there are only 16 different combinations (out of 12870 possible) that we can get for any given LCG.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#49
post #47
post #42

Earlier quoted context omitted.

MLCG is sequential. No value will be repeated within the period.

"sequential" in the sense that if returned values are i1, i2, ..., in, then 0 A MLCG will return numbers all over the place; sorting them will take an additional O(n log n) time.

I see.

Re: Vitter's reservoir sampling algorithm D: randomly selecting unique items

#50
Again, I am confused. Why doesn't this snippet solve the problem?

  void increasingRandomSequence(arrayptr, base, k, n)
  {
      if (k == 0) return;
      int i = randInt(n - k);
      *(arrayptr) = base + i;
      increasingRandomSequence(arrayptr + 1, base + i + 1, k - 1, n - (i + 1));
  }
increasingRandomSequence(hand, 0, k, n) fills the array hand with a sequence which is picked with uniform distribution over all increasing sequences of length k with numbers in [0, n - 1].

This is O(k), and we can shuffle this in O(k). Why doesn't this solve the problem?

Post reply on HN