perl – 按使用频率随机选择字母
发布时间:2020-12-16 06:08:27 所属栏目:大数据 来源:网络整理
导读:在将少量莎士比亚书籍送到我的Perl脚本后,我有一个哈希,其中包含26个英文字母作为键,以及它们在文本中出现的次数 – 作为值: %freq = ( a = 24645246,b = 1409459,.... z = 807451,); 当然还有所有字母的总数 – 让我们说在$total变量中. 是否有一个很好的
在将少量莎士比亚书籍送到我的Perl脚本后,我有一个哈希,其中包含26个英文字母作为键,以及它们在文本中出现的次数 – 作为值:
%freq = ( a => 24645246,b => 1409459,.... z => 807451,); 当然还有所有字母的总数 – 让我们说在$total变量中. 是否有一个很好的技巧来生成一个包含16个随机字母的字符串(一个字母可以在那里出现几次) – 按使用频率加权? 要在类似于Ruzzle的文字游戏中使用: 优雅的东西 – 比如从文件中挑选一条随机行,如Perl Cookbook收据所示: rand($.) < 1 && ($line = $_) while <>; 解决方法
选择随机线的Perl Cookbook技巧(也可以在
perlfaq5中找到)也可以用于加权采样:
my $chosen; my $sum = 0; foreach my $item (keys %freq) { $sum += $freq{$item}; $chosen = $item if rand($sum) < $freq{$item}; } 这里,$sum对应于行计数器$.和$freq {$item}到Cookbook版本中的常量1. 如果您要选择大量加权随机样本,可以通过一些准备加快这一点(注意这会破坏%freq,所以如果你想保留它,请先复制一份): # first,scale all frequencies so that the average frequency is 1: my $avg = 0; $avg += $_ for values %freq; $avg /= keys %freq; $_ /= $avg for values %freq; # now,prepare the array we'll need for fast weighted sampling: my @lookup; while (keys %freq) { my ($lo,$hi) = (sort {$freq{$a} <=> $freq{$b}} keys %freq)[0,-1]; push @lookup,[$lo,$hi,$freq{$lo} + @lookup]; $freq{$hi} -= (1 - $freq{$lo}); delete $freq{$lo}; } 现在,要从准备好的分布中绘制随机加权样本,您只需执行以下操作: my $r = rand @lookup; my ($lo,$threshold) = @{$lookup[$r]}; my $chosen = ($r < $threshold ? $lo : $hi); (这基本上是Marsaglia,Tsang& Wang(2004),“Fast Generation of Discrete Random Variables”,J.Stat.Soft.11(3)中描述的Square Histogram方法,最初归于A.J.Walker(1974).) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |