使用Ruby Array #shuffle / sample的自定义随机数生成器
发布时间:2020-12-17 03:05:09 所属栏目:百科 来源:网络整理
导读:使用Array #shuffle时,Ruby允许使用自定义随机函数,甚至提供Random类来使用它.以下示例使用种子值为48的类. array = [1,2,3,4,5,6,7,8,9,10]array.shuffle(random: Random.new(48)) # = [8,10,1] 我写了一个小的单比特测试,看看一个值在洗牌数组中出现的次数
使用Array #shuffle时,Ruby允许使用自定义随机函数,甚至提供Random类来使用它.以下示例使用种子值为48的类.
array = [1,2,3,4,5,6,7,8,9,10] array.shuffle(random: Random.new(48)) # => [8,10,1] 我写了一个小的单比特测试,看看一个值在洗牌数组中出现的次数. deck = (1..10).to_a counts = Hash.new(0) rng = Random.new 50000.times do counts[deck.shuffle(random: rng).first] += 1 end 1.upto(10) do |card| puts "#{card}:t#{counts[card]}" end 输出类似于以下内容: 1: 4942 2: 5100 3: 4938 4: 4960 5: 5024 6: 4992 7: 5184 8: 4930 9: 4916 10: 5014 假设我想用新类替换伪随机数生成器.由于在上面的例子中,Array #shuffle似乎使用Random#rand,因此实现一个新的类来充当用于混洗的RNG似乎很简单.在这里,我实现了一个新的伪随机数生成器,它实际上只是一个围绕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 do counts[deck.shuffle(random: rng).first] += 1 end 1.upto(10) do |card| puts "#{card}:t#{counts[card]}" end 然而,这并不像预期的那样运作.调用FooRandom #rand,但是shuffling会产生以下分布: 1: 0 2: 5423 3: 5562 4: 5544 5: 5512 6: 5569 7: 5535 8: 5595 9: 5524 10: 5736 如您所见,在数组被洗牌后,数组值1永远不会出现在数组的第一个位置.任何人都知道为什么? 解决方法
有一个
bug in Ruby 2.0.0p0,限制是一个.
这已在Ruby 2.0.0p195中修复,因此您应该升级您的安装. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |