Ask a Question related to PERL Beginners, Design and Development.
-
Charles Lu #1
simple probability problem using PERL
Hi
If I want to randomly generate a dice (4 side) roll, I can use the
following expression:
$roll = 1 + int( rand(4));
This assumes that every side of this dice has equal chance of being rolled
(0.25). Thats easy. Now What if I say, that the probability of rolling a 3
is 70% and the probability of rolling a 1 or 2 or 4 is 10%.
i.e.
$probability = { '1' => 0.1,
'2' => 0.1,
'3' => 0.7,
'4 => 0.1
}
Notice the total probability still addes up to 1. So If I want to roll this
"loaded" dice, how should I modify the above code to accurately reflect the
different weight of this new dice? Any suggestion would be appreciated.
Thanks.
Charles
__________________________________________________ _______________
Get a FREE online virus check for your PC here, from McAfee.
[url]http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963[/url]
Charles Lu Guest
-
Nested arrays & probability
Let say I have a 2D array; myarray="A" myarray="B" myarray="C" myarray="D" myarray="E" myarray="F" -
Simple db - PERL vs MS SQL Server
Hi all, I currently have a very simple, fairly small (25,000 records), one table database in MS SQL Server that is accessed for read only & read... -
perl simple cms
Andrew Crook wrote: See HTML::Template from CPAN -- David Dorward http://dorward.me.uk/ -
simple perl script
Hi, I would like to write a perl script to open and file and add a prefix to all the lines of that file. The file will be like: name1blah... -
Make Huge $$$$'s through Statistics & Probability
First off, I don't need your money, What I need is for you to PAY ATTENTION. THAT IS ALL. I will show you how I make a 100% profit on 75% of my... -
James Edward Gray II #2
Re: simple probability problem using PERL
On Jan 24, 2004, at 5:31 PM, Charles Lu wrote:
How about something like this:> Hi
>
> If I want to randomly generate a dice (4 side) roll, I can use the
> following expression:
>
> $roll = 1 + int( rand(4));
>
> This assumes that every side of this dice has equal chance of being
> rolled (0.25). Thats easy. Now What if I say, that the probability
> of rolling a 3 is 70% and the probability of rolling a 1 or 2 or 4 is
> 10%.
>
> i.e.
> $probability = { '1' => 0.1,
> '2' => 0.1,
> '3' => 0.7,
> '4 => 0.1
> }
>
> Notice the total probability still addes up to 1. So If I want to
> roll this "loaded" dice, how should I modify the above code to
> accurately reflect the different weight of this new dice? Any
> suggestion would be appreciated. Thanks.
sub roll_loaded_die {
my $roll = rand;
if ($roll <= .1) { return 1; }
elsif ($roll <= .2) { return 2; }
elsif ($roll <= .3) { return 4; }
else { return 3; }
}
Hope that helps.
James
James Edward Gray II Guest
-
Drieux #3
Re: simple probability problem using PERL
On Jan 24, 2004, at 3:31 PM, Charles Lu wrote:
What if you did it the other way around?> $probability = { '1' => 0.1,
> '2' => 0.1,
> '3' => 0.7,
> '4 => 0.1
> }
my $probability= {0 => 1, 1 => 2, 9 => 4};
my $value = 10;
for(my $i= 0 ; $i <$value ; $i++ )
{
$probability->{$i} = 3
unless(exists($probability->{$i}));
}
my $roll = int(rand($value));
print " \$roll is => $roll = shows side $probability->{$roll} \n";
notice we will wind up with ten elements in the hash ref,
and we have already assigned our basics...
Or you could have gone with a list.
my @probability = qw/1 2 3 3 3 3 3 3 3 4/;
my $value = 10;
my $roll = int(rand($value));
print " \$roll is => $roll = shows side $probability[$roll] \n";
ciao
drieux
---
Drieux Guest
-
Charles K. Clarkson #4
RE: simple probability problem using PERL (long)
Charles Lu <charlu76@hotmail.com> wrote:
:
: If I want to randomly generate a dice (4 side) roll, I can use
: the following expression:
:
: $roll = 1 + int( rand(4));
:
: This assumes that every side of this dice has equal chance of
: being rolled (0.25). Thats easy. Now What if I say, that the
: probability of rolling a 3 is 70% and the probability of rolling
: a 1 or 2 or 4 is 10%.
:
: i.e.
: $probability = { '1' => 0.1,
: '2' => 0.1,
: '3' => 0.7,
: '4' => 0.1,
: }
:
: Notice the total probability still addes up to 1. So If I want
: to roll this "loaded" dice, how should I modify the above code
: to accurately reflect the different weight of this new dice?
Perhaps this is overkill, but ...
Well, okay it is overkill, but I was bored and thought:
Why stop at just four sides?
And what about 1-sided dice for testing?
And unloaded dice?
#!/usr/bin/perl
use strict;
use warnings;
#use Data::Dumper;
#
load_die(
1 => 0.1,
2 => 0.1,
3 => 0.7,
4 => 0.1,
);
printf "%s\n", roll_loaded_die() foreach ( 0 .. 9 );
printf "%s\n", roll_unloaded_die() foreach ( 0 .. 9 );
#
load_die(
'misses' => 1/3,
'hits' => 1/2,
'loses weapon' => 2/18,
'killed it' => 1/18,
'Huh!' => 0, # just because! :)
);
printf "Boris %s!\n", roll_loaded_die() foreach ( 0 .. 39 );
printf "Boris %s!\n", roll_unloaded_die() foreach ( 0 .. 39 );
printf "On the last roll Boris %s.\n", last_roll();
#
load_die(
1 => 1/100,
2 => 1/100,
3 => 1/100,
4 => 1/100,
5 => 1/100,
6 => 1/100,
7 => 1/100,
8 => 1/100,
9 => 1/100,
10 => 2/100,
11 => 2/100,
12 => 2/100,
13 => 2/100,
14 => 2/100,
15 => 2/100,
16 => 2/100,
17 => 2/100,
18 => 2/100,
19 => 2/100,
20 => 2/100,
21 => 11/100,
22 => 11/100,
23 => 11/100,
24 => 11/100,
25 => 11/100,
26 => 14/100,
);
printf "%s\n", roll_loaded_die() foreach ( 0 .. 39 );
{
# these variables are only accessible within this scope
# the subroutines in here can "see" them, but not the main
# program
my %sides; # holds die side names and probabilities
my $sum; # used as a check for total probability
my $last_roll; # remembers the last roll of the die
sub load_die {
die "load_die() expected a list of sides and probabilities"
unless @_ > 1;
die "load_die() expected even number of arguments.\n"
if @_ % 2;
$sum = 0;
%sides = ();
my %probability = @_;
foreach my $value ( sort { $a <=> $b } values %probability ) {
die "Sorry, no imaginary dice!" if $value < 0;
# cumulate values
$sum += sprintf '%.5f', $value;
# store cumulative probabilities
$value = $sum;
}
# print Dumper \%probability;
# precision is just a guess - needs testing
die "load_die() expected sides to sum to 1.\n"
unless $sum > .9999 && $sum < 1.0001;
# each value is now unique
# convert human-readable format
# to algorithm-readable format
%sides = reverse %probability;
# print Dumper \%sides;
}
# once the die is loaded it can be rolled multiple times
sub roll_loaded_die {
die "Please load the side ratios first.\n"
unless keys %sides;
my $roll = rand;
foreach my $probability ( sort { $a <=> $b } keys %sides ) {
next if $roll > $probability;
$last_roll = $sides{ $probability };
last;
}
return $last_roll;
}
sub roll_unloaded_die {
die "Please load the side ratios first.\n"
unless keys %sides;
# the first 'values %sides' is in list context and
# the second is in scalar context :)
$last_roll = ( values %sides )[ rand values %sides ];
return $last_roll;
}
# return the last roll
sub last_roll {
return $last_roll;
}
}
HTH,
Charles K. Clarkson
--
Head Bottle Washer,
Clarkson Energy Homes, Inc.
Mobile Home Specialists
254 968-8328
Alright, I said I was bored!
Charles K. Clarkson Guest
-
Steve Grazzini #5
Re: simple probability problem using PERL
Charles Lu wrote:
You can use the "pick a random line" algorithm from the FAQ:> If I want to randomly generate a dice (4 side) roll, I can use the
> following expression:
>
> $roll = 1 + int( rand(4));
>
> This assumes that every side of this dice has equal chance of being
> rolled (0.25). Thats easy. Now What if I say, that the probability of
> rolling a 3 is 70% and the probability of rolling a 1 or 2 or 4 is 10%.
>
> i.e.
> $probability = { '1' => 0.1,
> '2' => 0.1,
> '3' => 0.7,
> '4' => 0.1
> }
sub roll {
my $die = shift;
my $result;
my $total = 0;
while (my ($face, $weight) = each %$die) {
$result = $face if rand($total += $weight) < $weight;
}
return $result;
}
--
Steve
Steve Grazzini Guest



Reply With Quote

