Java 实现自定义概率性配置并随机抽取算法
最近在做一个奖品抽取的活动,可以自定义配置每个奖品的中奖概率,奖品的抽奖数和概率都可以动态配置的。比如说配置电脑0%,手机10%,ipad 5%,谢谢惠顾60%,1元优惠券25%这种配置。话不多说且看实现。
实现思路
1、首先构造一个概率实体类。为了通用性使用,我们可以使用泛型做实际的抽奖实物。
代码如下
@Data
@Accessors(chain = true)
public class ProbabilityEntity<T> {
private T entity;//实体
private Integer id; // id 区别实体的id,每个实体保证唯一
private Double ProbabilityValue;//概率值,0.1-100---》0.1%--100%
}
2、通过读取配置构造出概率实体列表,然后就可以抽奖了,抽奖算法思路分为以下
a.公平性检测
b. 基数建立
c. 基数分区
d.随机抽取
e. 返回结果
代码如下
public class MyAlgorithmUtil {
private MyAlgorithmUtil() {
}
/**
* 概率性抽奖
* @param probabilityEntityList 概率配置列表
* @param defaultValue 不符条件返回的默认结果
* @param <T> 抽奖的实体
* @return
*/
public static <T> ProbabilityEntity<T> probabilityLottery(List<ProbabilityEntity<T>> probabilityEntityList,ProbabilityEntity<T> defaultValue) {
// 公平性检测
if (probabilityEntityList.stream().mapToDouble(e -> e.getProbabilityValue()).summaryStatistics().getSum() != 100.00) {
System.out.println("概率总共不为1,公平性有偏差");
}
// 基数建立
Map<Integer, Integer> numbers = new HashMap<>();
for (ProbabilityEntity entity : probabilityEntityList) {
numbers.put(entity.getId(), (int) (entity.getProbabilityValue() * 10.0));
}
// 基数分区
int idxStart = 0;
int idxEnd = 0;
List<Integer> nums = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
nums.add(i);
}
Map<Integer, List<Integer>> numParts = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : numbers.entrySet()) {
idxEnd = idxStart + entry.getValue();
if (idxEnd >= 1000) {
idxEnd = 1000;
}
if (entry.getValue() > 0) {
numParts.put(entry.getKey(), nums.subList(idxStart, idxEnd));
}
idxStart = idxEnd;
}
// 随机抽取
Random random = new Random();
int r = random.nextInt(1000);
// 基础概率数
for (Map.Entry<Integer, List<Integer>> entry : numParts.entrySet()) {
List<Integer> value = entry.getValue();
if (value.contains(r)) {
List<ProbabilityEntity> entities = probabilityEntityList.stream().filter(e -> e.getId().equals(entry.getKey())).collect(Collectors.toList());
if (entities != null && entities.size() > 0) {
return entities.get(0);
}
}
}
return defaultValue;
}
}
测试结果
public static void main(String[] args) {
List<ProbabilityEntity<String>> probabilityEntities = new ArrayList<>();
// 电脑0%,手机10%,ipad 5%,谢谢惠顾60%,1元优惠券25%
probabilityEntities.add(new ProbabilityEntity<String>().setProbabilityValue(0.0).setId(1).setEntity("电脑"));
probabilityEntities.add(new ProbabilityEntity<String>().setProbabilityValue(10.0).setId(2).setEntity("手机"));
probabilityEntities.add(new ProbabilityEntity<String>().setProbabilityValue(5.0).setId(3).setEntity("ipad"));
probabilityEntities.add(new ProbabilityEntity<String>().setProbabilityValue(60.0).setId(4).setEntity("谢谢惠顾"));
probabilityEntities.add(new ProbabilityEntity<String>().setProbabilityValue(25.0).setId(5).setEntity("1元优惠券"));
ProbabilityEntity<String> defaultThanks = new ProbabilityEntity<String>().setEntity("谢谢惠顾")
.setId(4).setProbabilityValue(0.0);
ProbabilityEntity<String> entity = MyAlgorithmUtil.probabilityLottery(probabilityEntities,defaultThanks);
System.out.println("**********-----中奖结果---***********");
System.out.println("恭喜你抽中了 "+entity.getEntity());
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/TianH_legend/article/details/111065133