首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java随机数发生器-抽奖

java随机数发生器-抽奖
EN

Stack Overflow用户
提问于 2012-04-11 21:40:49
回答 3查看 8.4K关注 0票数 0

我的代码看起来很业余,因为我是一名软件工程专业的二年级学生。

我创建了一个彩票号码生成器,并注意到了奇怪但一致的结果。我的程序试图匹配之前百万欧元抽奖的彩票号码。我跟踪它所做的尝试次数,并且跟踪我匹配3、4、5和6个数字的次数。

尝试的范围在100万到4.22亿之间。也就是说,我会运行程序10次,我会达到一个范围,我也会跟踪每次运行的时间长度。

我解释了许多事情,比如防止随机数被多次使用,这个检查是针对可能的彩票号码的HashMap进行的。如果在hashmap中找到随机数,则将该数字添加到数组列表中,然后从hashmap中删除该数字。

我的问题围绕着结果.

在所有与彩票号码相匹配的尝试中,我得到3个号码的机会平均为3.13%。4个数字下降到0.28%,5个数字下降到0.00012%,6个数字下降到0.00022%。

可以理解的是,随着彩票数量的增加,中奖的机会将会减少,然而,无论我尝试了100万次还是1亿次,这个比例都是相同的或非常接近的。

如果您感兴趣,我的最小尝试次数是1,088,157次,大约花费了6秒或6612 my。

最多的次数是422,036,905次,花费了26分钟,即1589867毫秒。

因为我使用的是Java随机库,所以我只是想了解一下这一点。还是我应该简单地把它归结为概率?

我的代码是一个不必要的225行,如果你想看到一个特定的部分或更愿意看到整个事情,那么请请求这个。下面是前5个数字的随机数生成的示例。

代码语言:javascript
复制
//stores all possible lottery numbers
public static  HashMap<Integer,Integer> randRange = new HashMap<Integer,Integer>();

//stores bonus ball numbers
public static  HashMap<Integer,Integer> boRange = new HashMap<Integer,Integer>();

//stores lottery number output
public static  ArrayList<Integer> lotNum = new  ArrayList<Integer>();

//stores bonus ball output
public static  ArrayList<Integer> boNum = new  ArrayList<Integer>();

public static void randomInt(){

    Random rand = new Random();

    //generate a random number
    int RandInt = rand.nextInt(51);
    int boInt = rand.nextInt(12);

    //loop used to get unique random number
    int count=0;
    while(count!=5){

        //check if random number exists
        if(randRange.get(RandInt)!=null)
        {
            //finalise random number
            RandInt=randRange.get(RandInt);

            //add to ArrayList
            lotNum.add(RandInt);

            //remove number
            //ensures next random number is unique
            randRange.remove(RandInt);

            count++;                
        }

        else
        {
            //get a new random number 
            //and start process again
            RandInt = rand.nextInt(51);
        }
    }
}

编辑:

首先,对不起,我不能投票,因为我的声誉还不到15个。所有的回答都很有帮助,包括评论。

多亏了所有成员的建议,我改进了我的程序,并在代码中发现了错误,这是不足为奇的。@digitaljoel您在匹配5和6个数字的概率上是正确的。我错误地设置了计算方法,例如,对于11,20,30,35,45,2,3的欧洲百万抽签,3为0.7%,4为.05%,5为.00273%,6为.000076%。

由于@maybewecouldstealavan,我改变了我的洗牌方法,只需填充一个ArrayList并洗牌列表,得到前五个数字,并对奖金球做同样的操作。好处是每秒检查的次数从每秒150-20万次增加到每秒250-70万次。

由于@真实性,在某些情况下,如果我检查了1000或100万匹配,变化是相似的或分钟。

@LeviX再次感谢可能组合的计算。我在程序中使用了这一方法,发现中奖所需的组合比组合的总数还要多。很可能我正在产生重复的随机数。由此,我可能会创建所有可能的组合,并随机选择每个组合,直到程序找到匹配。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-11 23:36:39

你的意思是你希望你赢的次数的比例是“随机的”吗?如果这就是你想要的,那么@真实性是非常正确的。要进一步阅读,您可以查看大数定律中心极限定理

如果你在问你的洗牌方法是否正确,那就是它是低效的。你所产生的随机数比所需的要多,因为你只是在检查它们发生的时候,而不是在你选择一个球之后创建一个新的随机数,所以你要求每个球至少有一个HashMap.get(int)。

我可以使用以下方法之一:

1)创建一个包含所有球值的ArrayList。对于每一张图,使用Collections.shuffle(yourArrList, rand)对它们的克隆进行洗牌,然后使用列表中的前5个球。

2)再次创建一个球值的数组或ArrayList。然后自己实现洗牌操作的一部分:从可能性的越来越小的子集中选择,并在不再适合刚刚选择的元素位置的元素中交换。优点是不需要对整个数组进行洗牌。下面是我的快速而肮脏的实现:

代码语言:javascript
复制
public static int[] choose(int[] array, int count, Random rand) {
    int[] ar = array.clone();
    int[] out = new int[count];
    int max = ar.length;
    for (int i = 0; i<count; i++) {
        int r = rand.nextInt(max); 
        //max is decremented, 
        //the selected value is copied out then overwritten 
        //by the last value, which would no longer be accessible
        max--;
        out[i]=ar[r];
        ar[r]=ar[max];
    }
    return out;
}

可能还有改进的余地,特别是如果秩序不重要的话。

票数 0
EN

Stack Overflow用户

发布于 2012-04-11 21:47:00

在所有与彩票号码相匹配的尝试中,我得到3个号码的机会平均为3.13%。4个数字下降到0.28%,5个数字下降到0.00012%,6个数字下降到0.00022%。 可以理解的是,随着彩票数量的增加,中奖的机会将会减少,然而,无论我尝试了100万次还是1亿次,这个比例都是相同的或非常接近的。

这其实一点也不奇怪。你最终要做的是估计猜错3,4,5或6个数字的概率。拥有更多的样本只会使你的估计中的变化更小,但是即使是“最小”的100万个样本,你的估计也会接近精确的概率(你可以通过一些数学计算)。

票数 4
EN

Stack Overflow用户

发布于 2012-04-11 22:15:18

据我理解,百万欧元有两个不同的部分。五个球,然后是两个额外的球。你可以通过计算出获胜的确切概率来检查你的程序的数学。我相信你可以搜索它,但它很容易计算。

从50个球中得到5个球的概率(订单不重要)

代码语言:javascript
复制
P(A) = 50!/5!(50-5)! = 2,118,760

在11个球中得到2个球的概率(顺序不重要)

代码语言:javascript
复制
P(B) 11!/2!(11-2)! = 55

这两个事件是独立的,所以把它们相乘。

代码语言:javascript
复制
P(A) * P(B) = P(A&B)
2,118,760 * 55 = 116,531,800

因此,中奖的机会是:

代码语言:javascript
复制
1 in 116,531,800
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10114401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档