class RouletteWheelSelection

Constants

NOT_SET
VERSION

Public Class Methods

new(hash) click to toggle source
# File lib/roulette-wheel-selection.rb, line 30
def initialize(hash)
  @hash = hash
  @total_rate = hash.values.inject(0, :+)
end
sample(*args) click to toggle source
# File lib/roulette-wheel-selection.rb, line 9
def sample(*args)
  object = args.first
  case object
  when Array ; sample_from_array(*args)
  when Hash  ; sample_from_hash(*args)
  else       ; fail "Unsupported type: #{object.class}"
  end
end

Private Class Methods

sample_from_array(array, key) click to toggle source
# File lib/roulette-wheel-selection.rb, line 20
def sample_from_array(array, key)
  hash = array.map{|v| [v, v[key]] }.to_h
  return sample_from_hash(hash)
end
sample_from_hash(hash) click to toggle source
# File lib/roulette-wheel-selection.rb, line 25
def sample_from_hash(hash)
  RouletteWheelSelection.new(hash).sample
end

Public Instance Methods

sample(num = NOT_SET) click to toggle source
# File lib/roulette-wheel-selection.rb, line 35
def sample(num = NOT_SET)
  return if @total_rate == 0
  return sample_an_object(@total_rate, @hash) if num == NOT_SET
  return if num < 1
  return sample_n_objects(num) if num > 1
  return [sample_an_object(@total_rate, @hash)]
end

Private Instance Methods

sample_an_object(total_rate, hash) click to toggle source
# File lib/roulette-wheel-selection.rb, line 57
def sample_an_object(total_rate, hash)
  random_seed = rand(total_rate)
  hash.each do |obj, rate|
    return obj if random_seed < rate
    random_seed -= rate
  end
end
sample_n_objects(num) click to toggle source
# File lib/roulette-wheel-selection.rb, line 45
def sample_n_objects(num)
  hash = @hash.clone
  total_rate = @total_rate
  num = total_rate if num > total_rate
  return Array.new(num) do
    obj = sample_an_object(total_rate, hash)
    hash[obj] -= 1
    total_rate -= 1
    next obj
  end
end