Java 实现自定义概率性配置并随机抽取算法

1 篇文章 0 订阅
1 篇文章 0 订阅

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());
    }

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值