Current state of the project

Version 1.0.0: In alpha. Actively being developed.

Version 0.4.x: Stable.

Improvements in v1.0.0:

  • Significant performance Improvements
  • Support for probabilities, not just weights
  • Better user experience and quality of life improvements
  • Polished docs and a livebook tutorial
  • swappable backends, not locked into any particular algorithm.

Docs

See Hex docs. Documentation will not be kept in the README.

Examples

Uniform random

for 1..5000 do
  Enum.random(0..3)
end

Uniform


probabilities = [
  0.3, 0.05, 0.6, 0.05
]
WeightedRandom.preprocess_p(probabilities)
|> WeightedRandom.take(1000)

Probabilities

# Weights offer an alternative paradigm to probabilities.
# By default, every number has a weight of 1.0
# Let's add a little weight to the outcome of 2 for a total of 1.8

#### Controls ####
outcomes = 0..3
weights = [
  %{target: 2, amount: 0.8}
]
####


WeightedRandom.preprocess(outcomes, weights)
|> WeightedRandom.take(5000)

Small Weight

WeightedRandom integrates well with the Curves library.

####
# By using different predefined curves, we clearly get very distinct shapes
# (Of course, some curves work better than others when doing this)

curve = :ease_in_out
outcomes = 0..100
weights = [%{target: 50, amount: 100, radius: 25, curve: curve}]
####


WeightedRandom.preprocess(outcomes, weights)
|> WeightedRandom.take(1_000_000)

Ease In Out

#### Define your own bezier curve ####
curve = [
  {0, 0},
  {0.33, -4},
  {0.67, 4},
  {1, 1}
]
outcomes = 0..100
weights = [%{target: 50, amount: 200, radius: 25, curve: curve}]
####


WeightedRandom.preprocess(outcomes, weights)
|> WeightedRandom.take(1_000_000)

Custom Curve