java随机数发生器 - 彩票

时间:2012-04-11 21:40:50

标签: java random

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

我创建了一个彩票号码生成器,并注意到了奇特但一致的结果。我的节目试图匹配以前的欧元百万抽奖的彩票号码。我跟踪尝试的次数,并跟踪我匹配3,4,5和6号码的次数。

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

我考虑了许多事情,例如防止随机数被多次使用,并且这个检查是针对可能的彩票号码的HashMap完成的。如果我在hashmap中找到随机数,我会将数字添加到arraylist中,然后从hashmap中删除该数字。

我的问题围绕着结果。

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

可以理解随着彩票数量增加而获胜的机会将会减少,但无论我有100万次还是1亿次尝试,这个比率是相同还是非常接近。

如果您感兴趣,我的最小尝试次数为1,088,157次,大约需要6秒或6612ms。

最大尝试次数为422,036,905次,耗时26分钟或1589867次。

由于我使用的是Java Random库,所以我只是想要清楚一点。或者我应该简单地说明概率?

我的代码是不必要的225行,如果您想查看特定部分或者更愿意看到整个内容,请请求此处。下面是前5个数字随机数生成的示例。

//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为0.05%,5为.00273%,6​​为.000076%。

感谢@maybewecouldstealavan我改变了我的shuffling方法,只需填充一个ArrayList并对列表进行洗牌,得到前五个数字并对奖金球做同样的事情。好处是每秒的支票数量从每秒150-20万次增加到每秒250-700,000次支票。

感谢@trutheality,因为在某些情况下,如果我检查了1000或1,000,000个匹配,则变化相似或分钟。

@LeviX再次感谢可能组合的计算。我在程序中使用了这个,发现它花了超过组合总数来赢得彩票。我很可能正在制作重复的随机数。从此我可能会创建所有可能的组合,并随机选择每个组合,直到程​​序找到匹配。

3 个答案:

答案 0 :(得分:4)

  

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

     

可以理解随着彩票数量增加而获胜的机会将会减少,但无论我有100万次还是1亿次尝试,这个比率是相同还是非常接近。

这实际上并不令人惊讶。你最终在这里做的是估计正确猜测3,4,5或6个数字的概率。拥有更多样本只会使估算值的变化变小,但即使“100%样本”的变化很小,您的估计值也会接近准确的概率(您可以通过算数计算)。

答案 1 :(得分:0)

根据我的理解,Euro Millions有两个不同的部分。 5球,然后2个奖金球。您可以通过确定获胜的确切概率来检查您的计划的数学。我相信你可以谷歌,但它很容易计算。

从50个中获得5个球的可能性(顺序无关紧要)

P(A) = 50!/5!(50-5)! = 2,118,760

从11个中获得2个球的可能性(顺序无关紧要)

P(B) 11!/2!(11-2)! = 55

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

P(A) * P(B) = P(A&B)
2,118,760 * 55 = 116,531,800

因此,赢得彩票的机会是:

1 in 116,531,800

答案 2 :(得分:0)

你的意思是你认为你赢得的时间比例更“随机”吗?如果这就是你所得到的,那么@truthreality是完全正确的。如需进一步阅读,您可以查看law of large numberscentral limit theorem

如果你问的是你的洗牌方法是否正确,那就是效率低下。你生成的随机数超过了必要的数量,因为你只是在它们发生时检查它们,并且在你选择一个球后你没有创建一个新的随机数,所以你需要至少一个HashMap.get (int)每个选择。

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

1)创建一个包含所有球值的ArrayList。对于每个绘图,使用Collections.shuffle(yourArrList, rand)将它们的副本混合起来,然后使用列表中的前5个球。

2)再次,创建球值的Array或ArrayList。然后自己实现一部分随机操作:从可能性越来越小的子集中进行选择,并交换不再适合刚刚选择的元素位置的元素。优点是您不需要随机播放整个阵列。这是我快速而又肮脏的实现:

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;
}

可能还有改进的余地,特别是如果订单无关紧要的话。