2012-04-11 81 views
0

我的代碼看起來業餘,因爲我是第二年的軟件工程學生。java隨機數發生器 - 彩票

我創建了一個彩票號碼發生器,並已注意到特殊但一致的結果。我的程序試圖匹配以前的歐洲百萬彩票抽獎號碼。我跟蹤它需要的嘗試次數,並且還跟蹤匹配3,4,5和6個數字的次數。

這些嘗試的範圍在100萬到422百萬之間。即我會運行程序10次,我會達到一個範圍,我也會跟蹤每次運行所花費的時間。

我考慮了很多事情,例如防止隨機數被多次使用,並且此檢查是針對可能的彩票號碼的HashMap完成的。如果我在散列表中找到隨機數字,我將數字添加到數組列表中,然後從散列表中刪除數字。

我的問題圍繞着結果。

在所有匹配彩票號碼的嘗試中,我獲得3個號碼的機會平均爲3.13%。 4個數字下降到0.28%,5個數字0.00012%,6個數字0.00022%。

可以理解隨着彩票數量增加,獲勝的機會將會減少,但無論我有100萬次還是1億次嘗試,這個比例是相同的還是非常接近的。

如果你有興趣,我的最小嚐試次數是1,088,157次,大約需要6秒或6612ms。

嘗試次數最多的是422,036,905次,耗時26分鐘或1589867ms。

因爲我正在使用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爲0.7%,4爲0.05%,5爲0.00273%,6​​爲0.00776%。

感謝@maybewecouldstealavan我改變了我的洗牌方法,簡單地填充一個ArrayList和洗牌列表,得到前五個數字,併爲獎金球做同樣的事情。好處在於每秒支票數量從每秒150-200萬支票增加到每秒250-700萬支票。

感謝@trutheality在某些情況下,如果我檢查1000或1,000,000匹配的變化是相似或分鐘。

@LeviX再次欣賞可能組合的計算。我在程序中使用了這個功能,發現花費的彩票組合總數超過了總數。我最有可能產生重複的隨機數字。從這我可能會創建所有可能的組合,並隨機選擇每個組合,直到程​​序找到匹配。

+3

我在這裏看到的唯一驚喜是,你匹配6個數字的可能性是你匹配5個數字的兩倍,而我希望你不太可能匹配更多的數字。 – digitaljoel 2012-04-11 21:51:25

+0

你的問題到底是什麼?你期望什麼? – KeatsPeeks 2012-04-11 22:10:34

+0

@Samuel_xL我正在尋找一個解釋,爲什麼當使用java隨機庫,我保持在同一範圍內的百分比。爲了公平起見,我應該說明這一點,我猜想會有很多因素可能影響我的結果,但我不確定它們是什麼。 – thirdOctet 2012-04-11 22:43:55

回答

0

你的意思是你期望的,你贏得更多的「隨機」倍的比例?如果這就是你所得到的,那麼@真實性是非常正確的。爲了進一步閱讀,你可以看看law of large numberscentral limit theorem

如果你問你的洗牌方法是否正確,它雖然效率低下。你生成的隨機數超過了必要的數值,因爲你只是在發生錯誤時檢查它們,而且在你選擇一個球之後你不會創建一個新的隨機數,所以你至少需要一個HashMap.get (int)。

我可能會使用以下方法,而不是之一:

1)創建一個包含所有球值的ArrayList。對於每張圖紙,使用Collections.shuffle(yourArrList, rand)來對它們進行克隆,然後使用列表中的前5個球。

2)再次,創建一個數組或球列表的ArrayList。然後自己實施一部分shuffle操作:從可能性的較小和較小子集中進行選擇,並在不再適合剛剛選擇的元素位置的元素中進行交換。好處是你不需要洗牌整個陣列。這裏是我的快速和骯髒的實施:

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

感謝您的建議,我知道它可以更有效率,我看着你的建議鏈接,真的很有幫助! – thirdOctet 2012-04-12 07:49:55

4

在所有匹配彩票號碼的嘗試中,我獲得3個號碼的機會平均爲3.13%。 4個數字下降到0.28%,5個數字0.00012%,6個數字0.00022%。

可以理解隨着彩票數量增加,獲勝的機會將會減少,但無論我有100萬次還是1億次嘗試,這個比例是相同的還是非常接近的。

這實際上並不令人意外。你最終在這裏做的是估計正確猜測3,4,5或6個數字的概率。有更多的樣本只會使你的估計值的變化更小,但即使是100萬樣本「儘可能少」,你的估計值也會接近確切的概率(你可以通過計算一些數學來計算)。

0

根據我的理解,歐洲百萬富翁有兩個不同的部分。 5個球,然後是2個獎金球。您可以通過確定獲勝的確切概率來檢查您的程序的數學。我相信你可以谷歌它,但它很容易計算。獲得5個球總分50(順序無關緊要)得到2個球的11(順序無關緊要)

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

兩個的

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

概率

概率事件是獨立的,所以把它們放在一起。

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

因此彩票中獎的機會是:

1 in 116,531,800 
+0

感謝獨特世代的總數,我會用這個數字來實現一個檢查,即如果我不能在1.16億次嘗試中產生中獎組合,那麼打破程序並返回匹配的彩票號碼總數。 – thirdOctet 2012-04-12 07:46:14