2010-03-13 96 views
1

我想創建30個由以下字段組成的表。例如,在java中生成隨機數

 
Service_ID Service_Type  consumer_feedback 
    75   Computing  1     
    35   Printer   0     
    33   Printer   -1     
3 rows in set (0.00 sec) 
 
mysql> select * from consumer2; 
Service_ID Service_Type  consumer_feedback 
    42   data    0 
    75   computing  0 
 
mysql> select * from consumer3; 
Service_ID Service_Type  consumer_feedback 
    43   data   -1 
    41   data    1 
    72   computing  -1 

正如你可以從上面的表推斷,我收到的反饋值。我使用隨機數的概念生成了這些consumer_feedback值,Service_IDService_Type。我已經使用功能:

int min1=31;//printer 
int max1=35;//the values are generated if the Service_Type is printer. 
int provider1 = (int) (Math.random() * (max1 - min1 + 1)) + min1; 
int min2=41;//data 
int max2 =45 
int provider2 = (int) (Math.random() * (max2 - min2 + 1)) + min2; 
int min3=71;//computing 
int max3=75; 
int provider3 = (int) (Math.random() * (max3 - min3 + 1)) + min3;   
int min5 = -1;//feedback values 
int max5 =1; 
int feedback = (int) (Math.random() * (max5 - min5 + 1)) + min5; 

我需要Service_Types要在所有的30臺均勻分佈。同樣,我需要反饋值1產生多次,而不是0和-1。

+0

參見http://stackoverflow.com/questions/2339508/random-numbers-in-java/2343296#2343296 – trashgod 2010-03-13 02:58:40

回答

1

在引擎蓋下,Math.random()正在使用java.util.Random的實例來生成數字。

做這樣的事情:你可以直接使用隨機的API避免映射從雙打到整數雜亂

import java.util.Random; 

... 

private static Random prng = new Random(); 

... 

int min1=31;//printer 

int max1=35;//the values are generated if the Service_Type is printer. 

int provider1 = prng.nextInt(max1 - min1 + 1) + min1; 

當然,真實的隨機生成的數字都不是很隨機的,但他們肯定對於你的用例來說足夠好。但是,我想知道,如果使用「循環」策略將負載分配到各個設備上,您是否會做得更好。

2

如果您有30個號碼,並且您需要通過您的方法找到這30個號碼,那麼隨機生成器不會對您有好處。在這種情況下,我認爲將這30個數字添加到一個列表中並且調用方法[Collections.shuffle] [1]來對列表中的內容進行混洗,然後簡單地用for ... each塊進行遍歷,會更值得推薦。如果你想要的是真正的隨機數,那麼你應該使用Random類,就像Stephen解釋的那樣。

只要記住,你在每一次需要一個隨機數時間不能創建Random類的新實例:

 
public Random() 

Creates a new random number generator. Its seed is initialized to a value based on the current time: 

    public Random() { this(System.currentTimeMillis()); } 

Two Random objects created within the same millisecond will have the same sequence of random numbers. 

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Random.html#Random()

這是一個很好的做法,使用Random.nextInt(int n),提供最大的整數值,如常規做法Random.nextInt() % n不會生成均勻分佈的數字。

如果你需要50和100之間的數字,它是這樣簡單:

 
Random r = new Random(); 
public int yourMethod() { 
    return r.nextInt(50) + 50; 
} 

[1]:http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#shuffle(java.util.List,java.util.Random中)

0

編輯:這個答案是基於對這個問題的誤讀,我把「除0和-1以外的許多次」表示爲「許多更多次比0和-1」。如果這個答案對其他人有用,我會離開這個答案,但我懷疑它對原始海報會有用。


要生成不均勻的隨機數,您將需要指定權重應該是什麼。例如,也許你想要有三倍於1的值,就像0或-1一樣。

這是一個採用三個值爲double的數組的方法,其中第一個值是-1的權重,第二個值是0的權重,第三個值是1的權重。這將生成-1,0或1,並根據您給出的權重以不同的概率出現。

$ java RandomTest | sort | uniq -c 
    20062 -1 
    19776 0 
    60162 1 

public int minusOneZeroOrOne(final double[] weights) 
{ 
    if (weights.length != 3) 
     throw new IllegalArgumentException("Must provide three weights"); 
    double weightTotal = 0.0; 
    for (final double next : weights) 
     weightTotal += next; 
    double random = Math.random() * weightTotal; 
    if (random < weights[0]) 
     return -1; 
    if (random < (weights[0] + weights[1])) 
     return 0; 
    return 1; 
} 

餘通過與重量陣列{ 1.0, 1.0, 3.0 }(即,三次許多1的作爲0或-1的)十萬次,與我得到了以下結果調用它測試此方法

正如你所看到的,我獲得了「1」結果的大約三倍,因爲我得到了「0」結果或「-1」結果。

+0

正如@raviaw已經指出的,通過使用'java.util.Random'而不是'Math.random()',你可以使這段代碼變得更好。但是,爲了簡單起見,我在這裏使用'Math.random()'。我也可能提供了命名參數,而不是使用'double []'作爲參數列表,但是,這只是一個例子。 :-) – 2010-03-13 03:01:54

+0

OP要求*均勻分佈的數字...... – 2010-03-13 03:38:55

+0

啊,好吧,我誤讀了句子「同樣我需要反饋值1多次產生,而不是0和-1。」。我認爲這意味着「比0和-1多得多」。 – 2010-03-13 03:42:25

0

您基本上可以擁有一個consumer_feedback代碼列表(平均分佈),然後從中刪除代碼,但使用隨機索引,您可以保證每個consumer_feedback代碼的確切數量歸於'服務' 。

這是一個Groovy代碼舉例說明概念:

假設:

  • 99服務記錄
  • 3種不同的consumer_feedback碼

爲具有相等的分配我必須分配一個'consumer_feedback代碼'到33'服務',並且對每一個都做。 (爲簡便起見,我選擇哪個多個的3個數字,你的問題有3個consumer_feedback碼)

//Creating the pool of available feedback codes 
feedbacks = [] 
feedback = 0; 
3.times { 
    33.times { 
     feedbacks << feedback 
    } 
    feedback++ 
} 

rnd = new Random() 

idx = 0 
services = [:] 
99.times { 
    services["Service_${idx++}"] = 
     feedbacks.remove(rnd.nextInt(feedbacks.size())) 
} 

println Collections.frequency(services.values(), 0) 
println Collections.frequency(services.values(), 1) 
println Collections.frequency(services.values(), 2) 

println services