Java 实现根据权重设置抽奖概率
2017-05-17 10:56
489 查看
抽奖活动
package com.wamei.activity; import com.wamei.common.ResourceUtils; import com.wamei.entity.AppUser; import com.wamei.entity.activity.LotteryAddress; import com.wamei.entity.activity.LotteryPrize; import com.wamei.entity.activity.LotteryRecord; import com.wamei.entity.activity.LotteryWinRecord; import com.wamei.service.AppUserService; import com.wamei.service.BaseService; import com.wamei.util.AjaxPostResponse; import com.wamei.util.DateToolUtils; import com.wamei.util.JsonResponseHelper; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.ServletRequestUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 总统竞选抽奖活动 Controller. * @author qixuan.chen * @version 1.0 */ @Controller @RequestMapping({"/activity/lotteryController"}) public class LotteryController extends AbstractController{ private final static Logger logger = Logger.getLogger(LotteryController.class); private static String smsUrl = ResourceUtils.getValue("sms.httpUrl"); public static String pathUrl = ResourceUtils.getValue("sign.path"); public final static String ECID = "100148"; public final static String ECKEY = "3O9oOAuGZ0k=dMMSmPTJUUI="; @Resource(name = "lotteryPrizeManager") private BaseService<LotteryPrize> lotteryPrizeSrv; @Resource(name = "lotteryRecordManager") private BaseService<LotteryRecord> lotteryRecordSrv; @Resource(name = "lotteryWinRecordManager") private BaseService<LotteryWinRecord> lotteryWinRecordSrv; @Resource(name = "lotteryAddressManager") private BaseService<LotteryAddress> lotteryAddressSrv; @Resource(name="appUserManager") private AppUserService appUserSrv; private static Cache validCodeCache; static{ if (validCodeCache == null) { validCodeCache = CacheManager.getInstance().getCache("govDataCache"); } } /** * 主页视图 * @return * @throws Exception */ @RequestMapping(value = "/main", method ={RequestMethod.GET,RequestMethod.POST}) public ModelAndView lotteryMain(HttpServletRequest request) throws Exception { ModelAndView mav = new ModelAndView("pages/activity/lottery/lottery"); String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID String loMark = "no"; if(StringUtils.isNotEmpty(token)){ AppUser user = appUserSrv.find(token); if(null!=user){ //当天是否已参与过 String lrHql = " from LotteryRecord t where user.id=? and t.createTime>= ? and t.createTime <= ? "; List<Object> param = new ArrayList<Object>(); Date startTime = DateToolUtils.getTodayStart(); Date endTime = DateToolUtils.getTodayEnd(); param.add(user.getId()); param.add(startTime); param.add(endTime); List<LotteryRecord> lrList = lotteryRecordSrv.list(lrHql,param.toArray()); if(null!=lrList && lrList.size()>0){ loMark = "yes"; } mav.addObject("token",user.getId()); } } mav.addObject("loMark",loMark); //追加投票数 String id = "1005"; LotteryPrize mo = lotteryPrizeSrv.find(id); String time = String.valueOf(System.currentTimeMillis()); String pr = time.substring(time.length()-1,time.length()); //利用时间戳最后一位来设置投票互斥事件 String[] p2={"1","3","5","7","9"}; int lpCount = mo.getNum(); float mkCount = mo.getPrice(); if(Arrays.asList(p2).contains(pr)){ mo.setNum(lpCount+1); }else{ mo.setPrice(mkCount+1); } lotteryPrizeSrv.update(mo); //奖品列表 String hql = " from LotteryPrize t where t.status=1 "; List<LotteryPrize> list = lotteryPrizeSrv.list(hql,null); mav.addObject("prizeList",list); mav.addObject("lpCount",lpCount); mav.addObject("mkCount",(int)mkCount); return mav; } /** * 抽奖 * @param request */ @RequestMapping(value = "/getprize", method={RequestMethod.POST,RequestMethod.GET}) public synchronized ResponseEntity<AjaxPostResponse> getprizesetting(HttpServletRequest request){ String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID try { int result = 5; int status = 0; if(StringUtils.isNotEmpty(token)){ AppUser user = appUserSrv.find(token); if (null != user) { synchronized(this) { //每天只能抽一次奖 String lrHql = " from LotteryRecord t where user.id=? and t.createTime>= ? and t.createTime <= ? "; List<Object> param = new ArrayList<Object>(); Date startTime = DateToolUtils.getTodayStart(); Date endTime = DateToolUtils.getTodayEnd(); param.add(user.getId()); param.add(startTime); param.add(endTime); List<LotteryRecord> lrList = lotteryRecordSrv.list(lrHql,param.toArray()); if(null!=lrList && lrList.size()>0){ return this.errorResponse(""); }else{ // //IP限制(每个IP一天一次) // String ipHql = " from LotteryRecord t where userIp=? and t.createTime>= ? and t.createTime <= ? "; // List<Object> ipParam = new ArrayList<Object>(); // ipParam.add(this.getIPAddress(request)); // ipParam.add(startTime); // ipParam.add(endTime); // List<LotteryRecord> ipList = lotteryRecordSrv.list(ipHql,ipParam.toArray()); // if(null!=ipList && ipList.size()>0){ // return this.errorResponse("手气不佳,明天再来!"); // } //添加抽奖记录 LotteryRecord lotteryRecord = new LotteryRecord(); lotteryRecord.setUser(user); lotteryRecord.setCreateTime(new Date()); lotteryRecord.setUserIp(this.getIPAddress(request)); lotteryRecord.setStatus(status); lotteryRecordSrv.create(lotteryRecord); //已经中过一次的用户,不能在中 String lwrHql = " from LotteryWinRecord t where user.id=? "; List<Object> lwrParam = new ArrayList<Object>(); lwrParam.add(user.getId()); List<LotteryWinRecord> lwrList = lotteryWinRecordSrv.list(lwrHql,lwrParam.toArray()); if(null!=lwrList && lwrList.size()>0){ return this.errorResponse("手气不佳,明天再来!"); } String time = String.valueOf(System.currentTimeMillis()); String pr = time.substring(time.length()-1,time.length()); Integer[] data = {2,4,6,8};//奖品参数 //利用时间戳最后一位来设置外层概率,互斥事件 //String[] p2={"0","1","2","3","4","5","6","7","8","9"}; String[] p2={"1","3","5","8"}; if(Arrays.asList(p2).contains(pr)){ //进行抽奖 List<LotteryPrize> prizeList = lotteryPrizeSrv.list(); result = getPrizeIndex(prizeList); LotteryPrize prize = prizeList.get(result); String prizeName = ""; if(null!=prize){ //中奖了 String msg = "手气不佳,明天再来!"; if("1001".equals(prize.getId())){ msg = "1台"+prize.getPrizename(); prizeName = prize.getPrizename(); }else if("1002".equals(prize.getId())){ msg = "1台"+prize.getPrizename(); prizeName = prize.getPrizename(); }else if("1003".equals(prize.getId())){ msg = "1张"+prize.getPrizename(); prizeName = "价值"+prize.getPrice()+"元的"+prize.getPrizename(); }else if("1004".equals(prize.getId())){ msg = "1张"+prize.getPrizename(); prizeName = "价值"+prize.getPrice()+"元的"+prize.getPrizename(); }else{ return this.errorResponse(msg);//手气不佳 } if(prize.getNum()>=1){ prize.setNum(prize.getNum()-1); lotteryPrizeSrv.update(prize);//更新剩余量 status = 1; //添加中奖记录 LotteryWinRecord winRecord = new LotteryWinRecord(); winRecord.setUser(user); winRecord.setPrizeId(prize.getId()); winRecord.setImgsrc(prize.getImgsrc());//奖品图片 winRecord.setPrizename(prizeName);//奖品名称 winRecord.setCreateTime(new Date()); winRecord.setUserIp(this.getIPAddress(request)); winRecord.setStatus(status); lotteryWinRecordSrv.create(winRecord); return this.okResponse(msg); } } }else{ return this.errorResponse("手气不佳,明天再来!"); } } } }else{ return this.errorResponse("不存在该用户!"); } } } catch (Exception e) { e.printStackTrace(); return this.errorResponse("手气不佳,明天再来!"); } return this.errorResponse("手气不佳,明天再来!"); } /** * 我的奖品记录 * @param request * @param response */ @RequestMapping(value = "/myprizes", method={RequestMethod.POST,RequestMethod.GET}) public @ResponseBody void myprizesRecord(HttpServletRequest request, HttpServletResponse response){ String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID StringBuffer sb = new StringBuffer(); String result = ""; try { if(StringUtils.isNotEmpty(token)) { AppUser user = appUserSrv.find(token); if (null != user) { String hql = " from LotteryWinRecord t where user.id=? "; List<Object> paramValues = new ArrayList<Object>(); paramValues.add(token); List<LotteryWinRecord> lotteryWinRecords = lotteryWinRecordSrv.list(hql, paramValues.toArray()); result = JsonResponseHelper.toJson(lotteryWinRecords).toString(); } } sb.append("{\"statusCode\":\"1\", \"msg\":\"\", \"errorCode\":\"\", \"result\":{\"data\":" + result + "}}"); } catch (Exception e) { e.printStackTrace(); sb.append("{\"statusCode\":\"0\", \"msg\":\"获取失败!\", \"errorCode\":\"\", \"result\":{}}"); } JsonResponseHelper.renderText(sb.toString(), response); } /** * 获取奖品快递地址信息 * @param request */ @RequestMapping(value = "/getAddress", method={RequestMethod.POST}) public ResponseEntity<AjaxPostResponse> getAddress(HttpServletRequest request){ String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID try { if(StringUtils.isBlank(token)){ return this.errorResponse("请先登录!"); } if(StringUtils.isNotEmpty(token)){ AppUser user = appUserSrv.find(token); if (null != user) { String hql = " from LotteryAddress t where user.id=? "; List<Object> paramValues = new ArrayList<Object>(); paramValues.add(token); List<LotteryAddress> list = lotteryAddressSrv.list(hql,paramValues.toArray()); if(null!=list && list.size()>0){ return this.okResponse(list.get(0)); }else{ return this.okResponse(""); } }else{ return this.errorResponse("请先登录!"); } } } catch (Exception e) { e.printStackTrace(); } return this.errorResponse("获取失败!"); } /** * 保存奖品快递地址信息 * @param request */ @RequestMapping(value = "/address", method={RequestMethod.POST}) public ResponseEntity<AjaxPostResponse> saveAddress(HttpServletRequest request){ String token = ServletRequestUtils.getStringParameter(request, "token", "");//用户ID String truename = ServletRequestUtils.getStringParameter(request, "truename", "");//真实姓名 String telPhone = ServletRequestUtils.getStringParameter(request, "mobile", "");//联系方式 String city = ServletRequestUtils.getStringParameter(request, "city", "");//区域 String street = ServletRequestUtils.getStringParameter(request, "street", "");//街道 String address = ServletRequestUtils.getStringParameter(request, "address", "");//地址 try { if(StringUtils.isBlank(token)){ return this.errorResponse("请先登录!"); } if(StringUtils.isBlank(truename)){ return this.errorResponse("请输入真实姓名!"); } if(StringUtils.isBlank(telPhone)){ return this.errorResponse("请输入联系方式!"); } Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$"); Matcher m = p.matcher(telPhone); if (false == m.matches()) { return this.errorResponse("手机号格式不正确"); } if(StringUtils.isBlank(city)){ return this.errorResponse("请输入区域地址!"); } if(StringUtils.isBlank(street)){ return this.errorResponse("请输入街道地址!"); } if(StringUtils.isNotEmpty(token)){ AppUser user = appUserSrv.find(token); if (null != user) { String hql = " from LotteryAddress t where user.id=? "; List<Object> paramValues = new ArrayList<Object>(); paramValues.add(token); List<LotteryAddress> list = lotteryAddressSrv.list(hql,paramValues.toArray()); LotteryAddress mo = new LotteryAddress(); mo.setUser(user); mo.setTruename(truename); mo.setTelPhone(telPhone); mo.setCity(city); mo.setStreet(street); mo.setPrizeId(""); mo.setAddress(address); if(null!=list && list.size()>0){ mo.setId(list.get(0).getId()); mo.setCreateTime(list.get(0).getCreateTime()); lotteryAddressSrv.update(mo); }else{ mo.setCreateTime(new Date()); lotteryAddressSrv.create(mo); } logger.info("userId="+token+",地址保存成功"); return this.okResponse("保存成功!"); }else{ return this.errorResponse("请先登录!"); } } } catch (Exception e) { e.printStackTrace(); } return this.errorResponse("保存失败!"); } /** * 根据Math.random()产生一个double型的随机数,判断每个奖品出现的概率 * @param prizes * @return random:奖品列表prizes中的序列(prizes中的第random个就是抽中的奖品) */ public int getPrizeIndex(List<LotteryPrize> prizes) { DecimalFormat df = new DecimalFormat("######0.00"); int random = -1; try{ //计算总权重 double sumWeight = 0; for(LotteryPrize p : prizes){ sumWeight += p.getPrizeWeight(); } //产生随机数 double randomNumber; randomNumber = Math.random(); //根据随机数在所有奖品分布的区域并确定所抽奖品 double d1 = 0; double d2 = 0; for(int i=0;i<prizes.size();i++){ d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrizeWeight()))/sumWeight; if(i==0){ d1 = 0; }else{ d1 +=Double.parseDouble(String.valueOf(prizes.get(i-1).getPrizeWeight()))/sumWeight; } if(randomNumber >= d1 && randomNumber <= d2){ random = i; break; } } }catch(Exception e){ random =-1; logger.info("生成抽奖随机数出错,出错原因:" +e.getMessage()); } return random; } /** * 测试 * @param args */ public static void main(String args[]){ int i = 0; int[] result=new int[5]; List<LotteryPrize> prizes = new ArrayList<LotteryPrize>(); LotteryPrize p1 = new LotteryPrize(); p1.setPrizename("iPhone7"); p1.setPrizeWeight(0);//奖品的权重设置成1 prizes.add(p1); LotteryPrize p2 = new LotteryPrize(); p2.setPrizename("扫地机器人"); p2.setPrizeWeight(0);//奖品的权重设置成2 prizes.add(p2); LotteryPrize p3 = new LotteryPrize(); p3.setPrizename("充电宝"); p3.setPrizeWeight(3);//奖品的权重设置成3 prizes.add(p3); LotteryPrize p4 = new LotteryPrize(); p4.setPrizename("京东电子卡"); p4.setPrizeWeight(4);//奖品的权重设置成4 prizes.add(p4); LotteryPrize p5 = new LotteryPrize(); p5.setPrizename("手气不佳"); p5.setPrizeWeight(100000);//奖品的权重设置成4 prizes.add(p5); LotteryController a1 = new LotteryController(); //Thread t1 = new Thread(a1); System.out.println("抽奖开始"); for (i = 0; i < 10000; i++)// 打印100个测试概率的准确性 { int selected=a1.getPrizeIndex(prizes); System.out.println("第"+i+"次抽中的奖品为:"+prizes.get(selected).getPrizename() +"=========="+selected); result[selected]++; System.out.println("--------------------------------"); } System.out.println("抽奖结束"); System.out.println("每种奖品抽到的数量为:"); System.out.println("一等奖:"+result[0]); System.out.println("二等奖:"+result[1]); System.out.println("三等奖:"+result[2]); System.out.println("四等奖:"+result[3]); System.out.println("无等奖:"+result[4]); } }
相关文章推荐
- Java根据奖品权重计算中奖概率实现抽奖
- 【项目实战】——Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋、大转盘等抽奖活动)
- Java根据概率、剩余奖品数量动态抽奖算法实现,概率总和可以不为100%
- 根据概率抽奖(无奖品数量) -- Java实现
- java实现一个抽奖概率类
- php实现可以设置中奖概率的抽奖程序代码分享
- java实现一个抽奖概率类
- Java实现根据权重优先返回(速度较快)
- java实现抽奖概率
- php实现可以设置中奖概率的抽奖程序代码分享
- JAVA 根据设置的概率生成随机数的方法
- JAVA 根据设置的概率生成随机数
- java版根据权重抽奖算法
- C#&PHP&Java实现Alias Method概率抽奖算法
- JAVA 根据设置的概率生成随机数
- 根据经纬度求两点间距离实现源码(java)
- 使用java简单实现根据输入的汉字,得到汉字的首字母
- Java JTable设置列宽实现表格不等宽
- Java实现根据List中对象的相应属性进行排序
- 项目4:抽奖程序 分时间段(按时段设置的奖品数为概率)