math.random()遵循哪些算法

时间:2014-03-25 07:54:01

标签: java random

使用math.random()方法生成随机数。但我对这种方法有疑问。 math.random()是哪些算法可以生成随机数。还有其他随机数生成的算法吗?

尝试使用此代码,但我认为生成随机代码效率不高:

for (int i = 0; i < N; i++) {
     int sd = i + (int) (Math.random() * (N-i));

     String t = one[r];
     one[r] = one[i];
     one[i] = t;
 }

有没有更好的随机数生成算法?

5 个答案:

答案 0 :(得分:5)

Java主要根据您的使用情况提供四个随机数生成器API。

java.lang.Math.random()

如果我们检查Math class source code,我们可以查看:

private static Random randomNumberGenerator;

private static synchronized void initRNG() {
    if (randomNumberGenerator == null)
        randomNumberGenerator = new Random();
}

public static double random() {
    if (randomNumberGenerator == null) initRNG();
    return randomNumberGenerator.nextDouble();
}

Math.random()只是调用Random Class的快捷方式。它比java.util.Random更简单,更不完整,但在某些情况下它已经足够了。

java.util.Random中

Random类实现Linear Congruential Generator

LCG是伪随机数生成的一个非常简单的公式。 java.util.Random不是随机的,它是完全确定的。使用相同的初始条件(也称为种子),您可以按相同的顺序获得相同的结果。

使用java.util.Random适用于大多数用例(模拟,游戏,...),但由于其可预测性而不适合加密,因为这种用例更喜欢java.security.SecureRandom

java.util.Random是线程安全的,但在多线程上下文中可能存在性能问题。如果您使用的是多线程应用程序,请选择ThreadLocalRandom

java.security.SecureRandom中

SecureRandom类扩展java.util.Random类,以基于熵源实现加密强随机数生成器。 SecureRandom不具有确定性。

SecureRandom在您的平台(the complete implementation list)的功能中有多个实现。

由于熵源,

java.security.SecureRandom的速度低于java.util.Random

java.util.concurrent.ThreadLocalRandom

ThreadLocalRandom类是Linear Congruential Generator的另一个实现,但是这个实现不是线程安全的,而是专用于特定的线程。

This implementation is more fast than java.util.Random in multi-threaded context.

在您的情况下,您可以使用java.util.Collections.shuffle(list)使用java.util.Random或使用java.security.SecureRandom等特定随机生成器来随机播放数组。

答案 1 :(得分:2)

使用java.util.Random API

  

此类的实例用于生成伪随机数流。该类使用48位种子,使用线性同余公式进行修改。 (参见Donald Knuth,“计算机程序设计的艺术”,第3卷,第3.2.1节。)

算法类:伪随机数生成器,称为 PRNG 。您可以阅读更多相关信息here

注意:Math.random()也使用java.util.Random实例在内部生成伪随机数

答案 2 :(得分:1)

它使用伪随机数生成算法,即从整个系统中不断波动的数字。

您可能还会发现以下内容: - Pseudo-Random vs. True Random

同时检查 Source for java.util.Random

答案 3 :(得分:1)

做你想做的最简单的方法是

String[] words = ...
Collections.shuffle(Arrays.asList(words));

你是对的,生成一个随机的double然后把它变成一个小整数是没有效率的。幸运的是,Random有一种方法。

Random rand = new Random();
for (int i = words.length - 1; i > 0; i--) {
     int sd = rand.nextInt(i+1); // random number between 0 and i inclusive

     String t = words[r];
     words[r] = words[i];
     words[i] = t;
}

答案 4 :(得分:0)

以下是对数组进行随机播放的两种方法:

方法1:在数组中随机元素

方法2:Java Collection.shuffle()方法

您使用的方法是完成此任务的一种标准方法。

java中有两种方式:java.util.Randomjava.lang.Math.random. java.lang.Math.random()使用java.util.Random。 它只提供双打,没有播种能力。