simple probability problem using PERL

Ask a Question related to PERL Beginners, Design and Development.

  1. #1

    Default 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

  2. Similar Questions and Discussions

    1. Nested arrays & probability
      Let say I have a 2D array; myarray="A" myarray="B" myarray="C" myarray="D" myarray="E" myarray="F"
    2. 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...
    3. perl simple cms
      Andrew Crook wrote: See HTML::Template from CPAN -- David Dorward http://dorward.me.uk/
    4. 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...
    5. 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...
  3. #2

    Default Re: simple probability problem using PERL

    On Jan 24, 2004, at 5:31 PM, Charles Lu wrote:
    > 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.
    How about something like this:

    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

  4. #3

    Default Re: simple probability problem using PERL


    On Jan 24, 2004, at 3:31 PM, Charles Lu wrote:
    > $probability = { '1' => 0.1,
    > '2' => 0.1,
    > '3' => 0.7,
    > '4 => 0.1
    > }
    What if you did it the other way around?

    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

  5. #4

    Default 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

  6. #5

    Default Re: simple probability problem using PERL

    Charles Lu 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
    > }
    You can use the "pick a random line" algorithm from the FAQ:

    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

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139