[RUBY] how do generate a random number w specific distribution ( which library ?)

58 views
Skip to first unread message

Erwin

unread,
Mar 12, 2011, 5:10:27 AM3/12/11
to Ruby on Rails: Talk
I know how to generate a random number between 1 and 2 :

def random
return (1 + rand(2))
end

but let's say I would like to return 1 in 80% of the calls and 2 in
20% of the call...
which library should I use ? ( I've seen a lot at http://raa.ruby-lang.org/
)

thanks for your suggestions

Colin Law

unread,
Mar 12, 2011, 5:37:14 AM3/12/11
to rubyonra...@googlegroups.com

No doubt there are better ways but something like
(rand(100) + 120)/100
should do it.

Colin

Rob Biedenharn

unread,
Mar 12, 2011, 8:42:29 AM3/12/11
to rubyonra...@googlegroups.com


Well, perhaps something that reveals the intention better:

def usually_one
rand < 0.80 ? 1 : 2
end

-Rob

Rob Biedenharn
R...@AgileConsultingLLC.com http://AgileConsultingLLC.com/
r...@GaslightSoftware.com http://GaslightSoftware.com/

Colin Law

unread,
Mar 12, 2011, 9:23:00 AM3/12/11
to rubyonra...@googlegroups.com
On 12 March 2011 13:42, Rob Biedenharn <R...@agileconsultingllc.com> wrote:
>
> On Mar 12, 2011, at 5:37 AM, Colin Law wrote:
>
>> On 12 March 2011 10:10, Erwin <yves_...@mac.com> wrote:
>>>
>>> I know how to generate a random number between 1 and 2 :
>>>
>>> def random
>>>  return (1 + rand(2))

No it doesn't actually. 1 + rand would be better, though it depends
what you mean by *between* whether even that is correct.

>>> end
>>>
>>> but let's say  I would like to return 1 in 80% of the calls and 2 in
>>> 20% of the call...
>>> which library should I use ?  ( I've seen a lot at
>>> http://raa.ruby-lang.org/
>>> )
>>>
>>
>> No doubt there are better ways but something like
>> (rand(100) + 120)/100
>> should do it.
>>
>> Colin
>
>
> Well, perhaps something that reveals the intention better:
>
> def usually_one
>  rand < 0.80 ? 1 : 2
> end

Yes, much better. I suppose it is the old programmer in me
instinctively avoiding floating point to save on processor time. A
bit silly when everything has hardware floating point.

Colin

Michael Pavling

unread,
Mar 12, 2011, 3:47:15 PM3/12/11
to rubyonra...@googlegroups.com

Although I prefer Rob's suggestion as a better example of self
documented code; this is another alternative...

def usually_one
[1,2,2,2,2][rand(5)]
end

...there's many ways to skin a cat :-)

Michael Pavling

unread,
Mar 12, 2011, 3:48:45 PM3/12/11
to rubyonra...@googlegroups.com
On 12 March 2011 20:47, Michael Pavling <pav...@gmail.com> wrote:
>  def usually_one
>    [1,2,2,2,2][rand(5)]
>  end

*ahem* of course.. this is the total opposite of what the OP asked
for, and returns 1 in 20% of the calls :-D

sorry for not paying attention.... oops!

Colin Law

unread,
Mar 12, 2011, 4:07:03 PM3/12/11
to rubyonra...@googlegroups.com

Ha! Vindicated

ruby-1.8.7-p302 > begin
ruby-1.8.7-p302 > t=Time.now
ruby-1.8.7-p302 ?> 1000000.times{(rand(100) + 120)/100}
ruby-1.8.7-p302 ?> puts Time.now-t
ruby-1.8.7-p302 ?> end
0.905431

ruby-1.8.7-p302 > begin
ruby-1.8.7-p302 > t=Time.now
ruby-1.8.7-p302 ?> 1000000.times{rand < 0.80 ? 1 : 2}
ruby-1.8.7-p302 ?> puts Time.now-t
ruby-1.8.7-p302 ?> end
1.712769

ruby-1.8.7-p302 > begin
ruby-1.8.7-p302 > t=Time.now
ruby-1.8.7-p302 ?> 1000000.times{ [1,2,2,2,2][rand(5)] }
ruby-1.8.7-p302 ?> puts Time.now-t
ruby-1.8.7-p302 ?> end
1.150481

> ...there's many ways to skin a cat :-)

But how fast can you do it?

Colin

Michael Pavling

unread,
Mar 12, 2011, 4:36:38 PM3/12/11
to rubyonra...@googlegroups.com
On 12 March 2011 21:07, Colin Law <cla...@googlemail.com> wrote:
> Ha!  Vindicated

I expected to get different times, but to keep the proportions the
same... but I get a little difference in order of speed:

>> begin
?> t=Time.now
>> 1000000.times{(rand(100) + 120)/100}
>> puts Time.now-t
>> end
1.200484

>> begin
?> t=Time.now


>> 1000000.times{rand < 0.80 ? 1 : 2}

>> puts Time.now-t
>> end
1.249109

>> begin
?> t=Time.now
>> 1000000.times{[1,2,2,2,2][rand(5)]}
>> puts Time.now-t
>> end
1.498434

>> ...there's many ways to skin a cat :-)
>
> But how fast can you do it?

A fair bit faster if I don't build the array in every loop ;-)

>> x=[1,2,2,2,2]
=> [1, 2, 2, 2, 2]
>> begin
?> t=Time.now
>> 1000000.times{x[rand(5)]}
>> puts Time.now-t
>> end
1.026202

