我的代码看起来很业余,因为我是一名软件工程专业的二年级学生。
我创建了一个彩票号码生成器,并注意到了奇怪但一致的结果。我的程序试图匹配之前百万欧元抽奖的彩票号码。我跟踪它所做的尝试次数,并且跟踪我匹配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个数字的随机数生成的示例。
//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再次感谢可能组合的计算。我在程序中使用了这一方法,发现中奖所需的组合比组合的总数还要多。很可能我正在产生重复的随机数。由此,我可能会创建所有可能的组合,并随机选择每个组合,直到程序找到匹配。
发布于 2012-04-11 23:36:39
你的意思是你希望你赢的次数的比例是“随机的”吗?如果这就是你想要的,那么@真实性是非常正确的。要进一步阅读,您可以查看大数定律和中心极限定理。
如果你在问你的洗牌方法是否正确,那就是它是低效的。你所产生的随机数比所需的要多,因为你只是在检查它们发生的时候,而不是在你选择一个球之后创建一个新的随机数,所以你要求每个球至少有一个HashMap.get(int)。
我可以使用以下方法之一:
1)创建一个包含所有球值的ArrayList。对于每一张图,使用Collections.shuffle(yourArrList, rand)对它们的克隆进行洗牌,然后使用列表中的前5个球。
2)再次创建一个球值的数组或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;
}可能还有改进的余地,特别是如果秩序不重要的话。
发布于 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万个样本,你的估计也会接近精确的概率(你可以通过一些数学计算)。
发布于 2012-04-11 22:15:18
据我理解,百万欧元有两个不同的部分。五个球,然后是两个额外的球。你可以通过计算出获胜的确切概率来检查你的程序的数学。我相信你可以搜索它,但它很容易计算。
从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,800https://stackoverflow.com/questions/10114401
复制相似问题