java实现抽奖概率类

本文实例为大家分享了java实现抽奖概率类的具体代码,供大家参考,具体内容如下

在一些项目需求中,可能会遇到抽奖问题,如提供一系列奖品及获奖概率,要求根据概率返回每次抽到的奖品。以下是本人在实际项目中写的一个抽奖工具类,与大家共同分享:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 抽奖工具类,概率和可以不等于1
 * 概率为百分数去掉百分号的部分,如10%,则为10
 * 抽奖操作如下:
 * 1.输入抽奖概率集合,【抽奖概率集合为{10.0, 20.0, 30.0}】
 * 2.生成连续集合,  【生成的连续集合为{(0.0, 10.0],(10.0, 30.0],(30.0, 60.0]}】
 * 3.生成随机数,   【生成方法为 random.nextDouble() * maxElement】
 * 4.判断随机数在哪个区间内,返回该区间的index【生成了随机数12.001,则它属于(10.0, 30.0],返回 index = 1】
 *
 */
public class LotteryUtil {

 /**
 * 定义一个连续集合
 * 集合中元素x满足:(minElement,maxElement]
 * 数学表达式为:minElement < x <= maxElement
 *
 */
 public class ContinuousList {

 private double minElement;
 private double maxElement;

 public ContinuousList(double minElement, double maxElement){
 if(minElement > maxElement){
 throw new IllegalArgumentException("区间不合理,minElement不能大于maxElement!");
 }
 this.minElement = minElement;
 this.maxElement = maxElement;
 }

 /**
 * 判断当前集合是否包含特定元素
 * @param element
 * @return
 */
 public boolean isContainKey(double element){
 boolean flag = false;
 if(element > minElement && element <= maxElement){
 flag = true;
 }
 return flag;
 }

 }

 private List<ContinuousList> lotteryList; //概率连续集合
 private double maxElement;  //这里只需要最大值,最小值默认为0.0

 /**
 * 构造抽奖集合
 * @param list 为奖品的概率
 */
 public LotteryUtil(List<Double> list){
 lotteryList = new ArrayList<ContinuousList>();
 if(list.size() == 0){
 throw new IllegalArgumentException("抽奖集合不能为空!");
 }
 double minElement = 0d;
 ContinuousList continuousList = null;
 for(Double d : list){
 minElement = maxElement;
 maxElement = maxElement + d;
 continuousList = new ContinuousList(minElement, maxElement);
 lotteryList.add(continuousList);
 }
 }

 /**
 * 进行抽奖操作
 * 返回:奖品的概率list集合中的下标
 */
 public int randomColunmIndex(){
 int index = -1;
 Random r = new Random();
 double d = r.nextDouble() * maxElement; //生成0-1间的随机数
 if(d == 0d){
 d = r.nextDouble() * maxElement;  //防止生成0.0
 }
 int size = lotteryList.size();
 for(int i = 0; i < size; i++){
 ContinuousList cl = lotteryList.get(i);
 if(cl.isContainKey(d)){
 index = i;
 break;
 }
 }
 if(index == -1){
 throw new IllegalArgumentException("概率集合设置不合理!");
 }
 return index;

 }

 public double getMaxElement() {
 return maxElement;
 }

 public List<ContinuousList> getLotteryList() {
 return lotteryList;
 }
 public void setLotteryList(List<ContinuousList> lotteryList) {
 this.lotteryList = lotteryList;
 }

}

该工具类的基本思想是,将抽奖概率分布到数轴上,如现有三个抽奖概率10、20、30,将三者依次添加到概率集合中,则构造的数轴为:0~10范围内表示概率10,10~30范围内表示概率为20,30~60范围内表示概率为30,数轴上的长度对应着相应的概率。由这种处理方式可知,概率总和并不需要等于1。该工具类的成功与否在于Random.nextDouble()能否等概率地生成0~1之间的任意一个数。

对该抽奖工具进行测试,测试类如下:

package com.lottery;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