Colin Law

unread,
Mar 12, 2011, 5:01:55 PM3/12/11
to rubyonra...@googlegroups.com

OK, I admit defeat. I am using ruby 1.8.7 which may be the reason for
the different ratios you are seeing (assuming you are using 1.9.2).
Interestingly the benefit of your technique is even greater on 1.8.7,
taking only 0.67 secs on my machine.

Colin

Michael Pavling

unread,
Mar 12, 2011, 5:16:29 PM3/12/11
to rubyonra...@googlegroups.com
On 12 March 2011 22:01, Colin Law <cla...@googlemail.com> wrote:
> OK, I admit defeat.  the benefit of your technique is even greater on 1.8.7,

> taking only 0.67 secs on my machine.

Nah! Who cares if it takes half-a-second or a second to select a
million random numbers.... any of the methods are perfect for
selecting one number.

Was a nice distraction from the recent run of posts...

Colin Law

unread,
Mar 12, 2011, 5:23:34 PM3/12/11
to rubyonra...@googlegroups.com
On 12 March 2011 22:16, Michael Pavling <pav...@gmail.com> wrote:
> On 12 March 2011 22:01, Colin Law <cla...@googlemail.com> wrote:
>> OK, I admit defeat.  the benefit of your technique is even greater on 1.8.7,
>> taking only 0.67 secs on my machine.
>
> Nah! Who cares if it takes half-a-second or a second to select a
> million random numbers.... any of the methods are perfect for
> selecting one number.

The OP might be doing some statistical simulation, so might need
millions of values, but probably not.

Colin

>
> Was a nice distraction from the recent run of posts...
>

> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
>
>

Conrad Taylor

unread,
Mar 12, 2011, 6:29:05 PM3/12/11
to rubyonra...@googlegroups.com
Here's my number from within and outside IRB from Mac OS 10.6.6:

ruby-1.9.2-head :001 > begin
ruby-1.9.2-head :002 >       t=Time.now
ruby-1.9.2-head :003?>     1000000.times{(rand(100) + 120)/100}
ruby-1.9.2-head :004?>     puts Time.now-t
ruby-1.9.2-head :005?>   end

from-irb: 0.16657  from-ruby-script:  0.159452

ruby-1.9.2-head :006 > begin
ruby-1.9.2-head :007 >       t=Time.now
ruby-1.9.2-head :008?>     1000000.times{rand < 0.80 ? 1 : 2}
ruby-1.9.2-head :009?>     puts Time.now-t
ruby-1.9.2-head :010?>   end

from-irb:  0.280634  from-ruby-script:  0.150247

ruby-1.9.2-head :011 > begin
ruby-1.9.2-head :012 >       t=Time.now
ruby-1.9.2-head :013?>     1000000.times{[1,2,2,2,2][rand(5)]}
ruby-1.9.2-head :014?>     puts Time.now-t
ruby-1.9.2-head :015?>   end

from-irb: 0.521992  from-ruby-script: 0.35944

-Conrad
 

> ...there's many ways to skin a cat :-)

But how fast can you do it?

Colin

Colin Law

unread,
Mar 13, 2011, 4:45:16 AM3/13/11
to rubyonra...@googlegroups.com

I think I need a new laptop.

Colin

Martin Streicher

unread,
Mar 15, 2011, 9:37:57 AM3/15/11
to Ruby on Rails: Talk
I use this often:

class Uuid
def self.uuid
return rand( 18446744073709551615 ).to_s( 36 ).rjust( 13, '0' )
end
end

See http://blog.locomotivellc.com/post/3277434038/unique-ids

On Mar 13, 4:45 am, Colin Law <clan...@googlemail.com> wrote:
> On 12 March 2011 23:29, Conrad Taylor <conra...@gmail.com> wrote:
>
>
>
>
>
> > On Sat, Mar 12, 2011 at 1:07 PM, Colin Law <clan...@googlemail.com> wrote:
>
> >> On 12 March 2011 20:47, Michael Pavling <pavl...@gmail.com> wrote:

Michael Pavling

unread,
Mar 15, 2011, 9:46:26 AM3/15/11
to rubyonra...@googlegroups.com
On 15 March 2011 13:37, Martin Streicher <martin.s...@gmail.com> wrote:
> I use this often:
>
> class Uuid
>  def self.uuid
>    return rand( 18446744073709551615 ).to_s( 36 ).rjust( 13, '0' )
>  end
> end

Nice, simple process (assuming it works... I've not tried it), but I
don't think it has much to do with the topic of this thread, and it's
not likely to create a *real* UUID (RFC4122) is it?

This old thread discusses it a bit:
http://www.ruby-forum.com/topic/164078

Ar Chron

unread,
Mar 15, 2011, 1:14:32 PM3/15/11
to rubyonra...@googlegroups.com
Colin Law wrote in post #987114:

>
> But how fast can you do it?
>

Ooh, that's an evil tweak... (a minor diversion which is much more fun
than what I was doing)

Lenovo T61p, Core2Duo, T9300, 2.5GHz, ruby 1.9.2-p0

= 0.253025

And for curiosity, my Ubuntu 10.10 VM on top of the same hardware:

= 0.323791

--
Posted via http://www.ruby-forum.com/.

Martin Streicher

unread,
Mar 15, 2011, 3:52:44 PM3/15/11
to Ruby on Rails: Talk
I don't think it makes a true UUID, but I've run it into the billions
and never got a repeat. So, effectively, it acts like UUID.
Reply all
Reply to author
Forward
0 new messages