200回ぐらい回せば大体、Weightに従って分布してくる…と思う。
def wrr(addr_weights, n) addrs = [] ary = [] addr_weights.each do |a, w| w.times { ary << a } end ary = ary.sort_by{ rand } loop do addrs << ary.shift addrs.uniq! if addrs.size >= n or ary.empty? break end end return addrs end h = {} ipaddrs = [ ['10.0.0.1', 100], ['10.0.0.2', 150], ['10.0.0.3', 50], ['10.0.0.4', 100], ['10.0.0.5', 200] ] 200.times { wrr(ipaddrs, 2).each do |i| h[i] ||= 0 h[i] += 1 end } sum = h.values.inject(0) {|r, i| r + i } h.sort_by {|a, b| a }.each {|i, n| puts '%s=%3d (%.2f)' % [i, n, n.to_f / sum * 100] }
~$ ruby test.rb
10.0.0.1= 66 (16.50)
10.0.0.2=104 (26.00)
10.0.0.3= 42 (10.50)
10.0.0.4= 70 (17.50)
10.0.0.5=118 (29.50)
~$ ruby test.rb
10.0.0.1= 70 (17.50)
10.0.0.2=100 (25.00)
10.0.0.3= 39 (9.75)
10.0.0.4= 72 (18.00)
10.0.0.5=119 (29.75)
~$ ruby test.rb
10.0.0.1= 76 (19.00)
10.0.0.2= 93 (23.25)
10.0.0.3= 35 (8.75)
10.0.0.4= 64 (16.00)
10.0.0.5=132 (33.00)
~$