Summary
Functions
Given a non-empty list (or range) of possible outcomes, and a list of weight maps, build a struct that can later be passed into WeightedRandom.take/2 for very fast random sampling.
Given a non-empty list of percentages (floats from 0.0 - 1.0), build the struct.
Returns a random value based on the weights given.
If you need a lot of random numbers over time, this is suboptimal and you should use preprocess + take instead.
similar to rand/3 but instead of a list of outcomes, and a list of weights, rand_p/3 accepts a list of probability floats.
If you need a lot of random numbers over time, this is suboptimal and you should use preprocess + take instead.
Given a WeightedRandom struct, return a single random value.
Given a WeightedRandom struct, return a list of random values
Functions
@spec preprocess( WeightedRandom.Utils.Types.outcomes(), [WeightedRandom.Utils.Types.weight_spec()], WeightedRandom.Utils.Types.opts() ) :: WeightedRandom.Backend.t()
Given a non-empty list (or range) of possible outcomes, and a list of weight maps, build a struct that can later be passed into WeightedRandom.take/2 for very fast random sampling.
Examples
iex> r = WeightedRandom.preprocess(0..10, [%{target: 2, amount: 1000}])
iex> li = WeightedRandom.take(r, 5)
[2, 2, 2, 2, 2]Supported options:
:backend(atom/0) - Required. Any module which implements the @behaviour:WeightedRandom.Backend. This is the core algorithm providing the randomness functionality.:precision(pos_integer/0) - The number of decimal places to use when rounding. Leave nil for no rounding.:tolerance(float/0) - When WeightedRandom automatically normalizes your probabilities to make sure they add up to 1.0, sometimes they are off slightly due to floating point precision issues. How close does it need to be? By default we use 1.0e-10, which means that: 0.99 is NOT close enough, but 0.9999999999 is close enough. The default value is1.0e-10.:outcome_type- When you take a random sample, will it return the index of an outcome, or the value?index:pick random indices from the list of outcomes. For example if your outcomes are125..130then the results will be between0and5.value:pick random values from the list of outcomes. For example if your outcomes are125..130then the results will be between125and130.
The default value is
:index.
@spec preprocess_p( WeightedRandom.Utils.Types.probabilities(), WeightedRandom.Utils.Types.opts() ) :: WeightedRandom.Backend.t()
Given a non-empty list of percentages (floats from 0.0 - 1.0), build the struct.
Next, pass the resulting struct into WeightedRandom.take/2 to get rand
Examples
iex> r = WeightedRandom.preprocess_p([0.01, 0.01, 0.98])
iex> li = WeightedRandom.take(r, 5)
[2, 2, 2, 2, 2]Supported options:
:backend(atom/0) - Required. Any module which implements the @behaviour:WeightedRandom.Backend. This is the core algorithm providing the randomness functionality.:precision(pos_integer/0) - The number of decimal places to use when rounding. Leave nil for no rounding.:tolerance(float/0) - When WeightedRandom automatically normalizes your probabilities to make sure they add up to 1.0, sometimes they are off slightly due to floating point precision issues. How close does it need to be? By default we use 1.0e-10, which means that: 0.99 is NOT close enough, but 0.9999999999 is close enough. The default value is1.0e-10.
@spec rand( outcomes :: WeightedRandom.Utils.Types.outcomes(), weights :: [WeightedRandom.Utils.Types.weight_spec()], WeightedRandom.Utils.Types.opts() ) :: any()
Returns a random value based on the weights given.
If you need a lot of random numbers over time, this is suboptimal and you should use preprocess + take instead.
Supported options:
:precision(pos_integer/0) - The number of decimal places to use when rounding. Leave nil for no rounding.:tolerance(float/0) - When WeightedRandom automatically normalizes your probabilities to make sure they add up to 1.0, sometimes they are off slightly due to floating point precision issues. How close does it need to be? By default we use 1.0e-10, which means that: 0.99 is NOT close enough, but 0.9999999999 is close enough. The default value is1.0e-10.:outcome_type- When you take a random sample, will it return the index of an outcome, or the value?index:pick random indices from the list of outcomes. For example if your outcomes are125..130then the results will be between0and5.value:pick random values from the list of outcomes. For example if your outcomes are125..130then the results will be between125and130.
The default value is
:index.:take(pos_integer/0) - If used, then instead of returning one random value, will return a list (size == :take) of random values:backend(atom/0) - Any module which implements the @behaviour:WeightedRandom.Backend. This is the core algorithm providing the randomness functionality.
@spec rand_p( WeightedRandom.Utils.Types.probabilities(), WeightedRandom.Utils.Types.opts() ) :: any()
similar to rand/3 but instead of a list of outcomes, and a list of weights, rand_p/3 accepts a list of probability floats.
If you need a lot of random numbers over time, this is suboptimal and you should use preprocess + take instead.
Supported options:
:backend(atom/0) - Any module which implements the @behaviour:WeightedRandom.Backend. This is the core algorithm providing the randomness functionality.:precision(pos_integer/0) - The number of decimal places to use when rounding. Leave nil for no rounding.:tolerance(float/0) - When WeightedRandom automatically normalizes your probabilities to make sure they add up to 1.0, sometimes they are off slightly due to floating point precision issues. How close does it need to be? By default we use 1.0e-10, which means that: 0.99 is NOT close enough, but 0.9999999999 is close enough. The default value is1.0e-10.:take(pos_integer/0) - If used, then instead of returning one random value, will return a list (size == :take) of random values
@spec take(WeightedRandom.Backend.t()) :: any()
Given a WeightedRandom struct, return a single random value.
Examples
iex> r = WeightedRandom.preprocess(0..10, [%{target: 2, amount: 1000}])
iex> li = WeightedRandom.take(r)
2
@spec take(WeightedRandom.Backend.t(), count :: integer()) :: list()
Given a WeightedRandom struct, return a list of random values
Examples
iex> # Make the item at index 2 1000x more likely than any other single index.
iex> r = WeightedRandom.preprocess(0..10, [%{target: 2, amount: 1000}])
iex> li = WeightedRandom.take(r, 3)
[2, 2, 2]