class Result{
 private int index;
 private int sumTime;
 private int time;
 private double probability;
 private double realProbability;

 public int getIndex() {
 return index;
 }

 public void setIndex(int index) {
 this.index = index;
 }

 public int getTime() {
 return time;
 }

 public void setTime(int time) {
 this.time = time;
 }

 public int getSumTime() {
 return sumTime;
 }

 public void setSumTime(int sumTime) {
 this.sumTime = sumTime;
 }

 public double getProbability() {
 return probability;
 }

 public double getRealProbability() {
 return realProbability;
 }

 public void setRealProbability(double realProbability) {
 this.realProbability = realProbability;
 }

 public Result(){

 }

 public Result(int index, int sumTime, int time, double realProbability) {
 this.setIndex(index);
 this.setTime(time);
 this.setSumTime(sumTime);
 this.setRealProbability(realProbability);

 }

 public String toString(){
 return "索引值:" + index + ",抽奖总数:" + sumTime + ",抽中次数:" + time + ",概率:"
   + realProbability + ",实际概率:" + (double)time/sumTime;
 }
}

public class TestLottery {

 static final int TIME = 100000;

 public static void iteratorMap(Map<Integer, Integer> map, List<Double> list){
 for(Entry<Integer, Integer> entry : map.entrySet()){
 int index = entry.getKey();
 int time = entry.getValue();
 Result result = new Result(index, TIME, time, list.get(index));
 System.out.println(result);
 }
 }

 public static void main(String[] args) {
 //构造概率集合
 List<Double> list = new ArrayList<Double>();
 list.add(20d);
 list.add(80d);
 list.add(50d);
 list.add(30d);
 LotteryUtil ll = new LotteryUtil(list);
 double sumProbability = ll.getMaxElement();

 Map<Integer, Integer> map = new HashMap<Integer, Integer>();
 for(int i = 0; i < TIME; i++){
 int index = ll.randomColunmIndex();
 if(map.containsKey(index)){
 map.put(index, map.get(index) + 1);
 }else{
 map.put(index, 1);
 }
 }
 for(int i = 0; i < list.size(); i++){
 double probability = list.get(i) / sumProbability;
 list.set(i, probability);
 }
 iteratorMap(map, list);

 }

}

运行结果:

由结果可知,抽奖100000时, 得到的实际概率基本与正式概率相当。

以下说明此类调用方式:

public LotteryUtil(List<Double> list)
说明:构造方法,传入参数为一个概率集合

