抽奖的加权算法--按照权重概率中奖

懒驴 2022年01月12日 568次浏览

临近春节了,各大平台也好还是各个公司,大大小小都会搞一些抽奖之类的活动,那么随之而来的也涉及到开发各种各样的抽奖系统,有公平公正公开的,全随机抽奖,也有按照权重比例的来抽奖的。记得之前一个朋友做过的项目,功能也是抽奖活动,但是需求中有这样的要求,就是抽奖的奖品抽中的概率是可调的。就比如给到很大的奖品,但就是抽不到,抽到的概率为0。

下面就来介绍一种按照权重的随机抽奖方法的实现:
具体代码:


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/***
 * 权重抽奖的工具类
 */
public class LuckDrawUtil {
	
	/***
	 * 1.随机抽奖
	 * @param orignalRates 原始的概率列表,保证顺序和实际奖品对应
	 * @return
	 */
	public static int getLottery(List<Double> orignalRates){
		if (orignalRates == null || orignalRates.isEmpty()) {
			return -1;
		}
		int size = orignalRates.size();
		//计算总概率,这样可以保证不一定总概率是1
		double sumRate = 0d;
		for (double rate : orignalRates) {
			sumRate += rate;
		}
		//System.out.println("sumRate:"+sumRate);
		//计算每个物品在总概率的基础下的概率情况
		List<Double> sortOrignalRates = new ArrayList<Double>(size);
		Double tempSumRate = 0d;
		for (double rate : orignalRates) {
			tempSumRate += rate;
			sortOrignalRates.add(tempSumRate / sumRate);
		}
		//根据区块值来获取抽取到的物品索引
		double nextDouble = Math.random();
		//System.out.println("nextDouble:"+nextDouble);
		sortOrignalRates.add(nextDouble);   
		Collections.sort(sortOrignalRates); //排序
		//System.out.println("sortOrignalRates.indexOf(nextDouble):"+sortOrignalRates.indexOf(nextDouble));
		return sortOrignalRates.indexOf(nextDouble);
	}
	
}


首先获取所有奖品的权重值,然后计算出总的权重值,再依次计算出每一个的在占比总的比率后排序,最后随机一个索引,得到出对于的概率值就是对于的奖品啦。