かき混ぜ法

M. D. MacLarenとG. Marsagliaによって提案された、擬似乱数アルゴリズムを「改良」する(と言われている)「かき混ぜ法」です。

  • 課題:maxの扱い
  • 課題:インタフェースを定め、Decoratorパターンに。
class LinearCongruentialRandom
  A = 1812433253

  def initialize(seed=314159)
    @state = seed
  end

  def next(max=nil)
    @state = A * @state + 1
    if max
      @state % max.to_i.abs
    else
      @state
    end
  end
end

class ShuffledRandom
  DECK_SIZE = 101

  def initialize(prng_class=LinearCongruentialRandom, seed=314159)
    @prng = prng_class.new(seed)
    @deck = Array.new(DECK_SIZE)
    DECK_SIZE.times do |i|
      @deck[i] = @prng.next
    end
  end

  def next(max=nil)
    index = @prng.next(DECK_SIZE)
    result, @deck[index] = @deck[index], @prng.next
    if max
      result % max.to_i.abs
    else
      result
    end
  end
end

r = ShuffledRandom.new
100.times do
  print "#{r.next(10000)}, "
end