首先,我们构造一个奖项数组:

PHP

1

2

3

4

5

6

7

8

9

10

<?php

$prize_arr = array(

    array('id'=>1, 'prize'=>'No.1', 'v'=>1),

    array('id'=>2, 'prize'=>'No.2', 'v'=>3),

    array('id'=>3, 'prize'=>'No.3', 'v'=>6),

    array('id'=>4, 'prize'=>'No.4', 'v'=>10),

    array('id'=>5, 'prize'=>'No.5', 'v'=>20),

    array('id'=>6, 'prize'=>'Sorry', 'v'=>60),

);

?>

上面的数组中,No.1代表1等奖,以此类推,No.5代表5等奖,而Sorry代表没有中奖。v代表概率。

继续,我们看看算法的代码:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<?php

function get_rand($proArr) {

    $result = '';

    //概率数组的总概率精度

    $proSum = array_sum($proArr);

    //概率数组循环

    foreach ($proArr as $key => $proCur) {

        $randNum = mt_rand(1, $proSum);

        if ($randNum <= $proCur) {

            $result = $key;

            break;

        } else {

            $proSum -= $proCur;

        }

    }

    unset($proArr);

    return $result;

}

?>

上面的代码从1等奖开始,根据概率逐一计算每个奖项是否中出,直至最后没有中奖。

究竟这个算法是否准确,我们来模拟一下:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?php

//通过奖项数组,构造出一个用于抽奖的概率数组

foreach ($prize_arr as $key => $val) {

    $arr[$key] = $val['v'];

}

 

//模拟1万次抽奖

for ($i=1; $i<=10000; $i++) {

    $prize_key = get_rand($arr);

    if (isset($test[$prize_arr[$prize_key]['prize']])) {

        $test[$prize_arr[$prize_key]['prize']]++;

    } else {

        $test[$prize_arr[$prize_key]['prize']] = 1;

    }

}

print_r($test);

?>

上面代码的模拟结果输出:

1

2

3

4

5

6

7

8

9

Array

(

    [sorry] => 6017

    [No.5] => 2011

    [No.4] => 968

    [No.3] => 587

    [No.2] => 310

    [No.1] => 107

)

通过模拟结果可以看出,这个算法还是很靠谱的。