转轮抽奖的算法实现

转轮抽奖的算法实现

抽奖

由于最近项目需要做一个抽奖活动,香港虚拟主机,于是实现了一个简单的抽奖算法,可以控制抽奖概率。提到抽奖,想必大家都见过玩过转轮抽奖吧,投一个币,然后转轮抽奖开始转动,当几个轮子的图片都是一样的时候就表示中奖了(当然还有大转盘的玩法,即投币后指针开始转动,转动停止后指针指向的那个位置就是判断中奖与否)。 1、抽奖原理

假设现在有三个转轮,每个转轮上有(1~10)数字图片。中奖情况如下:

每一次投币之后,系统会返回3个数字,中奖情况可以自由设定:

* 三个数字都相同:中大奖

* 三个数字中有两个相同:中小奖或不算中奖

* 三个数字都不同:没中奖 2、概率控制

每一个数字都有相应的概率值:

数字 物品 概率 1 苹果 5% 2 橘子 7% 3 香蕉 9% 4 葡萄 13% 5 荔枝 12% 6 柚子 14% 7 橙子 10% 8 柿子 11% 9 西瓜 8% 10 芒果 11%

每个转轮转动一次后会随机(根据概率)选中一个数字。

每个转轮上的数字的顺序是随机分配的。 第一个转轮选取过程(第一个默认顺序):

数字 物品 概率区段 1 苹果 0~5% 2 橘子 5~12% 3 香蕉 12~21% 4 葡萄 21~34% 5 荔枝 34~46% 6 柚子 46~60% 7 橙子 60~70% 8 柿子 70~81% 9 西瓜 81~89% 10 芒果 89~100%

* 在1~100之间产生一个随机数如:56

* 根据产生的随机数 56 放到转轮一中的概率区段去匹配,中奖数字是:6 第二个转轮选取过程:

数字 物品 概率区段 2 橘子 0~7% 1 苹果 7~12% 3 香蕉 12~21% 5 荔枝 21~33% 4 葡萄 33~46% 6 柚子 46~60% 7 橙子 60~70% 8 柿子 70~81% 10 芒果 81~92% 9 西瓜 92~100%

* 在1~100之间产生一个随机数如:77

* 根据产生的随机数77放到转轮一中的概率区段去匹配,中奖数字是:8 第三个转轮选取过程:

数字 物品 概率区段 4 葡萄 0~13% 10 芒果 13~24% 7 橙子 24~34% 1 苹果 34~39% 9 西瓜 39~47% 6 柚子 47~61% 3 香蕉 61~70% 8 柿子 70~81% 5 荔枝 81~93% 2 橘子 93~100%

* 在1~100之间产生一个随机数如:21

* 根据产生的随机数21放到转轮一中的概率区段去匹配,香港虚拟主机,中奖数字是:10 最终的抽奖结果:6,8,10即:柚子,柿子,网站空间,芒果,未中奖 3、代码 * 奖品类

package com.lottery.model;

/**

* @author zyd

* @date 2012-10-3

* @desc:

* 抽奖奖品

*/

public class Reward {

/**

* 奖品编号

*/

public int index;

/**

* 奖品名称

*/

public String name;

/**

* 中奖概率

*/

public int succPercent;

public Reward(int index, String name, int succPercent) {

super();

this.index = index;

this.name = name;

this.succPercent = succPercent;

}

@Override

public String toString() {

return “Reward [index=” + index + “,, succPercent=”

+ succPercent + “]”;

}

} * 抽奖算法类

package com.lottery.util;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import com.lottery.model.Reward;

/**

* @author zyd

* @date 2012-10-3

* @desc:

* 抽奖主类

*/

