[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

sample from an array of weighted elements

Robo

5/19/2006 12:13:00 PM

I got the following piece of perl code, and trying to convert it to Ruby.

I THINK what it's doing is from an array of floats, it has to select a
random element, where the larger values have more chance of getting
selected. So if weights = [0.2, 0.5, 0.1, 0.3], there'll be a higher
chance of the method returning index 1 (0.5).

Don't take my word only though...that's all I can make out of it. In
particular the line I don't get is $sample = $i if rand $count [$i];

Robo

# Function to sample from an array of weighted elements
# originally written by Abigail <abigail@foad.org>
sub sample
{
# get the reference to the weights array
my $weights = shift @_ or return undef;
# internal counting variables
my ($count, $sample);

for (my $i = 0; $i < scalar @$weights; $i ++)
{
$count += $weights->[$i];
$sample = $i if rand $count [$i];
}

# return an index into the weights array
return $sample;
}
3 Answers

ts

5/19/2006 1:00:00 PM

0

>>>>> "R" == Robo <robo@mars.com> writes:

R> $sample = $i if rand $count [$i];

See

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

Sorry,

http://www.bigbold.com/snippets/post...

Not verified


--

Guy Decoux

lloyd@binaryten.com

5/19/2006 1:04:00 PM

0

Have you tested this code? Also, can you specify exactly what you need
the code to do?

Robert Klemme

5/19/2006 3:39:00 PM

0

Robo wrote:
> I got the following piece of perl code, and trying to convert it to Ruby.
>
> I THINK what it's doing is from an array of floats, it has to select a
> random element, where the larger values have more chance of getting
> selected. So if weights = [0.2, 0.5, 0.1, 0.3], there'll be a higher
> chance of the method returning index 1 (0.5).
>
> Don't take my word only though...that's all I can make out of it. In
> particular the line I don't get is $sample = $i if rand $count [$i];
>
> Robo
>
> # Function to sample from an array of weighted elements
> # originally written by Abigail <abigail@foad.org>
> sub sample
> {
> # get the reference to the weights array
> my $weights = shift @_ or return undef;
> # internal counting variables
> my ($count, $sample);
>
> for (my $i = 0; $i < scalar @$weights; $i ++)
> {
> $count += $weights->[$i];
> $sample = $i if rand $count [$i];
> }
>
> # return an index into the weights array
> return $sample;
> }

def calc(weights)
r = weights.inject(0){|s,x|s+x} * rand
weights.inject(0) {|s,x| s+=x; return x if s>=r;s}
weights[-1]
end

>> 1_000_000.times { stat[ calc([0.2, 0.5, 0.1, 0.3]) ] += 1 }
=> 1000000
>> stat.each {|k,v| printf "%4.2f %4.2f\n", k, v/1_000_000.0}
0.20 0.18
0.30 0.27
0.10 0.09
0.50 0.45
=> {0.2=>182062, 0.3=>272793, 0.1=>90784, 0.5=>454361}

Kind regards

robert