游戏Algorithm----抽奖算法----奖品有权重的情况探讨

这么考虑的

相当于一个盒子里有好几个颜色的小球,每种颜色的小球有多个,每次取完,小球放回盒子内

	/**
	 * 每次取完放回盒内
	 * @param count 抽奖次数
	 * @param oddsMap 权值表
	 * @return
	 */
	public static <T> List<T> getLuckyDrawPutBack(int count,Map<T,Integer> oddsMap){
		List<T> list = Lists.newArrayList();
		SecureRandom rand = new SecureRandom();
		Map<T,Integer> factorMap = Maps.newHashMap();
		factorMap.putAll(oddsMap);
		if(null == factorMap || 0 == factorMap.size()){
			return list;
		}
		int sum = 0 ;
		for(Integer value : factorMap.values()){
			sum += value;
		}
		if(0 == sum){ 
			return list;
		}
		for(int i =0; i<count ;i++){
			int random = rand.nextInt(sum)+1;//均匀的产生1到SUM
			int overlapCount = 0; 
			for(Map.Entry<T, Integer> entry:factorMap.entrySet()){
				T key = entry.getKey() ;
				int value = entry.getValue() ;
				if((overlapCount < random) && (random <= (overlapCount+ value))){
					list.add(key);
					break;
				}
				overlapCount += value;
			}//for
		}
		return list;
	}

每次取完不放回盒内的情况

	/**
	 * 每次取完不放回盒内
	 * 抽取必有奖,奖可重复
	 * @param count 抽奖次数
	 * @param oddsMap
	 * @return
	 */
	public static <T> List<T> getLuckyDrawNobBack(int count,Map<T,Integer> oddsMap){
		List<T> list = Lists.newArrayList();
		SecureRandom rand = new SecureRandom();
		Map<T,Integer> factorMap = Maps.newHashMap();
		factorMap.putAll(oddsMap);
		if(null == factorMap || 0 == factorMap.size()){
			return list;
		}
		int sum = 0 ;
		for(Integer value : factorMap.values()){
			sum += value;
		}
		if(0 == sum){ 
			return list;
		}
		for(int i =0; i<count ;i++){
			int random = rand.nextInt(sum)+1;//均匀的产生1到SUM
			int overlapCount = 0; 
			for(Iterator<Map.Entry<T, Integer>> it = factorMap.entrySet().iterator();it.hasNext();){
				Map.Entry<T, Integer> entry = it.next();
				T key = entry.getKey() ;
				int value = entry.getValue() ;
				if((overlapCount < random) && (random <= (overlapCount+ value))){
					list.add(key);
					/* 
					 * 要取得不重复结果的方法
					 * it.remove();
					 * sum -= value;
					 */
					
					sum -= 1; //不放回盒内,个数减一
					entry.setValue(value-1);//
					break;
				}
				overlapCount += value;
			}//for
		}
		return list;
	}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值