牛骨文教育服务平台(让学习变的简单)
博文笔记

thinkphp 抽奖算法

创建时间:2014-09-11 投稿人: 浏览次数:139


最近公司要做一个抽奖的小程序,经过两天的查阅资料,终于鼓捣出来一个。

大家如果觉得还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];
			}
		}
	}
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。