2016-05-15 43 views
-1

我想製作一個程序,它將生成一個隨機數。我知道我需要爲此使用Math.random(),但我想爲可重複的數字設置比率。例如,我希望編譯器給出1-10的數字,但我想要5重複3次以上,而不是另一個數字。我怎麼做?請幫助謝謝。嗨我想用math.random設置它重複的可能性

+1

我不認爲這是可能的Math.random。你必須編寫你自己的函數來以這種方式生成隨機數。你可以使用Math.random,但不同。 – mhyst

回答

1

這將有5拿出至少3倍,經常爲其他9個數字:

private static int getRandom() 
{ 
    Random r = new Random(); 

    int next = r.nextInt(100000) + 1; 

    if (next <= 25000) 
    { 
     return 5; 
    } 
    else 
    { 
     return r.nextInt(10) + 1; 
    } 
} 

注意:您也可以排除5在其他情況下,試圖打「 3倍「可能更好。我不是爲了簡單。

另一變型: 這裏是使用nextInt()代替十萬分之二萬五千分裂的模量的變化。 另外,我把代碼放在else的情況下,試圖排除5(沒有無限循環)。

​​

測試代碼

public static void main(String[] args) 
{  
    Map<Integer, Integer> frequecnyMap = new HashMap<Integer, Integer>(); 

    for (int i = 0; i < 12000; i++) 
    { 
     int r = getRandom(); 

     Integer n = frequecnyMap.get(r); 

     if (n == null) 
     { 
      frequecnyMap.put(r, 1); 
     } 
     else 
     { 
      frequecnyMap.put(r, n + 1); 
     } 
    } 
    System.out.println(frequecnyMap); 
} 

樣本輸出(第二變形例)

{1 = 971,2 = 975,3 = 995,4 = 1037 ,5 = 3025,6 = 1042,7 = 995,8 = 976,9 = 969,10 = 1015}

{1 = 1016,2 = 1019,3 = 994,4 = 968, 5 = 3068,6 = 1030,7 = 996,8 = 914, 9 = 990,10 = 1005}

{1 = 939,2 = 944,3 = 979,4 = 986,5 = 3023, 6 = 1040,7 = 1007,8 = 1046,9 = 997,10 = 1039}

+0

啊我看到,使用100k和75k而不是4和3非常重要:P。 – Tom

+0

是不是5的頻率是1/4而不是1/10的正常情況?在你的代碼中,它的頻率是3/4。我錯了嗎? – MaxG

+1

@MaxG你是對的。 75000需要25000.將更新。謝謝。 –

0

如果您希望您的隨機生成的數字完全控制,你應該做這樣的事情:

public class MyRandom { 
    private int[] probability; 
    private long[] ntimes; 
    private long times; 

    public MyRandom(int[] probability) { 
     this.probability = new int[10]; 
     System.arraycopy(probability, 0, this.probability, 0, probability.length); 
     ntimes=new long[10]; 
     for(int i=0; i < ntimes.length; i++) 
      ntimes[i]=0; 
     times=0; 
    } 

    public void showProbability() { 
     for (long i : probability) { 
      System.out.print(i+" "); 
     } 
     System.out.println(); 
    } 

    public int random() { 
     int t = 10; 

     int r = (int)Math.floor(Math.random()*10+1); 
     double p = 0; 
     if (times == 0) 
      p = 0; 
     else 
      p = ntimes[r-1]*100/times; 

     System.out.println("P: "+p +" : "+probability[r-1]); 
     while (p > probability[r-1] && t > 0) { 
      r = (int)Math.floor(Math.random()*10+1); 
      p = ntimes[r-1]*100/times;    
      t--; 
     } 
     ntimes[r-1]++; 
     times++; 
     return r; 
    } 

    public long getOcurrences(int i) { 
     return ntimes[i-1]; 
    } 


    //This is an example of how to use it.   
    public static void main(String[] args) { 
     int[] p = {5, 5, 5, 5, 30, 5, 5, 5, 10, 15}; 
     MyRandom mr = new MyRandom(p); 

     for (int i = 0; i < 2000; i++) { 
      int r = mr.random(); 
      System.out.println("Id: "+i+" Number: "+r+" Ocurrences: "+mr.getOcurrences(r)); 
     } 
    } 
} 
1

首先,您應該使用Random類,而不是Math.random()。首先,它有很好的幫助方法nextInt(int n),它產生一個0到n-1(含)之間的隨機整數。

在你的特定情況下,你需要一個數字1-10,所以生成0-9並加1,即nextInt(10) + 1

但您希望5的次數多出現3次。一個快速骯髒的方式是產生兩個額外的號碼(1-12),並將它們映射到5

Random rnd = new Random(); 
int num = rnd.nextInt(12) + 1; 
if (num == 11 || num == 12) 
    num = 5; 

正如我所說,快速和骯髒的,但它確實爲您的特定情況下的伎倆。


現在,對於更通用的解決方案,您希望能夠指定加權概率。數字1-4,6-10的權重爲1,5的權重爲3.

然後你做的是對權重求和(12),並生成一個隨機數,然後找到數字,累計重量超過隨機數。

下面是一個方法:

private static int random(Random rnd, int ... weights) { 
    if (weights.length < 2) 
     throw new IllegalArgumentException("Need at least two weights"); 
    int total = 0; 
    for (int weight : weights) { 
     if (weight <= 0) 
      throw new IllegalArgumentException("Invalid weight: " + weight); 
     if ((total += weight) < 0) 
      throw new IllegalArgumentException("Weight overflow"); 
    } 
    for (int i = 0, val = rnd.nextInt(total); ; i++, val -= weights[i]) 
     if (val < weights[i]) 
      return i; 
} 

然後,您可以這樣調用它:

Random rnd = new Random(); 
int num = random(rnd, 1,1,1,1,3,1,1,1,1,1) + 1; 

通知的+1,因爲該方法是像Random.nextInt(n),並返回一個數字0到n -1,其中n是給定權重的數量。

你可以很容易地將它變成一個很好的類,在構造函數中給出權重,並且類爲你管理Random對象。

請注意,隨着權重數量的增加,性能將會下降。有一種方法可以使用TreeMapbinarySearch來改善,但您需要類實現,以便它可以準備數據。

2

正是出於這個情況:

private static final int[] CHOICES = new int[] { 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9, 10 }; 
public static int strangeRandom() { 
    return CHOICES[ThreadLocalRandom.current().nextInt(CHOICES.length)]; 
} 

從一組給定的&你控制的選擇,使5更可能選擇隨機選擇。