public int randomColunmIndex()
功能:进行抽奖操作,返回List集合的索引下标,此下标对应的概率的奖品即为抽中的奖品

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 简单实现java抽奖系统

    本文为大家分享了java抽奖系统的具体代码,供大家参考,具体内容如下 用户信息类 /* * 用户信息类 * 1.账号 * 2.密码 * 3.卡号 * 4.是否登录 */ public class User { public static String userName = ""; public static String passWord = ""; public static int cardNumber = 0; // 是否登录 public static bo

  • Java抽奖算法第二例

    本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下 1. 算法分析  根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品. 2. 代码 核心算法 public class Arithmetic { // 放大倍数 private static final int mulriple = 1000000; public int pay(List<Prize> prizes) { int lastScope = 0; // 洗牌,打乱奖品次

  • 基于Java实现抽奖系统

    本次任务要求为某商场开发一套幸运抽奖系统,客户必须首先注册成为该商场会员,会员登录成功后,就可以参加抽奖活动了. 注册 用户选择"注册"菜单,进入注册界面.输入用户名和密码后,系统提示注册成功,并给出会员卡号. 登录 注册成功后,用户选择"登录"菜单,进入登录界面.输入注册时的用户名和密码.登录成功,系统提示欢迎信息.如果用户和密码输入错误,提示用户继续输入,最多有3次机会. 抽奖 登录成功后,用户选择"抽奖"菜单,进入幸运抽奖界面.输入会员卡号

  • Java实现游戏抽奖算法

    常用抽奖算法对比 基础的游戏抽奖算法通常要求实现在指定奖品的集合中,每个奖品根据对对应概率进行抽取.个人了解的主要有以下几中抽奖算法: 随机数一一对应 算法思想 这种算法思想最为简单.将n个奖品编号0 - N-1,其中各类奖品的概率通过其数量体现,最后程序产生0~n-1之间的随机数便是抽中的奖品编号.例如: 苹果手机概率1%,网站会员20%,折扣券20%,很遗憾59%.这样,编号0是苹果手机,1-20是会员,21-40是折扣券,41~100是 很遗憾.产生的随机数落在那个区间,就代表那个奖品被抽

  • Java实现抽奖功能

    本文实例为大家分享了Java实现抽奖功能的具体代码,供大家参考,具体内容如下 1 概述 项目开发中经常会有抽奖这样的营销活动的需求,例如:积分大转盘.刮刮乐.老虎机等等多种形式,其实后台的实现方法是一样的,本文介绍一种常用的抽奖实现方法. 整个抽奖过程包括以下几个方面: 奖品 奖品池 抽奖算法 奖品限制 奖品发放 2 奖品 奖品包括奖品.奖品概率和限制.奖品记录. 奖品表: CREATE TABLE `points_luck_draw_prize` ( `id` bigint(20) NOT N

  • Java实现多用户注册登录的幸运抽奖

    本文实例为大家分享了Java实现简单幸运抽奖的具体代码,供大家参考,具体内容如下 代码模块: User类: package test1; public class User { private String userName; private String password; private int vipID; public User(String userName,String password,int vipID) { this.userName = userName; this.pass

  • java实现砸金蛋抽奖功能

    本文实例为大家分享了java实现砸金蛋抽奖的具体代码,供大家参考,具体内容如下 代码如下 需求:用户每一次砸金蛋,抽中一等奖的概率为2% 二等奖10% 三等奖18% 四等奖70%. 累计砸第n次时必抽中x等奖以上的奖品.比如,累计砸第5次,则此次必中二等奖及以上的奖品.且配置的此次必中中奖概率不一样. /** * 金蛋抽奖 * userId : 抽奖用户ID * consumeType : 抽奖消耗的物品 1:金币 2:次数 */ @Override public Map<String, Obj

  • Java实现简单抽奖功能界面

    本文实例为大家分享了Java实现简单抽奖功能的具体代码,供大家参考,具体内容如下 要求:定义文本框添加姓名,将姓名存储并且在界面中可见,点击抽奖按钮进行抽奖并输出最后的中奖得主. 关于抽奖当然需要用到随机数的生成函数,在Java中Random 的使用合适比较简单的: 有两种不同的Random方法的使用,其中一种是Math中的random. 该方法生成的是0-1之间的浮点数,如果要生成整数类型的数字,可以乘一个整数,强制转换为整数类型. int n = (int)(Math.random()*x)

  • 纯java代码实现抽奖系统

    本文实例为大家分享了java实现抽奖系统 的具体代码,供大家参考,具体内容如下 模拟一个在终端登陆注册的页面 public class Cjtest { public static void main(String[] args) { String isGoOn = "n"; //循环的判断条件是否继续 do { System.out.println("*********幸运52********"); System.out.println("1.注册&qu

  • JAVA使用随机数实现概率抽奖

    本文实例为大家分享了JAVA使用随机数实现概率抽奖的具体代码,供大家参考,具体内容如下 需求 网站现有一抽奖功能,已经定义好奖品,每个奖品都有对应的中奖概率.通过奖品概率随机进行抽奖 实现思路 1.每个奖品都有对应的中奖概率,先对所有奖品中奖概率求和 2.计算出每个奖品在0-1之间所占的区间块 3.随机产生0-1之间的随机数,随机数落在哪个区间,就是中奖哪个 例如现有以下奖品: 奖品A 中奖概率为 0.1 奖品B 中奖概率为 0.01 奖品C 中奖概率为 0.001 奖品D 中奖概率为 0.8

随机推荐