客户很多时候难以正确理解概率的意义,或者难以给出概率,此时可大致上把奖品数量作为权重进行抽奖
权重作为概率抽奖时,可以用循环把每个奖品放进数组,权重多大就有多少个值,然后用array_rand获取数组的key,再获得奖品
但是客户可能要求不同时段概率不同,所以我们可以事先将所有概率和时段的关系写好,然后抽奖时进行判断,获取相应的权重数组,之后再执行上述权重作为概率抽奖
权重抽奖实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| $current = date('Y-m-d H:i:s');
$keys = array_keys($this->weight); $period = []; $nowkey = ''; foreach ($keys as $k => $v) { $nowkey = $v;
if ($v == '2018-09-15 00:00:00') { $period = $this->weight[$nowkey]; break; }
$nextkey = $keys[$k + 1]; if ($current >= $nowkey && $current < $nextkey) { $period = $this->weight[$nowkey]; break; } } $result = array_intersect($this->prize, $giftlist); $gifts = []; foreach ($period as $k => $value) { if (empty($result[$k])) { continue; } for ($i = 0; $i < $value; $i++) { $gifts[] = $k; } }
$giftindex = $gifts[array_rand($gifts)]; return $result[$giftindex];
|
权重写法如下
1
| public $weight = ['2018-08-30 00:00:00' => [7862, 0, 0, 0, 0, 0, 0, 0, 0, 1069, 1069]];
|
以上写法在为建行做的抽奖活动中使用,经受住了实践的检验,但是很明显,当客户要求两个奖品概率相差千倍时候,他的效率不高
于是给出以下改进方案,把每个奖品与数字区间对应,然后使用mt_rand即可高效的随机获得奖品
以下方案在为加拿大牛肉协会做的抽奖活动中使用过,经受住了实践检验
改进写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| class Weight { public $prize = ['1', '2', '3', '4'];
public $default = 4;
public $weight = [ '2018-09-04 00:00:00' => [[0, 1], [2, 11], [12, 212], [213, 1013]], ];
public function rand($giftlist) { $current = date('Y-m-d H:i:s'); $keys = array_keys($this->weight); $period = []; $nowkey = ''; foreach ($keys as $k => $v) { $nowkey = $v;
if ($v == $keys[count($keys) - 1]) { $period = $this->weight[$nowkey]; break; }
$nextkey = $keys[$k + 1]; if ($current >= $nowkey && $current < $nextkey) { $period = $this->weight[$nowkey]; break; } }
$result = array_intersect($this->prize, $giftlist);
$gifts = []; foreach ($period as $k => $value) { $gifts = array_merge($gifts, $value); } sort($gifts); $len = count($gifts);
$giftnumber = mt_rand($gifts[0], $gifts[$len - 1]);
foreach ($period as $key => $value) { if (empty($result[$key])) { $prize = $this->default; break; } if ($giftnumber >= $value[0] && $giftnumber <= $value[1]) { $prize = $result[$key]; break; } } return $prize; } }
|