Class: WeightedDistribution

Inherits:
Object
  • Object
show all
Defined in:
lib/weighted_distribution.rb

Overview

Note:

Mostly adapted from recipe 5.11 from the Ruby Cookbook.

Implements randomization of weighted objects. Constructor expects a hash of object => weight pairs where the weight represents the probability of the corresponding object being selected. follows specification of ryanlecompte’s WeightedRandomizer re-implements the sample function to run in O(log(n)) rather than O(n).

Examples:

Usage

suit_dist = WeightedDistribution.new({heart: 12, spade: 11, diamond: 10, club:13})
puts "you picked a #{suit_dist.sample}"

Instance Method Summary collapse

Constructor Details

#initialize(object_weights, randomizer = Kernel) ⇒ WeightedDistribution

Creates a new instance of the WeightedDistribution Class

weights(key object, value weight)

Parameters:

  • object_weights (Hash)

    objects with their corresponding



20
21
22
23
24
25
26
27
# File 'lib/weighted_distribution.rb', line 20

def initialize(object_weights, randomizer = Kernel)
  @len = object_weights.length
  @keys = object_weights.keys
  @orig_values = @keys.map{|x| object_weights[x]}
  @values = normalize(@orig_values)
  @csum = cumulative_sum(@values)
  @randomizer = randomizer
end

Instance Method Details

#sample(num = nil) ⇒ Object+

Samples from the WeightedDistribution. Each object has a probability of being selected equal to its weight over the total sum of all the object weights. Can specify a number of samples to obtain from distribution with the num argument.

Parameters:

  • num (Integer) (defaults to: nil)

    the number of samples to return (optional)

Returns:

  • (Object, Array<Object>)

    one or more sampled objects.



36
37
38
39
40
# File 'lib/weighted_distribution.rb', line 36

def sample(num = nil)
  return _sample unless num
  num = 0 if num < 0
  Array.new(num) { _sample }
end