Java抽奖概率算法
奖品
实体
package com.leigq.www.shiro.controller;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
/**
* 奖品 DTO
* <br/>
*
* @author :leigq
* @date :2019/7/5 23:00
*/
@Data
@Builder
@AllArgsConstructor
public class GiftDTO {
/**
* 索引
*/
private Integer index;
/**
* 奖品名称
*/
private String name;
/**
* 奖品编号
*/
private String no;
/**
* 中奖概率
*/
private Double probability;
}
抽奖方法
/**
* 抽奖方法
* <br/>
* create by: leigq
* <br/>
* create time: 2019/7/5 23:08
* @param orignalRates 商品中奖概率列表,保证顺序和实际物品对应
* @return 中奖商品索引
*/
public static int lottery(List<Double> orignalRates) {
if (orignalRates == null || orignalRates.isEmpty()) {
return -1;
}
int size = orignalRates.size();
// 计算总概率,这样可以保证不一定总概率是1
double sumRate = 0d;
for (double rate : orignalRates) {
sumRate += rate;
}
// 计算每个物品在总概率的基础下的概率情况
List<Double> sortOrignalRates = new ArrayList<>(size);
Double tempSumRate = 0d;
for (double rate : orignalRates) {
tempSumRate += rate;
sortOrignalRates.add(tempSumRate / sumRate);
}
// 根据区块值来获取抽取到的物品索引
double nextDouble = Math.random();
sortOrignalRates.add(nextDouble);
Collections.sort(sortOrignalRates);
return sortOrignalRates.indexOf(nextDouble);
}
测试
我这里就只用两个商品测试
public static void main(String[] args) {
List<GiftDTO> gifts = new ArrayList<>();
gifts.add(new GiftDTO(1, "一等奖", "P1", 0.4d));
gifts.add(new GiftDTO(2, "谢谢参与","P2", 0.6d));
// 存储概率
List<Double> orignalRates = new ArrayList<>(gifts.size());
for (GiftDTO gift : gifts) {
double probability = gift.getProbability();
if (probability < 0) {
probability = 0;
}
orignalRates.add(probability);
}
// 统计
Map<Integer, Integer> count = new HashMap<>();
// 测试次数
double num = 1000000;
for (int i = 0; i < num; i++) {
int orignalIndex = lottery(orignalRates);
Integer value = count.get(orignalIndex);
count.put(orignalIndex, value == null ? 1 : value + 1);
}
for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
System.out.println(gifts.get(entry.getKey()) + ", 命中次数=" + entry.getValue() + ", 实际概率="
+ entry.getValue() / num);
}
}
结果与预期差不多。
感谢
作者:不敲代码的攻城狮
出处:https://www.cnblogs.com/leigq/
任何傻瓜都能写出计算机可以理解的代码。好的程序员能写出人能读懂的代码。