C#怎么实现抽奖概率 三种算法的算法

C#&PHP&Java实现Alias Method概率抽奖算法_蓝狐软件工作室
.NET开发相关
Posted By : 蓝狐
最近在做抽奖服务端接口,会涉及到抽奖概率的问题,网上查资料找到一个比较好的抽奖概率的算法,Alias Method概率抽奖算法。今天就来分享一下这个算法的C#、PHP以及Java的实现。
举个例子,游戏中玩家推倒了一个boss,会按如下概率掉落物品:10%掉武器 20%掉饰品 30%掉戒指 40%掉披风。现在要给出下一个掉落的物品类型,或者说一个掉落的随机序列,要求符合上述概率。
一般会想到的两种解法
第一种算法,构造一个容量为100(或其他)的数组,将其中10个元素填充为类型1(武器),20个元素填充为类型2(饰品)...构造完毕之后,在1到100之间取随机数rand,取到的array[rand]对应的值,即为随机到的类型。这种方法优点是实现简单,构造完成之后生成随机类型的时间复杂度就是O(1),缺点是精度不够高,占用空间大,尤其是在类型很多的时候。
第二种就是一般的离散算法,通过概率分布构造几个点,[10, 30, 60, 100],没错,后面的值就是前面依次累加的概率之和(是不是像斐波那契数列)。在生成1~100的随机数,看它落在哪个区间,比如50在[30,60]之间,就是类型3。在查找时,可以采用线性查找,或效率更高的二分查找,时间复杂度O(logN)。
这里推荐一个大牛的两篇文章,从数学入手,探讨各种算法实现。&和&。想深入了解的朋友推荐看看。
参考他的文章中得到两个概念,PDF(密度分布函数)和 CDF(累积分布函数)两种概率分布,分别对应如上两种算法:
好了,现在就来说一下Alias Method(别名方法)
在这里我们不深究他的数学原理(&这篇文章里详述了其原理),来看看如何使用和实现。譬如说如上的PDF[0.1,0.2,0.3,0.4],将每种概率当做一列,别名算法最终的结果是要构造拼装出一个每一列合都为1的矩形,若每一列最后都要为1,那么要将所有元素都乘以4(概率类型的数量)
此时会有概率大于1的和小于1的,接下来就是构造出某种算法用大于1的补足小于1的,使每种概率最后都为1,注意,这里要遵循一个限制:每列至多是两种概率的组合。
最终,我们得到了两个数组,一个是在下面原始的prob数组[0.4,0.8,0.6,1],另外就是在上面补充的Alias数组,其值代表填充的那一列的序号索引,(如果这一列上不需填充,那么就是NULL),[3,4,4,NULL]。当然,最终的结果可能不止一种,你也可能得到其他结果。
等等,这个问题还没有解决,得到这两个数组之后,随机取其中的一列,比如是第三列,让prob[3]的值与一个随机小数f比较,如果f小于prob[3],那么结果就是3,否则就是Alias[3],即4。
我们可以来简单验证得到的概率是不是正确的,比如随机到第三列的概率是1/4,得到第三列下半部分的概率为1/4*3/5,记得在第一列还有它的一部分,那里的概率为1/4*(1-2/5),两者相加最终的结果还是3/10,符合原来的pdf概率。这种算法初始化较复杂,但生成随机结果的时间复杂度为O(1),是一种性能非常好的算法。
一、Alias Method概率抽奖算法的C#实现
using System.C
using System.Collections.G
using System.;
using System.T
using System.Threading.T
namespace Lanhusoft.Core
public class AliasMethod
/* The probability and alias tables. */
private int[] _
private double[] _
public AliasMethod(List&Double& probabilities)
/* Allocate space for the probability and alias tables. */
_probability = new double[probabilities.Count];
_alias = new int[probabilities.Count];
/* Compute the average probability and cache it for later use. */
double average = 1.0 / probabilities.C
/* Create two stacks to act as worklists as we populate the tables. */
var small = new Stack&int&();
var large = new Stack&int&();
/* Populate the stacks with the input probabilities. */
for (int i = 0; i & probabilities.C ++i)
/* If the probability is below the average probability, then we add
otherwise we add it to the large list.
if (probabilities[i] &= average)
large.Push(i);
small.Push(i);
/* As a note: in the mathematical specification of the algorithm, we
* will always exhaust the small list before the big list.
* due to floating point inaccuracies, this is not necessarily true.
* Consequently, this inner loop (which tries to pair small and large
* elements) will have to check that both lists aren't empty.
while (small.Count & 0 && large.Count & 0)
/* Get the index of the small and the large probabilities. */
int less = small.Pop();
int more = large.Pop();
/* These probabilities have not yet been scaled up to be such that
* 1/n is given weight 1.0.
We do this here instead.
_probability[less] = probabilities[less] * probabilities.C
_alias[less] =
/* Decrease the probability of the larger one by the appropriate
probabilities[more] = (probabilities[more] + probabilities[less] - average);
/* If the new probability is less than the average, add it into the
* otherwise add it to the large list.
if (probabilities[more] &= average)
large.Push(more);
small.Push(more);
/* At this point, everything is in one list, which means that the
* remaining probabilities should all be 1/n.
Based on this, set them
* appropriately.
Due to numerical issues, we can't be sure which
* stack will hold the entries, so we empty both.
while (small.Count & 0)
_probability[small.Pop()] = 1.0;
while (large.Count & 0)
_probability[large.Pop()] = 1.0;
* Samples a value from the underlying distribution.
* @return A random value sampled from the underlying distribution.
public int next()
long tick = DateTime.Now.T
var seed = ((int)(tick & 0xffffffffL) | (int)(tick && 32));
seed = (seed + Guid.NewGuid().GetHashCode() + new Random().Next(0, 100));
var random = new Random(seed);
int column = random.Next(_probability.Length);
/* Generate a biased coin toss to determine which option to pick. */
bool coinToss = random.NextDouble() & _probability[column];
return coinToss ? column : _alias[column];
二、Alias Method概率抽奖算法的PHP实现
class AliasMethod
private $prob_
public function __construct ($pdf)
$this-&length = 0;
$this-&prob_arr = $this-&alias = array();
$this-&_init($pdf);
private function _init($pdf)
$this-&length = count($pdf);
if($this-&length == 0)
die("pdf is empty");
if(array_sum($pdf) != 1.0)
die("pdf sum not equal 1, sum:".array_sum($pdf));
$small = $large = array();
$average=1.0/$this-&
for ($i=0; $i & $this-& $i++)
$pdf[$i] *= $this-&
if($pdf[$i] & $average)
$small[] = $i;
$large[] = $i;
while (count($small) != 0 && count($large) != 0)
$s_index = array_shift($small);
$l_index = array_shift($large);
$this-&prob_arr[$s_index] = $pdf[$s_index]*$this-&
$this-&alias[$s_index] = $l_
$pdf[$l_index] += $pdf[$s_index]-$
if($pdf[$l_index] & $average)
$small[] = $l_
$large[] = $l_
while(!empty($small))
$this-&prob_arr[array_shift($small)] = 1.0;
while (!empty($large))
$this-&prob_arr[array_shift($large)] = 1.0;
public function next_rand()
$column = mt_rand(0, $this-&length - 1);
return mt_rand() / mt_getrandmax() & $this-&prob_arr[$column] ? $column : $this-&alias[$column];
三、Alias Method概率抽奖算法的Java实现
package com.lanhusoft.
import android.util.L
import java.util.*;
import java.util.concurrent.atomic.AtomicI
public final class AliasMethod {
/* The random number generator used to sample from the distribution. */
private final R
/* The probability and alias tables. */
private final int[]
private final double[]
* Constructs a new AliasMethod to sample from a discrete distribution and
* hand back outcomes based on the probability distribution.
* Given as input a list of probabilities corresponding to outcomes 0, 1,
* ..., n - 1, this constructor creates the probability and alias tables
* needed to efficiently sample from this distribution.
* @param probabilities The list of probabilities.
public AliasMethod(List&Double& probabilities) {
this(probabilities, new Random());
* Constructs a new AliasMethod to sample from a discrete distribution and
* hand back outcomes based on the probability distribution.
* Given as input a list of probabilities corresponding to outcomes 0, 1,
* ..., n - 1, along with the random number generator that should be used
* as the underlying generator, this constructor creates the probability
* and alias tables needed to efficiently sample from this distribution.
* @param probabilities The list of probabilities.
* @param random
The random number generator
public AliasMethod(List&Double& probabilities, Random random) {
/* Begin by doing basic structural checks on the inputs. */
if (probabilities == null || random == null)
throw new NullPointerException();
if (probabilities.size() == 0)
throw new IllegalArgumentException("Probability vector must be nonempty.");
/* Allocate space for the probability and alias tables. */
probability = new double[probabilities.size()];
alias = new int[probabilities.size()];
/* Store the underlying generator. */
this.random =
/* Compute the average probability and cache it for later use. */
final double average = 1.0 / probabilities.size();
/* Make a copy of the probabilities list, since we will be making
* changes to it.
probabilities = new ArrayList&Double&(probabilities);
/* Create two stacks to act as worklists as we populate the tables. */
Deque&Integer& small = new ArrayDeque&Integer&();
Deque&Integer& large = new ArrayDeque&Integer&();
/* Populate the stacks with the input probabilities. */
for (int i = 0; i & probabilities.size(); ++i) {
/* If the probability is below the average probability, then we add
otherwise we add it to the large list.
if (probabilities.get(i) &= average)
large.add(i);
small.add(i);
/* As a note: in the mathematical specification of the algorithm, we
* will always exhaust the small list before the big list.
* due to floating point inaccuracies, this is not necessarily true.
* Consequently, this inner loop (which tries to pair small and large
* elements) will have to check that both lists aren't empty.
while (!small.isEmpty() && !large.isEmpty()) {
/* Get the index of the small and the large probabilities. */
int less = small.removeLast();
int more = large.removeLast();
/* These probabilities have not yet been scaled up to be such that
* 1/n is given weight 1.0.
We do this here instead.
probability[less] = probabilities.get(less) * probabilities.size();
alias[less] =
/* Decrease the probability of the larger one by the appropriate
probabilities.set(more,
(probabilities.get(more) + probabilities.get(less)) - average);
/* If the new probability is less than the average, add it into the
* otherwise add it to the large list.
if (probabilities.get(more) &= 1.0 / probabilities.size())
large.add(more);
small.add(more);
/* At this point, everything is in one list, which means that the
* remaining probabilities should all be 1/n.
Based on this, set them
* appropriately.
Due to numerical issues, we can't be sure which
* stack will hold the entries, so we empty both.
while (!small.isEmpty())
probability[small.removeLast()] = 1.0;
while (!large.isEmpty())
probability[large.removeLast()] = 1.0;
* Samples a value from the underlying distribution.
* @return A random value sampled from the underlying distribution.
public int next() {
/* Generate a fair die roll to determine which column to inspect. */
int column = random.nextInt(probability.length);
/* Generate a biased coin toss to determine which option to pick. */
boolean coinToss = random.nextDouble() & probability[column];
/* Based on the outcome, return either the column or its alias. */
/* Log.i("1234","column="+column);
Log.i("1234","coinToss="+coinToss);
Log.i("1234","alias[column]="+coinToss);*/
return coinToss ? column : alias[column];
public static void main(String[] args) {
TreeMap&String, Double& map = new TreeMap&String, Double&();
map.put("1金币", 0.2);
map.put("2金币", 0.15);
map.put("3金币", 0.1);
map.put("4金币", 0.05);
map.put("未中奖", 0.5);
List&Double& list = new ArrayList&Double&(map.values());
List&String& gifts = new ArrayList&String&(map.keySet());
AliasMethod method = new AliasMethod(list);
Map&String, AtomicInteger& resultMap = new HashMap&String, AtomicInteger&();
for (int i = 0; i & 100000; i++) {
int index = method.next();
String key = gifts.get(index);
if (!resultMap.containsKey(key)) {
resultMap.put(key, new AtomicInteger());
resultMap.get(key).incrementAndGet();
for (String key : resultMap.keySet()) {
System.out.println(key + "==" + resultMap.get(key));
http://blog.csdn.net/sky_zhe/article/details/
本站文章除注明转载外,均为本站原创或翻译,欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,共创和谐网络环境。
转载请注明:文章转载自: >>
本文标题:C#&PHP&Java实现Alias Method概率抽奖算法
本文地址:/Article/421.html
本科学历,蓝狐软件工作室创始人。2009年开始从事软件开发行业,从事软件开发互朕网7年以上,3年以上项目管理和架构设计经验,具有丰富的电子商务行业的移动和Web应用的架构设计和开发经验。参与过高并发、高可用、分布式系统设计,熟悉SOA架构设计,有敏捷开发经验。熟悉.NET和Java EE相关技术和框架,熟悉Linux、Windows、Nginx、Mysql等服务器的部署和优化。熟悉主流的开发语言,擅长SQL Server、mysql、Oracle等主流数据库,通过了Oracle OCP 11g认证,有丰富的数据库性能优化和设计经验。独立开发了多个人作品:蓝狐seo管理系统、seo关键词按天计费系统、蓝狐软件工作室门户等。曾在多家移动互联网担当核心技术研发和管理工作,同时承担关键技术难点攻关和设计高性能的技术架构。把握平台的技术发展方向,对技术发展及时提出指导性意见。在提高平台的稳定性、性能、质量等方面做出了重要贡献。目前专职于为企业提供优质的信息化建设服务,其中不限于系统、软件定制开发和高端网站建设。
发表成功!17:24 提问
求一个随机抽奖的算法
有没有这样一个算法,要求:
用n次随机结果代替排列组合的概率。
枚举step1到20
a=(int)(10000/(20-step+1))
b=(int)(10000×random)
如果b小于a则认为该step被选中。同时该step到20为止都不再计算概率。这样就完成从20个数里即时选出一个数,同时我运行了1000w组,统计得到每个step被选中的频率都是0.05;每二十个数会选中一个。
那么有没有这样的算法可以实现: 我要从二十个数中选三个,每个数都有0.15的中选可能,同时每20个数中必中三个。
按赞数排序
“20个数中必中三个”参考:
现在m=3,就算已知n=20也用不到。反正以20个为一组按这个算法选3。
这个算法我明白了,把经典概率转化为条件概率就可以了,然后我写了这个
[code=java]
public class hit {
public static int a[] = new int[21];
public static int b[] = new int[21];
public static int c[] = new int[21];
static boolean mark =// 记录是否发出一等奖
static int mark2 = 0;
boolean go_hit(int round) {// 伪随机方法
int fate = 0;
int rate = 0;
boolean temp =
if (mark == false) {
rate = (int) (10000 / (20 - round + 1));
fate = (int) (10000 * Math.random());
if (fate & rate) {
boolean go_hit2(int round) {// 伪随机方法
boolean temp =
int fate = 0;
int rate = 0;
if (mark2 &= 3) {
rate = (int) ((3 - mark2) * 1000 / (20 - round + 1));
rate = (int) (rate / 0.95);
fate = (int) (1000 * Math.random());
if (fate &= rate) {
mark2 = mark2 + 1;
public static void main(String[] args) {
int round = 0;
for (int i = 0; i & ; i++) {// 模拟1000000次
hit see = new hit();
round = 1;
mark2 = 0;
while (round &= 20) {
if (see.go_hit(round)) {
a[round] = a[round] + 1;// 累计结果观察概率
// System.out.println("一等奖" + round);// 模拟抽奖中奖过程
if (see.go_hit2(round)) {
b[round] = b[round] + 1;
// System.out.println("二等奖" + round);
c[round] = c[round] + 1;
// System.out.println("三等奖" + round);
for (int i = 1; i & a. i++) {
System.out.print("a" + i + "is" + "
" + a[i] + " ");// 查看概率
System.out.print("b" + i + "is" + "
" + b[i] + " ");// 查看概率
System.out.print("c" + i + "is" + "
" + c[i] + " ");// 查看概率
System.out.println("*");
有一个问题就是为什么我这里在20上的取值会少那么多,我加标记数组尝试了下,发现出现了不少二等奖只取两个数的特例,但是根据概率
P=(3-已取个数)/(20-位置+1)来看 就算前面一个不取,那最后三个的概率都是100%,为什么能出现只选择2个的情况???
@Tiger_Zhao
贴下整理后的代码:
public class fullhit{
public static int geted = 0;
public static boolean task =
public static int[] a = new int[21];
public static int[] b = new int[21];
public static int[] c = new int[21];
boolean first_hit(int round) {
tempmark =
int rate = 0;
int fate = 0;
rate = (int) ((4 - geted) * 10000 / (20 - round + 1));
fate = (int) (10000 * Math.random() + 1);
if (fate &= rate) {
tempmark =
int socend_hit() {
int tempint = 0;
r = (int) 10000 / (4 - geted + 1);
f = (int) (10000 * Math.random());
if ((task == false) & (f &= r)) {
tempint = 1;
tempint = 0;
public static void main(String[] args) {
int round = 0;
int s = 0;// 模拟楼层计数器
int ta = 0;// 一等奖检测
int tb = 0;// 二等奖检测
// 检测:不符合每20个出现1个一等奖和3个二等奖就终止程序
fullhit fh = new fullhit();
for (int i = 1; i &= ; i++) {//模拟10mX20个楼层
round = 0;
geted = 0;
while (round & 20) {
if (fh.first_hit(round)) {
if (fh.socend_hit() == 1) {
// 模拟一等奖;
a[round]++;
// 模拟二等奖;
b[round]++;
// 模拟三等奖;
c[round]++;
if (ta != 1) {
if (tb != 3) {
if (mark == false) {
System.out.println("error");
for (int i = 1; i &= 20; i++) {
// 查看选中概率
System.out.print("a" + i + "的个数=" + a[i] + "("+a[i]/10000+"%。)|");
System.out.print("b" + i + "的个数=" + b[i] + "("+b[i]/10000+"%。)|");
System.out.print("c" + i + "的个数=" + c[i]+"("+c[i]/10000+"%。)");
System.out.println("|");
s = a[i] + b[i] + c[i];
System.out.println(s);
运行结果:
a1的个数=%。)|b1的个数=%。)|c1的个数=%。)|
a2的个数=%。)|b2的个数=%。)|c2的个数=%。)|
a3的个数=%。)|b3的个数=%。)|c3的个数=%。)|
a4的个数=%。)|b4的个数=%。)|c4的个数=%。)|
a5的个数=%。)|b5的个数=%。)|c5的个数=%。)|
a6的个数=%。)|b6的个数=%。)|c6的个数=%。)|
a7的个数=%。)|b7的个数=%。)|c7的个数=%。)|
a8的个数=%。)|b8的个数=%。)|c8的个数=%。)|
a9的个数=%。)|b9的个数=%。)|c9的个数=%。)|
a10的个数=%。)|b10的个数=%。)|c10的个数=%。)|
a11的个数=%。)|b11的个数=%。)|c11的个数=%。)|
a12的个数=%。)|b12的个数=%。)|c12的个数=%。)|
a13的个数=%。)|b13的个数=%。)|c13的个数=%。)|
a14的个数=%。)|b14的个数=%。)|c14的个数=%。)|
a15的个数=%。)|b15的个数=%。)|c15的个数=%。)|
a16的个数=%。)|b16的个数=%。)|c16的个数=%。)|
a17的个数=%。)|b17的个数=%。)|c17的个数=%。)|
a18的个数=%。)|b18的个数=%。)|c18的个数=%。)|
a19的个数=%。)|b19的个数=%。)|c19的个数=%。)|
a20的个数=%。)|b20的个数=%。)|c20的个数=%。)|
其他相似问题&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!10:29 提问
求一个抽奖算法,最好java实现
需求如下:
总共分四等奖,
1等奖名额2个,中奖概率2/10000
2等奖名额10个,中奖概率5/1000
3等奖名额100个,中奖概率10/100
4等奖名额880个,中奖概率25/100
求一个算法,算出用户单次抽奖中奖等级(1,2,3,3等奖或不中奖)。
最好java实现。
按赞数排序
说个最简单的,用java的随机函数、用Random类生成随机数,也可以用Math类中的random生成
区别看这里:
选取一定的区间,比如0-1最为一等奖2/10000 ,选取一个50的区间作为2等奖50/10000
这样应该能满足你书的概率吧。
只是说一个思路。
如果是多用户抽奖怎么算
最简单的,比如你要2/10000概率,那么就用Random.NextDouble()返回一个随机数,因为随机数在0~1之间均匀分布,那么它在0~2/10000的概率就是0/10000
代码如下:
Double d = new Random().NextDouble();
if (d &= 2/10000.0)
其他相似问题php扩展(33)
php随记(38)
&* 全概率计算
&* @param array $p array('a'=&0.5,'b'=&0.2,'c'=&0.4)
&* @return string 返回上面数组的key
function random($ps){
&&& static $arr = array();
&&& $key = md5(serialize($ps));
&&& if (!isset($arr[$key])) {
&&&&&&& $max = array_sum($ps);
&&&&&&& foreach ($ps as $k=&$v) {
&&&&&&&&&&& $v = $v / $max * 10000;
&&&&&&&&&&& for ($i=0; $i&$v; $i++) $arr[$key][] = $k;
&&& return $arr[$key][mt_rand(0,count($arr[$key])-1)];
function get_rand($proArr) {&
&&& $result = '';
&&& //概率数组的总概率精度
&&& $proSum = array_sum($proArr);
&&& //概率数组循环
&&& foreach ($proArr as $key =& $proCur) {&
&&&&&&& $randNum = mt_rand(1, $proSum);&
&&&&&&& if ($randNum &= $proCur) {&
&&&&&&&&&&& $result = $&
&&&&&&&&&&&&
&&&&&&& } else {&
&&&&&&&&&&& $proSum -= $proC&
&&&&&&& }&
&&& unset ($proArr);
&&& return $&
上述代码是一段经典的概率算法,$proArr是一个预先设置的数组,假设数组为:array(100,200,300,400),开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内, 如果不在,则将概率空减,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。这样筛选到最终,总会有一个数满足要求。就相当于去一个箱子里摸东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。这个算法简单,而且效率非常高,关键是这个算法已在我们以前的项目中有应用,尤其是大数据量的项目中效率非常棒。
接下来我们通过PHP配置奖项。
$prize_arr = array(&
&&& '0' =& array('id'=&1,'prize'=&'平板电脑','v'=&1),&
&&& '1' =& array('id'=&2,'prize'=&'数码相机','v'=&5),&
&&& '2' =& array('id'=&3,'prize'=&'音箱设备','v'=&10),&
&&& '3' =& array('id'=&4,'prize'=&'4G优盘','v'=&12),&
&&& '4' =& array('id'=&5,'prize'=&'10Q币','v'=&22),&
&&& '5' =& array('id'=&6,'prize'=&'下次没准就能中哦','v'=&50),&
中是一个二维数组,记录了所有本次抽奖的奖项信息,其中id表示中奖等级,prize表示奖品,v表示中奖概率。注意其中的v必须为整数,你可以将对应的奖项的v设置成0,即意味着该奖项抽中的几率是0,数组中v的总和(基数),基数越大越能体现概率的准确性。本例中v的总和为100,那么平板电脑对应的中奖概率就是1%,如果v的总和是10000,那中奖概率就是万分之一了。
每次前端页面的请求,PHP循环奖项设置数组,通过概率计算函数get_rand获取抽中的奖项id。将中奖奖品保存在数组$res['yes']中,而剩下的未中奖的信息保存在$res['no']中,最后输出json个数数据给前端页面。
//如果中奖数据是放在数据库里,这里就需要进行判断中奖数量
//在中1、2、3等奖的,如果达到最大数量的则unset相应的奖项,避免重复中大奖
//code here eg:unset($prize_arr['0'])
foreach ($prize_arr as $key =& $val) {&
&&& $arr[$val['id']] = $val['v'];&
$rid = get_rand($arr); //根据概率获取奖项id
$res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项
//将中奖项从数组中剔除,剩下未中奖项,如果是数据库验证,这里可以省掉
unset($prize_arr[$rid-1]);&
shuffle($prize_arr); //打乱数组顺序
for($i=0;$i&count($prize_arr);$i++){&
&&& $pr[] = $prize_arr[$i]['prize'];&
$res['no'] = $&
echo json_encode($res);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:30983次
积分:2052
积分:2052
排名:第14685名
原创:161篇
转载:102篇
(2)(26)(24)(26)(11)(39)(30)(61)(36)(7)}

我要回帖

更多关于 java抽奖概率随机算法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信