php技术博客
让天下没有搞不定的bug~

使用 PHP 解决机率和权重问题

//有一个百货公司办了一个抽奖活动,一等奖的中奖率是3%,二等奖是5%,三等奖是10%,纪念奖是20%。
//处理这个需求,一般的程序员会采用如下的逻辑:
$randKey = mt_rand(1, 100);
$key = 0;
if ($randKey <= 3) { $key = 1; } elseif ($randKey <= 3 + 5) { $key = 2; } elseif ($randKey <= 3 + 5 + 10) { $key = 3; } elseif ($randKey <= 3 + 5 + 10 + 20) { $key = 4; } //这段程序似乎有些复杂,我们可以简化一下它: $prizeInfo = array( 0 => 62,
1 => 3,
2 => 5,
3 => 10,
4 => 20
);
$randKey = mt_rand(1, 100);
$radix = 0;
foreach ($prizeInfo as $key => $values) {
$radix += $values;
if ($randKey <= $radix) { break; } } //权重和机率类似,只是概率总值不固定,我们只想直观的用一个数字的大小来表示想给它多大的机会。 //我们修改一下需求,一等奖的权重是5,二等奖是10,三等奖是20,纪念奖是50,没有奖励是100。 //实际上,稍微修改一下逻辑,我们就可以处理这个问题了: $prizeInfo = array( 0 => 100,
1 => 5,
2 => 10,
3 => 20,
4 => 50
);
$randKey = mt_rand(1, array_sum($prizeInfo));
$radix = 0;
foreach ($prizeInfo as $key => $values) {
$radix += $values;
if ($randKey <= $radix) { break; } } //但是实际上,我们在处理更复杂的需求时会发现,即使我们使用了 PHP 中号称更好用线性分布更平均的 mt_rand,统计结果看起来,也不是那么随机,或许这是源于 PHP 本身的问题。 //我在设计杀死怪物时按照权重掉落物品的逻辑时,就遇到了这样的问题。 //稍作处理后,结果稍微满意了些,基本上,我只是扩大了随机范围,扰乱了权重的顺序。 $prizeInfo = array( 0 => 100,
1 => 5,
2 => 10,
3 => 20,
4 => 50
);
$keys = array_keys($prizeInfo);
shuffle($keys);
$randKey = rand(1, array_sum($prizeInfo));
$radix = 0;
foreach ($keys as $key) {
$radix += $prizeInfo[$key];
if ($randKey <= $radix) { break; } } //这段逻辑基本上可以应付大多数的权重和机率问题! //当然,如果你有更复杂更精确的需求,你可能需要自己设计一个特别的算法。 这几个对中奖求概率的很有用,贴出来,分享一下…

赞(0)
未经允许不得转载:PHP技术博客 » 使用 PHP 解决机率和权重问题