php教程

超轻量级php框架startmvc

基于PHP代码实现中奖概率算法可用于刮刮卡、大转盘等抽奖算法

更新时间:2020-03-07 03:24:30 作者:startmvc
大转盘中奖概率算法在我们的日常生活中,经常遇到,那么基于php代码是如何实现中奖概率

大转盘中奖概率算法在我们的日常生活中,经常遇到,那么基于php代码是如何实现中奖概率算法的,下面通过一段代码实例给大家介绍php中奖概率算法,代码简单易懂,并且附有注释,具体代码如下所示:


<?php
/*
 * 经典的概率算法,
 * $proArr是一个预先设置的数组,
 * 假设数组为:array(100,200,300,400),
 * 开始是从1,1000 这个概率范围内筛选第一个数是否在他的出现概率范围之内, 
 * 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,
 * 在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。
 * 这样 筛选到最终,总会有一个数满足要求。
 * 就相当于去一个箱子里摸东西,
 * 第一个不是,第二个不是,第三个还不是,那最后一个一定是。
 * 这个算法简单,而且效率非常 高,
 * 关键是这个算法已在我们以前的项目中有应用,尤其是大数据量的项目中效率非常棒。
 */
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; 
} 
/*
 * 奖项数组
 * 是一个二维数组,记录了所有本次抽奖的奖项信息,
 * 其中id表示中奖等级,prize表示奖品,v表示中奖概率。
 * 注意其中的v必须为整数,你可以将对应的 奖项的v设置成0,即意味着该奖项抽中的几率是0,
 * 数组中v的总和(基数),基数越大越能体现概率的准确性。
 * 本例中v的总和为100,那么平板电脑对应的 中奖概率就是1%,
 * 如果v的总和是10000,那中奖概率就是万分之一了。
 * 
 */
$prize_arr = array( 
 '0' => array('id'=>1,'prize'=>'平板电脑','v'=>1), 
 '1' => array('id'=>2,'prize'=>'数码相机','v'=>5), 
 '2' => array('id'=>3,'prize'=>'音箱设备','v'=>10), 
 '3' => array('id'=>4,'prize'=>'4G优盘','v'=>12), 
 '4' => array('id'=>5,'prize'=>'10Q币','v'=>22), 
 '5' => array('id'=>6,'prize'=>'下次没准就能中哦','v'=>50), 
); 
/*
 * 每次前端页面的请求,PHP循环奖项设置数组,
 * 通过概率计算函数get_rand获取抽中的奖项id。
 * 将中奖奖品保存在数组$res['yes']中,
 * 而剩下的未中奖的信息保存在$res['no']中,
 * 最后输出json个数数据给前端页面。
 */
foreach ($prize_arr as $key => $val) { 
 $arr[$val['id']] = $val['v']; 
} 
$rid = get_rand($arr); //根据概率获取奖项id 
$res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项 
unset($prize_arr[$rid-1]); //将中奖项从数组中剔除,剩下未中奖项 
shuffle($prize_arr); //打乱数组顺序 
for($i=0;$i<count($prize_arr);$i++){ 
 $pr[] = $prize_arr[$i]['prize']; 
} 
$res['no'] = $pr; 
print_r($res); 

下面再给大家分享一段实例代码基于Java实现中奖概率计算

 做移动的项目,有个需求,做个摇奖的活动!其中中奖的计算比较恶心,用户要改动各个奖项的中奖概率,而且每天的奖项有个数限制。一二三四五六等奖,概率不通,怎么算一个用户参与了中没中将呢?苦思了一下,可以用Random类的 nextInt(int x)方法产生一个范围内的随机数,产生到那个区间就是几等奖了,中奖区间的产生是动态的。贴出源代码,仅供参考!


package Mzone;
import java.util.ArrayList;
import java.util.Random;
public class Mzone {
 /**
 * CopyRright(c)2009-04: 
 * Project: 
 * Module ID: 
 * Comments: 概率计算
 * JDK version used: <JDK1.4>
 * Author:ch
 * Create Date:2009-04-20
 * Modified By: 
 * Modified Date: 
 * Why & What is modified 
 * Version: 1.0
 */ 
 static Random r = new Random();
 public static void main(String[] args) {
 //各个奖项的中奖概率的分母
 Integer _5m = new Integer(5);
 Integer _500m = new Integer(30);
 Integer _ipod = new Integer(500);
 Integer _phone = new Integer(1000);
 Integer _notebook = new Integer(1500);
 Integer _jay = new Integer(50);
 ArrayList list = new ArrayList();
 if(_5m.intValue()!=0)
 list.add(_5m);
 if(_500m.intValue()!=0)
 list.add(_500m);
 if(_ipod.intValue()!=0)
 list.add(_ipod);
 if(_phone.intValue()!=0)
 list.add(_phone);
 if(_notebook.intValue()!=0)
 list.add(_notebook);
 if(_jay.intValue()!=0)
 list.add(_jay);
 //计算最小公倍数
 int common = getN(list);
 System.out.println("最小公倍数:"+common);
 int a = 0;int b = 0;int c = 0;int d = 0;int e = 0;int f = 0;int g = 0;
 int first = 0;int second = 0;int third = 0;int four = 0;int fifth = 0;int sixth = 0;
 if(_5m.intValue()!=0){
 first = common/_5m.intValue();
 }
 if(_500m.intValue()!=0){
 second = first + (common/_500m.intValue());
 }else second = first;
 if(_ipod.intValue()!=0){
 third = second + (common/_ipod.intValue());
 }else third = second;
 if(_phone.intValue()!=0){
 four = third + (common/_phone.intValue());
 }else four = third;
 if(_notebook.intValue()!=0){
 fifth = four + (common/_notebook.intValue());
 }else fifth = four;
 if(_jay.intValue()!=0){
 sixth = fifth + (common/_jay.intValue());
 }else sixth = fifth;
 int times = 30000;//循环次数
 for(int i = 0;i < times; i++){
 int ri = getRandom(common);//产生随机数
 if(ri >= 0 && ri < first){
 a++;
 }else if(ri >= first && ri < second){
 b++;
 }else if(ri >= second && ri < third){
 c++;
 }else if(ri >= third && ri < four){
 d++;
 }else if(ri >= four && ri < fifth){
 e++;
 }else if(ri >= fifth && ri < sixth){
 f++;
 }else{
 g++;
 }
 }
 System.out.println("5m值:" + a + " 500m值:" + b + " ipodMP3:" + c + " 手机:" + d + " 笔记本电脑:" + e + " 演唱会门票:" + f + " 谢谢参与:" + g);
 }
 /**
 * 求最大公约数
 */
 public static int gcd(int m, int n){
 while (true){
 if ((m = m % n) == 0)
 return n;
 if ((n = n % m) == 0)
 return m;
 }
 }
 /**
 * 求最小公倍数
 */
 public static int gys(int z, int y){
 int t = 0;
 int c = 0;
 c = gcd(z,y);
 t = z * y / c;
 return t;
 }
 /**
 * 求几个数的最小公倍数
 */
 public static int getN(ArrayList list){
 int t = 1;
 for(int i = 0;i<list.size();i++){
 Integer temp = (Integer)list.get(i);
 t = gys(t,temp.intValue());
 }
 return t; 
 }
 /**
 * 产生随机数
 */
 public static int getRandom(int y){
 int result = r.nextInt(y);
 return result;
 }
}
中奖概率 大转盘中奖概率 大转盘抽奖算法 刮刮卡抽奖算法