2010-08-10 79 views
0

我需要從1到37生成6個唯一的隨機數;起初,我用一個簡單的數組映射:非均勻隨機發生器

private int k=6, n=37; 

public int[] Results() 
{ 
    // fill an array with numbers 1 2 3 . . . n 
    int[] numbers = new int[n]; 
    for (int i = 0; i < numbers.length; i++) 
     numbers[i] = i + 1; 

    // draw k numbers and put them into a second array 
    int result[] = new int[k]; 
    for (int i = 0; i < result.length; i++) 
    { 
     // make a random index between 0 and n - 1 
     int r = (int) (Math.random() * n); 
     // pick the element at the random location 
     result[i] = numbers[r]; 
     // move the last element into the random location 
     numbers[r] = numbers[n - 1]; 
     n--; 
    } 
    return result; 
} 

的問題是,在很多情況下我得到了近uniformic分佈(escpicially當我做出小於10平),即:1,9,16, 18,24,30或5,16,18,22,26,29

我真正需要的是一個TRUE隨機數發生器,可以給我如下結果: 11,16,25,29,30,32或4 ,8,9,15,18,19在LESS中10次抽籤。

我還看到一個HashMap實現類似的東西:

import java.util.*; 

public class RandomHash 
{ 
    HashMap numbers = new HashMap() ; 
    Random rnd_gen = new Random() ; 

    RandomHash() 
    { 
     for(;;) 
     { 
      int rnd_num = rnd_gen.nextInt() ; 
      Integer rnd_num_obj = new Integer(rnd_num) ; 

      if (! numbers.containsKey(rnd_num_obj)) 
      { 
       numbers.put(rnd_num_obj, rnd_num_obj) ; 
       /* Do whatever with the number */ 
       break ; 
      } /* else loop and get another rnadom num */ 

     } /*end for*/ 
    } 
} 

的問題是,我現在不知道怎麼分別向綁定的隨機和HashMap來6和32。散列表會給出更加混亂的結果嗎?

+1

定義「真正的隨機」的數字,並說明爲什麼你得到的產出是不是真正隨機的。 – 2010-08-10 18:02:23

+0

什麼是「非統一」?你的意思是「不統一」嗎?你需要什麼分配? – 2010-08-10 18:16:32

回答

2

我只是洗牌第一個數組(初始化步驟後),並採取前6個元素。你可以使用類似

Collections.shuffle(Arrays.asList(array)); 

使用語言的內置函數對數組進行洗牌。

如果您從1,000,000個元素中選擇,這可能是一個性能問題,但只有37個我認爲洗牌是一個更清晰的解決方案。

+1

那會使用32個隨機號碼嗎?我相信OP特別希望不超過10個。事實上,只有一個電話是可能的:請參閱我的答案。 – 2010-08-10 17:30:49

+0

@Moron:我沒有把它當作需求來閱讀。 – 2010-08-10 17:33:24

+1

「少於10次抽獎」。我解釋這意味着10個隨機數字電話。在任何情況下,洗牌都更加實用且不易出錯,32位數字可能不會成爲性能/準確度問題。所以+1 :-) – 2010-08-10 17:34:55

4

你可以在一個隨機號碼呼叫! 10是九太多:-)

請注意,有正確的37選擇6個可能性爲您的6個數字。

所以,你需要做的是選擇一個1到2324784之間的隨機數(這是37選6)。

然後使用映射來獲取6個元素的核心組合。有關映射的示例,請參閱此處:Generating the mth Lexicographical Element of a Mathematical Combination。在MSDN代碼

一個Java接口是在這裏:http://the-lost-beauty.blogspot.com/2010/07/generating-combinations-in.html

+0

您好,Moron,我需要幫助在這個代碼的Java實現。 C#對我來說太多的不匹配: -/ – Roey 2010-08-11 07:52:31

+0

@Roey:我編輯了答案以添加一個到Java代碼的鏈接。 – 2010-08-11 14:37:47

+0

THNX ALOT Moron( - : – Roey 2010-08-11 15:10:26

3

你問的隨機數,這是你會得到什麼。你的兩個例子:11,16,25,29,30,32和4,8,9,15,18,19簡直不像你認爲的均勻分佈的結果。

讓我們看看你最後的結果,並簡化說你期望所有的數字小於或等於19.如果你選擇1到32之間的單個數字,你有19/32的機會(appr 59%)爲19或更少。如果您選擇1到32之間的6個不同的數字,則所有這些數字少於3%的機率爲19或更少。

當運行代碼100次,事實上,我這五名名單滿足要求,這是兩個以上的統計預期:

[3,8,13,16,18,19]

[ 2,3,6,8,10,14]

[2,6,7,8,13,18]

[4,5,9,10,11,12]

[8,12,13,15,16,17]

0

線性同餘發生器模37,具有適當選擇的參數?

或者,

List l = Arrays.asList(numbers); 
Collections.shuffle(l); 
return l.subList(0,k).toArray(); 

注意,它預計數是一個Object []和返回另一個對象[]。

+0

您好tc, 如何/在哪裏可以在我的代碼中實施? 您能否寫下來? THNX – Roey 2010-08-11 06:39:21

+0

http://tinyurl.com/2coyye4 – 2010-08-11 13:35:39

0

這裏有一個非均勻分佈:

return new int[]{1,2,3,4,5,6};