public class Lottery {

public static List<Reward> randomList;

/**

* 获取中奖编码数组

* @param rlist

* @param keyLength

* @return

*/

public List<Reward> getKeys(List<Reward> rlist,int keyLength){

List<Reward> list = new ArrayList<Reward>();

for(int i=0;i<keyLength;i++){

list.add(getKey(rlist));

}

return list;

}

/**

* 获取中奖编码

* @param rlist

* @return

*/

private Reward getKey(List<Reward> rlist) {

//随机列表

List<Reward> randomList = getRandomList(rlist);

//根据随机列表得到的概率区段

List<Integer> percentSteps = getPercentSteps(rlist);

//概率区段的最大值

int maxPercentStep = percentSteps.get(percentSteps.size()-1);

//在概率区段范围内取一个随机数

int randomStep = new Random().nextInt(maxPercentStep);

//中间元素的下标

int keyIndex = 0;

int begin = 0;

int end = 0;

for(int i=0;i<percentSteps.size();i++){

if(i == 0){

begin = 0;

}else{

begin = percentSteps.get(i-1);

}

end = percentSteps.get(i);

//判断随机数值是否在当前区段范围内

if(randomStep>begin && randomStep<=end){

keyIndex = i;

break;

}

}

return randomList.get(keyIndex);

}

/**

* 获取概率区段[如:10,15,25,30,40,60,75,80,90,95,100]

* @param rlist

* @return

*/

private List<Integer> getPercentSteps(List<Reward> rlist) {

List<Integer> percentSteps = new ArrayList<Integer>();

int percent = 0;

for(Reward r: rlist){

percent += r.succPercent;

percentSteps.add(percent);

}

return percentSteps;

}

/**

* 获取随机列表

* @param rlist

* @return

*/

private List<Reward> getRandomList(List<Reward> rlist){

List<Reward> oldList = new ArrayList<Reward>(rlist);

List<Reward> newList = new ArrayList<Reward>();

//随机排序的老序列中元素的下标

int randomIndex = 0;

//随机排序下标的取值范围

int randomLength = 0;

for(int i=0;i<rlist.size();i++){

//指向下标范围

randomLength = oldList.size()-1;

//取值范围元素的个数为多个时,从中随机选取一个元素的下标

if(randomLength != 0){

randomIndex = new Random().nextInt(randomLength);

//取值范围元素的个数为一个时,直接返回该元素的下标

}else{

randomIndex = 0;

}

//在新的序列当中添加元素,同时删除元素取值范围中的randomIndex下标所对应的元素

newList.add(oldList.remove(randomIndex));

}

return newList;

}

} * 测试类

package com.lottery.test;

import java.util.ArrayList;

import java.util.List;

import com.lottery.model.Reward;

import com.lottery.util.Lottery;

/**

* @author zyd

* @date 2012-10-3

* @desc:

* 测试

*/

public class Test {

public static void main(String[] args){

List<Reward> rlist = initRewards();

Lottery lottery = new Lottery();

List<Reward> rewards = null;

for(int i=0;i<1000;i++){

rewards = lottery.getKeys(rlist, 3);

if(isWinner(rewards)){

System.out.println(“============================抽奖开始 第”+i+”次 ===============================”);

for(Reward r:rewards){

System.out.println(r);

}

System.out.println(“============================抽奖结束===============================”);

}

}

}

public static boolean isWinner(List<Reward> list){

boolean isWinner = false;

for(int i=0;i<list.size();i++){

for(int j=i+1;j<list.size();j++){

if(list.get(i).index != list.get(j).index){

return false;

}else{

isWinner =true;

}

}

}

return isWinner;

}

public static List<Reward> initRewards(){

List<Reward> rlist = new ArrayList<Reward>();

rlist.add(new Reward(1, “香蕉”, 5));

rlist.add(new Reward(2, “苹果”, 15));

rlist.add(new Reward(3, “橘子”, 5));

rlist.add(new Reward(4, “葡萄”, 15));

rlist.add(new Reward(5, “荔枝”, 5));

rlist.add(new Reward(6, “西瓜”, 5));

rlist.add(new Reward(7, “柚子”, 20));

rlist.add(new Reward(8, “橙子”, 10));

rlist.add(new Reward(9, “柿子”, 5));

rlist.add(new Reward(10, “芒果”, 15));

return rlist;

}

} * 测试输出

============================抽奖开始 第82次 ===============================

Reward [index=1, name=香蕉, succPercent=5]

Reward [index=1, name=香蕉, succPercent=5]

Reward [index=1, name=香蕉, succPercent=5]

============================抽奖结束===============================

============================抽奖开始 第115次 ===============================

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

============================抽奖结束===============================

============================抽奖开始 第510次 ===============================

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

============================抽奖结束===============================

============================抽奖开始 第542次 ===============================

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

============================抽奖结束===============================

============================抽奖开始 第584次 ===============================

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

Reward [index=9, name=柿子, succPercent=5]

============================抽奖结束===============================

============================抽奖开始 第706次 ===============================

Reward [index=5, name=荔枝, succPercent=5]

Reward [index=5, name=荔枝, succPercent=5]

Reward [index=5, name=荔枝, succPercent=5]

============================抽奖结束===============================

posted on

你在无垠的海边第一次听到了自己心跳的声音,

转轮抽奖的算法实现

相关文章:

你感兴趣的文章:

标签云: