在java中生成随机数

时间:2010-03-13 02:31:45

标签: java

我想创建30个表,其中包含以下字段。例如,

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;

我需要在所有30个表中统一分发Service_Types。同样,我需要将反馈值1生成多次,而不是0和-1。

4 个答案:

答案 0 :(得分:2)

如果您有30个数字,并且您需要通过您的方法找到这30个数字,那么随机生成器将不适合您。在这种情况下,我认为将这30个数字添加到List并调用方法[Collections.shuffle] [1]来重新排列列表的内容,然后简单地用{{1}遍历它是更值得推荐的。阻止。如果你想要的是真正的随机数,那么你应该使用Random类,正如斯蒂芬解释的那样。

请记住,每次需要随机数时都不应该创建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()

最好使用for ... each,提供最大整数值,因为通常的做法Random.nextInt(int 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)

答案 1 :(得分:1)

在幕后,Math.random()正在使用java.util.Random的实例来生成数字。您可以直接使用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;

当然,Random生成的数字不是很随机,但它们肯定足以满足您的使用需求。但是,我想知道你是否真的不会更好地使用“循环”策略来分配设备上的负载。

答案 2 :(得分:0)

编辑:这个答案是基于对这个问题的误读,我把“除了0和-1以外的很多次”用来表示“比更多次” 0和-1“。如果它对其他人有用,我会把这个答案留下来,但我怀疑它对原版海报有用。


要生成非均匀随机数,您需要指定权重应该是什么。例如,也许你希望它的数量是0或-1的三倍。

这是一个采用三个double值的数组的方法,其中第一个值是-1的权重,第二个值是0的权重,第三个值是1的权重。这将根据您给出的权重以不同的概率生成-1,0或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 }(也就是说,是0或-1的3倍)调用了十万次,我得到了以下结果:

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

正如你所看到的,我获得的“1”结果大约是“0”结果的三倍或“-1”结果。

答案 3 :(得分:0)

你基本上可以有一个consumer_feedback代码列表(均匀分布),然后你从中删除代码,但使用随机索引,你可以保证你想要归属于'服务'的每个consumer_feedback代码的确切数量。

这是一个Groovy代码,它举例说明了这个概念:

假设:

  • 99条服务记录
  • 3个不同的consumer_feedback代码

要获得相同的分配,我必须为33'Services'分配'consumer_feedback代码',然后对每个代码进行分配。 (为简单起见,我选择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