Java抽奖算法第二例

 更新时间:2021年09月17日 11:03:26   作者:go2shell  
这篇文章主要为大家详细介绍了Java抽奖算法,根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下

1. 算法分析

根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品。

2.代码

核心算法 

public class Arithmetic {
  // 放大倍数
  private static final int mulriple = 1000000;

  public int pay(List<Prize> prizes) {
    int lastScope = 0;
    // 洗牌,打乱奖品次序
    Collections.shuffle(prizes);
    Map<Integer, int[]> prizeScopes = new HashMap<Integer, int[]>();
    Map<Integer, Integer> prizeQuantity = new HashMap<Integer, Integer>();
    for (Prize prize : prizes) {
      int prizeId = prize.getPrizeId();
      // 划分区间
      int currentScope = lastScope + prize.getProbability().multiply(new BigDecimal(mulriple)).intValue();
      prizeScopes.put(prizeId, new int[] { lastScope + 1, currentScope });
      prizeQuantity.put(prizeId, prize.getQuantity());

      lastScope = currentScope;
    }

    // 获取1-1000000之间的一个随机数
    int luckyNumber = new Random().nextInt(mulriple);
    int luckyPrizeId = 0;
    // 查找随机数所在的区间
    if ((null != prizeScopes) && !prizeScopes.isEmpty()) {
      Set<Entry<Integer, int[]>> entrySets = prizeScopes.entrySet();
      for (Map.Entry<Integer, int[]> m : entrySets) {
        int key = m.getKey();
        if (luckyNumber >= m.getValue()[0] && luckyNumber <= m.getValue()[1] && prizeQuantity.get(key) > 0) {
          luckyPrizeId = key;
          break;
        }
      }
    }

    if (luckyPrizeId > 0) {
      // 奖品库存减一
    }

    return luckyPrizeId;
  }
}

Prize bean

public class Prize {

  /**
   * 奖品唯一标示
   */
  private Integer prizeId;

  /**
   * 中奖概率
   */
  private BigDecimal probability;

  /**
   * 奖品数量
   */
  private Integer quantity;

  public Integer getPrizeId() {
    return prizeId;
  }

  public void setPrizeId(Integer prizeId) {
    this.prizeId = prizeId;
  }

  public BigDecimal getProbability() {
    return probability;
  }

  public void setProbability(BigDecimal probability) {
    this.probability = probability;
  }

  public Integer getQuantity() {
    return quantity;
  }

  public void setQuantity(Integer quantity) {
    this.quantity = quantity;
  }

}

3.测试

prize1概率: 5% 
prize2概率: 10% 

prize3概率: 15% 
prize4概率: 20% 

prize5概率: 50% 


public class Test {
  public static void main(String[] args) {
    List<Prize> prizes = new ArrayList<Prize>();
    Prize prize1 = new Prize();
    prize1.setPrizeId(1);
    prize1.setProbability(new BigDecimal(0.05));
    prize1.setQuantity(1);
    prizes.add(prize1);

    Prize prize2 = new Prize();
    prize2.setPrizeId(2);
    prize2.setProbability(new BigDecimal(0.10));
    prize2.setQuantity(10);
    prizes.add(prize2);

    Prize prize3 = new Prize();
    prize3.setPrizeId(3);
    prize3.setProbability(new BigDecimal(0.15));
    prize3.setQuantity(20);
    prizes.add(prize3);

    Prize prize4 = new Prize();
    prize4.setPrizeId(4);
    prize4.setProbability(new BigDecimal(0.20));
    prize4.setQuantity(50);
    prizes.add(prize4);

    Prize prize5 = new Prize();
    prize5.setPrizeId(5);
    prize5.setProbability(new BigDecimal(0.50));
    prize5.setQuantity(200);
    prizes.add(prize5);

    int prize1GetTimes = 0;
    int prize2GetTimes = 0;
    int prize3GetTimes = 0;
    int prize4GetTimes = 0;
    int prize5GetTimes = 0;
    Arithmetic arithmetic = new Arithmetic();
    int times = 1000;
    for (int i = 0; i < times; i++) {
      int prizeId = arithmetic.pay(prizes);
      switch (prizeId) {
        case 1:
          prize1GetTimes++;
          break;
        case 2:
          prize2GetTimes++;
          break;
        case 3:
          prize3GetTimes++;
          break;
        case 4:
          prize4GetTimes++;
          break;
        case 5:
          prize5GetTimes++;
          break;
      }
    }
    System.out.println("抽奖次数" + times);
    System.out.println("prize1中奖次数" + prize1GetTimes);
    System.out.println("prize2中奖次数" + prize2GetTimes);
    System.out.println("prize3中奖次数" + prize3GetTimes);
    System.out.println("prize4中奖次数" + prize4GetTimes);
    System.out.println("prize5中奖次数" + prize5GetTimes);
  }
}

结果:

 

通过1000次抽取,我们看出算法精度还是很高的。

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

相关文章

  • springboot+mybatis拦截器方法实现水平分表操作

    springboot+mybatis拦截器方法实现水平分表操作

    这篇文章主要介绍了springboot+mybatis拦截器方法实现水平分表操作,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • Java中Integer128的坑

    Java中Integer128的坑

    本文主要介绍了Java中Integer128的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-03-03
  • 关于Java中使用jdbc连接数据库中文出现乱码的问题

    关于Java中使用jdbc连接数据库中文出现乱码的问题

    这篇文章主要介绍了关于Java中使用jdbc连接数据库中文出现乱码的问题,默认的编码和数据库表中的数据使用的编码是不一致的,如果是中文,那么在数据库中执行时已经是乱码了,需要的朋友可以参考下
    2023-04-04
  • Springboot启动同时创建数据库和表实现方法

    Springboot启动同时创建数据库和表实现方法

    这篇文章主要介绍了Springboot启动同时创建数据库和表,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Mybatis表的关联查询详情

    Mybatis表的关联查询详情

    这篇文章主要介绍了Mybatis表的关联查询详情,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 如何基于springcloud模拟RPC调用(Feign)

    如何基于springcloud模拟RPC调用(Feign)

    这篇文章主要介绍了如何基于springcloud模拟RPC调用(Feign),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • spring4新特性之web开发增强

    spring4新特性之web开发增强

    这篇文章主要介绍了spring4新特性之web开发增强的相关资料,需要的朋友可以参考下
    2017-09-09
  • springboot配置flyway(入门级别教程)

    springboot配置flyway(入门级别教程)

    本文介绍了springboot配置flyway,主要介绍基于SpringBoot集成flyway来管理数据库的变更,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • 深入聊一聊JDK中的Map和Set

    深入聊一聊JDK中的Map和Set

    这篇文章主要给大家介绍了关于JDK中Map和Set的相关资料,文中通过示例代码以及图文介绍的非常详细,对大家学习或者使用jdk具有一定的参考学习价值,需要的朋友可以参考下
    2022-12-12
  • SpringBoot3+graalvm:整合并打包为可执行文件方式

    SpringBoot3+graalvm:整合并打包为可执行文件方式

    本文介绍了如何在Spring Boot 3中整合GraalVM,并将其打包为可执行文件,适用于Windows和Linux系统,通过安装GraalVM、配置环境变量、下载Visual Studio组件(仅限Windows)以及使用Maven容器(适用于Linux),可以实现高效的打包和运行
    2024-12-12

最新评论