Reputation: 373
I'm coding my university assignment that is somewhat connected with distributions and random roll stuff. So the question is: how to get a random number with a given discrete distribution in Ruby.
To be more specific: in trivial example with normal discrete distribution like (0 with P=1/2; 1000 with P=1/2) I could write such a function:
def chooseNumber(a,b)
rval = Random.rand(0..1)
return a if rval == 0
return b
end
First question: is there any way to write it using native Random class?
Second question: what is the best way to deal with distributions like (0 with P=1/5; 2 with P=2/5; 1000 with P=2/5) or even worse (0 with P=0,33; 2 with P=0,49; 1000 with P=0,18)?
Upvotes: 5
Views: 363
Reputation: 83680
I would go with something like this
def pick_with_distribution(distributions)
r = rand
distributions.detect{ |k, d| r -= d; r < 0 }.first
end
distributions = { 0 => 0.33, 2 => 0.49, 1000 => 0.18 }
pick_with_distribution(distributions)
#=> 0
To check if distribution is correct, I run it 10000 times, here is the result:
10000.times.inject({}) do |h, _|
r = pick_with_distribution(distributions)
h[r] ||= 0
h[r] += 1
h
end
#=> {0=>3231, 1000=>1860, 2=>4909}
Upvotes: 5