thinkphp 抽奖算法
最近公司要做一个抽奖的小程序,经过两天的查阅资料,终于鼓捣出来一个。
大家如果觉得还OK ,就拿去用:
算法原理:
每个奖项都有一定的概率,比如说:0.01 0.09等等,所有奖项的概率的总和一定要为1.
对于一个奖项来说,每次中奖的概率都是一致的,只有当该奖品的数量为0 的时候,概率才会被清空,然后加到默认奖项(未中奖)中。
1、数据库设计(奖励表):
2、用的是thinkphp框架,大家凑合着看。
public function index() { $award = M ( "prize" ); $list = $award->select (); $prize = $this->_get_prize (100); //基数为100 $this->assign ( "award", $prize ); $this->display (); } /** * * @param unknown_type $mount 基数 100,1000 * @throws Exception * @return unknown */ private function _get_prize($mount) { $model = M ( "prize" ); // $prize = $model->select(); $prize = $model->order ( "award desc" )->getField ( "id,name,p,mount,award" ); //以id为键的关联数组 $gl = array (); // 概率数组,以奖励的id为key的关联数组 $num = 0; // 每个奖项的区间最大值 foreach ( $prize as $key => $value ) { if ($value ["p"] == 0) continue; if ($value ["p"] > 1) throw new Exception ( "概率不能大于1" ); $num += floor ( $mount * $value ["p"] ); $gl [$key] = $num; } $rand = mt_rand ( 1, $mount ); //随机数,当处于哪个区间,就中哪个奖励 foreach ( $gl as $k => $v ) { if ($rand <= $v) { if ($prize [$k] ["award"] == 0) //默认奖项 return $prize [$k]; $model->startTrans(); $model->where ( "id=" . $k )->setDec ( "mount", "1" ); if ($prize[$k]["mount"] == 1) { $data1 = array("id"=>$k,"p"=>0); $model->save($data1); $model->execute("UPDATE prize SET p = p+{$prize[$k]["p"]} WHERE award = 0"); } $model->commit(); return $prize [$k]; } } }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。