Class: LoadedDie::Sampler
- Inherits:
-
Object
- Object
- LoadedDie::Sampler
- Defined in:
- lib/loaded_die.rb
Overview
Objects of this class can choose randomly from a set of options (called individuals here). The options can have different probabilities of being chosen.
Defined Under Namespace
Classes: Segment
Constant Summary collapse
- DEFAULT_RNG =
The default random number generator.
::Object.new
Instance Method Summary collapse
-
#[](point) ⇒ Object
Returns the individual for the given point.
-
#initialize(population) ⇒ Sampler
constructor
Creates a sampler from a population.
-
#length ⇒ Object
Returns the sum of weights.
-
#sample(options = {}) ⇒ Object
Returns a randomly-chosen individual.
Constructor Details
#initialize(population) ⇒ Sampler
Creates a sampler from a population. The argument should be an enumerable of two-element arrays (a hash qualifies). The first element of each array is an individual that can be chosen; the second element is its weight – that is, the likelihood (relative to the other weights) that the individual will be chosen. Weights must be positive numbers.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/loaded_die.rb', line 40 def initialize(population) @compiled = population.inject [] do |accum, (individual, weight)| if weight <= 0 raise ::ArgumentError, "non-positive weight #{weight}" end prev_max = if last = accum.last last.maximum else 0 end accum << Segment.new(prev_max + weight, individual) end nil end |
Instance Method Details
#[](point) ⇒ Object
Returns the individual for the given point. The point should be a number. If it is greater than or equal to zero and less than the sum of weights, this returns the corresponding individual. If it is outside those bounds, this returns nil.
73 74 75 76 77 78 79 80 81 |
# File 'lib/loaded_die.rb', line 73 def [](point) if point < 0 nil elsif choice = @compiled.detect { |segment| point < segment.maximum } choice.individual else nil end end |
#length ⇒ Object
Returns the sum of weights.
59 60 61 62 63 64 65 |
# File 'lib/loaded_die.rb', line 59 def length if last = @compiled.last last.maximum else 0 end end |
#sample(options = {}) ⇒ Object
Returns a randomly-chosen individual. The argument is a hash, empty by default. If it contains a value for the :random key, that value will be used as the random number generator instead of the default. This RNG will be sent a “rand” message with one argument, the sum of weights, and should return a number greater than or equal to zero and less than the sum of weights.
91 92 93 94 95 |
# File 'lib/loaded_die.rb', line 91 def sample( = {}) rng = .fetch(:random) { DEFAULT_RNG } point = rng.rand(length) self[point] end |