Random goods by weight

For example, I have this data:

headings = { :heading1 => { :weight => 60, :show_count => 0} :heading2 => { :weight => 10, :show_count => 0} :heading3 => { :weight => 20, :show_count => 0} :heading4 => { :weight => 10, :show_count => 0} } total_views = 0 

Now I want to serve each heading based on their weights. For example, for the first 10 queries / iterations, heading1 , heading3 , heading2 and heading4 will be serviced 6, 2, 1 and 1 times, respectively, in order (by weight).

For each iteration, the show_count of the served header will increase by one, and total_views will also increase worldwide.

Could you suggest an algorithm or some ruby ​​code to handle this.

+3
source share
2 answers

This should work for your main case and can be changed according to the details you need:

  class Heading attr_reader :heading, :weight, :show_count def initialize(heading,weight=1) @heading=heading @weight=weight @show_count=0 end def serve puts "Served #{@heading}! " @show_count += 1 end end class HeadingServer attr_reader :headings def initialize(headings_hash) @headings=headings_hash.map {|h, data| Heading.new(h,data[:weight])} @ total_weight=@headings.inject (0) {|s,h| s+= h.weight} end def serve( num_to_serve=@total _weight) @headings.sort {|a,b| b.weight <=> a.weight}.each do |h| n = (h.weight * num_to_serve) / @total_weight #possibility of rounding errors n.times { h.serve } end end def total_views @headings.inject(0) {|s,h| s += h.show_count} end end headings = { :heading1 => { :weight => 60, :show_count => 0}, :heading2 => { :weight => 10, :show_count => 0}, :heading3 => { :weight => 20, :show_count => 0}, :heading4 => { :weight => 10, :show_count => 0} } # Example Usage: hs = HeadingServer.new(headings) hs.serve(10) hs.headings.each {|h| puts "#{h.heading} : served #{h.show_count} times"} puts "Total Views: #{hs.total_views}" 
+2
source

You can use a pickup gem

It accepts the hash as follows:

 require 'pickup' headings = { heading1: 60, heading2: 10, heading3: 20, heading4: 10 } pickup = Pickup.new(headings) pickup.pick #=> heading1 pickup.pick #=> heading1 pickup.pick #=> heading3 pickup.pick #=> heading1 pickup.pick #=> heading4 

So you can do something like this:

 require 'pickup' headings = { heading1: { :weight => 60, :show_count => 0}, heading2: { :weight => 10, :show_count => 0}, heading3: { :weight => 20, :show_count => 0}, heading4: { :weight => 10, :show_count => 0} } pickup_headings = headings.inject({}){ |h, (k,v)| h[k] = v[:weight]; h} pickup = Pickup.new(pickup_headings) # let fire it 1000 times 1000.times do server = pickup.pick headings[server][:show_count] += 1 end puts headings #=> { #=> :heading1=>{:weight=>60, :show_count=>601}, #=> :heading2=>{:weight=>10, :show_count=>116}, #=> :heading3=>{:weight=>20, :show_count=>176}, #=> :heading4=>{:weight=>10, :show_count=>107} #=> } 
+6
source

Source: https://habr.com/ru/post/1341818/


All Articles