Usage
table = WeightedRandom.preprocess(0..100, [%{target: 25, weight: 50, radius: 10}])
[n1, n2, n3, n4] = WeightedRandom.take(table, 4)Alternately, if you care less about performance, you can do it all at once:
[n1, n2, n3, n4] = WeightedRandom.rand(0..100, [%{target: 25, weight: 50, radius: 10}], [take: 4])But please note the algorithm is optimized to take a long time ( O(n) ) during preprocessing, in order to be very fast during the sampling step ( O(1) ).
So it will be far better to preprocess once, and take many times. rand/3 preprocesses EVERY time it is called.
Summary
Functions
Given a list of outcomes and a list of weights, map the list of outcomes into a list of floats which sum to 1.0 (potentially with rounding errors)
For maximum performance, especially at scale, do this
Returns a random value based on the weights given.
Functions
Given a list of outcomes and a list of weights, map the list of outcomes into a list of floats which sum to 1.0 (potentially with rounding errors)
For maximum performance, especially at scale, do this:
Returns a random value based on the weights given.
By default this operates on the index, not the value.
## Examples
iex> :rand.seed(:exsss, {108, 101, 102})
iex> li = 1..10
iex> weights = [ %{target: 7, weight: 100} ]
iex>
iex> # By default this uses the index 7, not the value 7.
iex> WeightedRandom.rand(li, weights)
8
iex> # But we can use the value by passing the option index: false
iex> WeightedRandom.rand(li, weights, index: false)
7
iex> li = [:a, :b, :c, :d, :e, :f, :g, :h, :j, :k, :l]
iex> WeightedRandom.rand(li, weights)
:h
iex> weights = [ %{target: :d, weight: 100} ]
iex> WeightedRandom.rand(li, weights, index: false)
:d
Opts
:backend[module]: WeightedRandom.Backend.WalkerAlias. We also provide WeightedRandom.Backend.Linear which can have slightly better performance if you are not taking that many samples. Worse performance in most other cases.:index[boolean]: true. Whether the:targetof a%WeightedRandom.Weight{}points at an index of the outcomes (if true), or at the actual value of one of the outcomes (if false).:with_index[boolean]: true. set by backend. Determines whether to callEnum.with_indexon the list of probabilities before preprocessing.:probability_type[:float | :fraction]: :float. To avoid floating point precision issues, you can use :fraction so that the probabilities are all tuples of{numenator :: integer(), denominator :: integer()}In which they all have the same denominator which equals the sum of all numinators.:precision[integer]: 3. Only applies when theprobability_typeis:float. Probability floats will be rounded to this number of decimal places.:take[integer | nil]:nil. If used, then instead of returning one random value, will return a list of random value with size equal to take.