Re: Need help with number generator
by ferrency (Deacon) on Aug 09, 2000 at 23:40 UTC
|
Your answer is good and short for the small case you need to solve now; but that method could get out of hand if you need to solve the more general problem of picking randomly from a weighted set of items.
In that case, and answer similar to Gryn's would be more appropriate.
There was another thread at Biased random number selection which has information on how to optimize the selection process for speed.
But here's the most straightforward (but not necessarily fastest... and not tested) solution:
# A list of weights; initialized for your problem
my @weights = (8, 1, 1);
# Count the total of all the counts
my $sum;
map { $sum += $_; } @weights;
# Choose a random number, then find a weighted random result
my $target = rand($sum);
for (1..@weights) {
$target -= $weights[$_];
last if $target <= 0;
}
print "The number is $_\n";
Hope this helps.
Alan | [reply] [d/l] |
Roulette wheel
by gryng (Hermit) on Aug 09, 2000 at 23:21 UTC
|
(warning all code untested)
If you aren't worried about space, then that approach is fine enough, but perhaps:
@a = split /\s+/, join " ",
("1 " x 8, "2 " x 1, "3 " x 1);
print $a[int(rand 10)];
Is more(?) clear?
However, I would not approach it this way. Instead, I would do something like:
my %wheel = {"One" => 8, "Two" => 1, "Three" => 1};
my $sum;
my $item;
foreach $item (keys %wheel) {
$sum+=$wheel{$item};
}
my $spin = int(rand($sum));
foreach $item (keys %wheel) {
last if $sum < $wheel{$item};
$sum-=$wheel{$item};
}
print "$item was picked\n";
I think that will work, if not, you should at least get the general idea.
G'Luck!
Gryn | [reply] [d/l] [select] |
Re: Need help with number generator
by Boogman (Scribe) on Aug 09, 2000 at 23:49 UTC
|
how about
$random = 2 + ( 8 <=> int( rand( 10 ) ) );
The <=> returns -1, 0, or 1, so you'll get -1 + 2 = 1 if its less
than 8, 2 if its equal to 8, or 3 if it is greater than 8. | [reply] [d/l] |
|
|
This idea rocks. But I think this is correct
$random = 2 + ( int( rand( 10 ) ) <=> 8 );
this will make
$random = 1 ...... 80% of the time
$random = 2 ...... 10% of the time
$random = 3 ...... 10% of the time | [reply] [d/l] |
Re: Need help with number generator
by turnstep (Parson) on Aug 10, 2000 at 00:15 UTC
|
($x) = map { $_<1 ? 2 : $_<2 ? 3 : 1} rand 9;
| [reply] [d/l] |
Re: Need help with number generator
by BlueLines (Hermit) on Aug 09, 2000 at 23:43 UTC
|
here's another approach that assumes rand is actually random, which it technically isn't (see Math::TrulyRandom):
my $seed=rand;
my $result=($seed>=0) + ($seed>=.8) + ($seed>=.9);
print "$result\n";
BlueLines
Disclaimer: This post may contain inaccurate information, be habit forming, cause atomic warfare between peaceful countries, speed up male pattern baldness, interfere with your cable reception, exile you from certain third world countries, ruin your marriage, and generally spoil your day. No batteries included, no strings attached, your mileage may vary. | [reply] [d/l] [select] |
Re: Need help with number generator
by jettero (Monsignor) on Aug 09, 2000 at 23:44 UTC
|
use strict;
my %odds = ( 1 => 80, 2 => 10, 3 => 10 );
for my $i (1..25) {
print "$i: ", &go, "\n";
}
sub go {
my $i = int(rand(100) + 1);
foreach my $k (keys %odds) {
$i -= $odds{$k};
return $k if $i <= 0;
}
return undef;
}
| [reply] [d/l] |
Re: Need help with number generator
by lolindrath (Scribe) on Aug 09, 2000 at 23:41 UTC
|
$randnum = int(rand(100));
if ( $randnum > 20 ) #80%
{
#stuff for 1
}
if ( $randnum > 90 ) #10%
{
#stuff for 2 and 3
}
--=Lolindrath=-- | [reply] [d/l] |
|
|
I don't want to be picky, but that would do
#stuff for 1 70% of the time.
It would do #stuff for 1
_and_ #stuff for 2 and 3 10% of the time.
And 20% of the time it would do nothing...
Remember to think before you code! :-P
cmburns
| [reply] [d/l] [select] |
RE: Need help with number generator
by sinan (Sexton) on Aug 10, 2000 at 15:36 UTC
|
I also need something like that, but what I want to do is
a little bit more complicated. I need to generate random
numbers using the standard distribution, that is, I want the
numbers in the middle to have a higher frequency than the
others.
Does anybody know an algorithm that does this?
Sinan | [reply] |
|
|
my @weights = qw(0.5 1 2);
my @random = sort {$a <=> $b} map{rand()} 0..$#weights;
my $tot;
foreach (0..$#weights) {
$tot += $random[$_] * $weights[$_];
}
print $tot;
| [reply] [d/l] |
RE: Need help with number generator
by Adam (Vicar) on Aug 09, 2000 at 23:41 UTC
|
This sounds suspiciously like a home work assignment.
Update: My apologies. I remember having that exact question in a first year cs class. I don't want to encourage CS students to post their home work and submit our answers. | [reply] |
|
|
I'm done with school, for now.
The question is for redirection of traffic at my company's website. There are two homepage test pages, and my boss wants 10% of our traffic directed to each.
Even if it was homework, isn't it a cool problem?
| [reply] |