Using custom random number generators with Ruby Array#shuffle/sample -


when using array#shuffle, ruby allows use of custom randomizer , provides class random utilize it. following example uses class seed value of 48.

array = [1,2,3,4,5,6,7,8,9,10] array.shuffle(random: random.new(48))  # => [8,6,3,7,10,9,5,2,4,1]  

i wrote small monobit test see how many times value appeared first in shuffled array.

deck = (1..10).to_a counts = hash.new(0)  rng = random.new  50000.times   counts[deck.shuffle(random: rng).first] += 1 end  1.upto(10) |card|   puts "#{card}:\t#{counts[card]}" end 

the output looks similar following:

1:  4942 2:  5100 3:  4938 4:  4960 5:  5024 6:  4992 7:  5184 8:  4930 9:  4916 10: 5014 

suppose want replace pseudo-random number generator new class. since array#shuffle appears use random#rand in above example, seem straightforward implement new class act rng shuffling. here, implement new pseudo-random number generator simple wrapper around rand:

deck = (1..10).to_a counts = hash.new(0)  class foorandom   def rand(max=nil)     max.nil? ? kernel::rand : kernel::rand(max)   end end  rng = foorandom.new  50000.times   counts[deck.shuffle(random: rng).first] += 1 end  1.upto(10) |card|   puts "#{card}:\t#{counts[card]}" end 

this, however, not operate expected. foorandom#rand called, shuffling produces following distribution:

1:  0 2:  5423 3:  5562 4:  5544 5:  5512 6:  5569 7:  5535 8:  5595 9:  5524 10: 5736 

as can see, array value 1 never appears in first position of array after array shuffled. have idea why?

there bug in ruby 2.0.0p0 limit off one.

this has been fixed in ruby 2.0.0p195, should upgrade installation.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -