我需要从数组中随机选择一些元素。我通过随机化索引$array[int(rand(100))]
来做到这一点。我希望更频繁地出现一些元素。我该怎么做?
我想到了一个愚蠢的解决方案,在阵列中多次重复这些元素,但我相信你们可以做得更好。
答案 0 :(得分:5)
您想要生成weighted random sample。链接的问题包括有无替换。
答案 1 :(得分:3)
似乎一种相当自然的方式涉及设置二进制搜索。假设一群人参加抽奖活动,允许人们根据自己的意愿多次提交姓名。我们有以下名称,提交的数量如下:
现在,如果我们想从包中随机选择一个名称,我们只需为每个名称指定一个从0开始的范围:
好吧,我们有一个相邻范围的数组,每个范围都在0到26之间。我们使用修改后的二进制搜索来找到我们的目标项(伪代码):
let raffle := { Juliet: 0, 1;
Jenny: 2, 12;
Jessica: 13, 19;
Jan: 20, 20;
Jane: 21, 21;
Jean: 22, 26 }
let search minIndex maxIndex rangeValue =
if minIndex > maxIndex then
failwith "Not found"
let selectedIndex = (minIndex + maxIndex) / 2
let item = raffle[selectedIndex]
if item.range.min >= rangeValue && item.range.max <= rangeValue
return item.name
elif item.range.min < rangeValue
return search minIndex (selectedIndex - 1) rangeValue
else
return search (selectedIndex + 1) maxIndex rangeValue
答案 2 :(得分:1)
This page提供了从任意分布生成随机数的理论。
答案 3 :(得分:0)
如果您知道要显示随机数的频率,则可以使用rand()函数。假设你希望数字0出现在33%的时间里,1出现在另外66%的出现时间。然后你会检查rand()&lt; 0.33,并返回一些索引。否则,返回另一个索引。这只是一种方法。
答案 4 :(得分:0)
另一个选择是有一个类似于以下的结构:(原谅我的语言,我实际上并不了解Perl)
[
(1, 10),
(2, 50),
(3, 80),
(4, 100)
]
然后当你从int(rand(100))
得到值时,你可以依次将它与每个第二个元素进行比较并返回第一个元素。
答案 5 :(得分:0)
最通用的解决方案是一个充当(反向)cumulative distribution function的函数:一个函数,它从0.0到1.0的(均匀)分布映射到你想要的任何分布。
朱丽叶给出了一个很好的方法来实现其中之一。答案 6 :(得分:0)
这个子'得到一个元素和权重数组-A(10)B(30)C(5) - 以及根据权重随机的一个元素。
sub we_rand {
my $line=$_[0];#get the elements array
my @b = split(/\(\d+\)/,$line);#b now holds each elemnet from the array
my @a = "";
my $i=0;
my $tmp;
while ($line=~m/(\(\d+\)+)/g) {
$tmp=$1;#temp gets the weight
if ($tmp=~m/\d+/g) {
if ($i>0){
$a[$i]=$&+$a[$i-1];#if weight is grather then 0 -each cell of
#a sums up the wheights up to it
}
else {
$a[$i]=$&;
}
}
$i++;
}
if ($i>1){
my $n=int(rand($a[$i-1])+1);#rand a number in the boundries of
#the total weight of all the elements
my $s=scalar(@b);
#go through a and compare to the randomized num-then take the
#element from b
for ( $i=0;$i<scalar(@b);$i++){
if($n<=$a[$i])
{
$c=$b[$i];
last;
}
}
} else {
$c=$b[0];#if only one element
}
return $c;
你像这样称呼子'
my $ rand = we_rand(A(10)B(30)C(5)D(17)); - #$兰特= B