I need to random some elements from an array. I'm doing that by randomizing the index $array[int(rand(100))]
. I want some of the elements to appear more often. How do I do it?
I thought of a stupid solution of having those elements duplicated several times in the array, but I'm sure you guys can do better.
If you know the frequency with which you want the random numbers to appear, you could use the rand() function. Let's say you want the number 0 to appear 33% of the time, and 1 to appear the other 66%. Then you would check if rand() < 0.33, and return some index. Otherwise, return another index. This is just one way to do it.
this sub' gets an array of element and weight -A(10)B(30)C(5)-and random one of the elements according the the weights.
sub we_rand {
}
you call the sub' like this:
my $rand=we_rand(A(10)B(30)C(5)D(17)); -#$rand=B
The most general solution is a function that acts as an (inverse) cumulative distribution function: a function that maps from a (uniform) distribution from 0.0 to 1.0 to whatever distribution that you want.
Juliet gave an excellent way to implement one of them.
This page provides the theory for generating random numbers from arbitrary distribution.
Another option is to have a structure similar to the following: (pardon my language, I don't actually know Perl all that well)
Then when you get the value from
int(rand(100))
you can compare it to each of the second elements in turn and return the first element.Seems that a rather natural way involves setting up a binary search. Let's say a bunch of people are enrolled in a raffle, where people are allowed to submit their names as many times as they want. We have the following names with the following number of submissions:
Now if we want to randomly select a name out of the bag, we just assign each name a range starting from 0:
Alright, so we have an array of adjacent ranges, were each range is between 0 and 26. We use a modified binary search to find our target item (pseudocode):