我的代码看起来很业余,因为我是第二年的软件工程专业学生。
我创建了一个彩票号码生成器,并注意到了奇特但一致的结果。我的节目试图匹配以前的欧元百万抽奖的彩票号码。我跟踪尝试的次数,并跟踪我匹配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再次感谢可能组合的计算。我在程序中使用了这个,发现它花了超过组合总数来赢得彩票。我很可能正在制作重复的随机数。从此我可能会创建所有可能的组合,并随机选择每个组合,直到程序找到匹配。
答案 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 numbers和central 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;
}
可能还有改进的余地,特别是如果订单无关紧要的话。