【问题标题】:Random numbers always in same order [duplicate]随机数总是以相同的顺序[重复]
【发布时间】:2012-10-12 23:01:15
【问题描述】:

可能重复:
Java random always returns the same number when I set the seed?

我正在使用 Java 的 Random 类和 nextInt() 方法来获取随机数。但似乎数字总是按相同的顺序排列。有没有办法解决这个问题?我知道一些随机生成器接收一个种子值,然后你使用系统计时器作为种子。

代码:

【问题讨论】:

  • 你在播种你的随机数生成器吗?
  • 看起来你不小心你的代码。请发布您目前是如何生成它们的,因为这将需要查看发生了什么问题。

标签: java random


【解决方案1】:

这才是你真正需要参考的https://stackoverflow.com/a/11705615/1143977。从参考链接中引用我的答案。

有两个问题导致您看到的内容。首先是代码为 Random 实例设置种子值。第二个是实例方法“random”实例化一个新的 Random 对象,然后每次都立即将其种子设置为相同的种子。这两者的结合保证了对于相同的 i 值,“随机”方法将始终返回相同的值,并且它始终是种子始终生成的序列中的第一个。

假设设置种子是强制性的,为了获取序列中的下一个值而不是每次序列的相同第一个值,Random 的 randnum 实例不能在其下一个方法获取之前每次都设置其种子叫。要解决此问题,请将 Random 的 randnum 局部变量实例从随机实例方法的范围移动到类范围。其次,仅在为 random 分配一个 Random 实例或仅从它获得相同的结果序列以重新开始时才设置种子。类 Random 的 setSeed(long seed) 实例方法不能在类范围内执行,因此构造函数必须使用带有 long seed 参数的 Random 构造函数来设置它。以下代码显示了更改:

public class RandomDemo { // arbitrary example class name
    // lots of class related stuff may be here...

    // still inside the class scope...
    // private is a good idea unless an external method needs to change it
    private Random randnum = new Random(123456789L);
    // the seed guarantees it will always produce the same sequence
    // of pseudo-random values when the next methods get called
    // for unpredicable sequences, use the following constructor instead:
    // private Random randnum = new Random();

    // lots of code may be here...

    // publicly exposed instance method for getting random number
    // from a sequence determined by seed 123456789L
    // in the range from 0 through i-1
    public int randnum(int i) {
        // don't set the seed in here, or randnum will return the exact same integer
        // for the same value of i on every method call
        // nextInt(i) will give the next value from randnum conforming to range i
        return randnum.nextInt(i);
    } // end randnum

    // lots of more code may be here...

} // end class RandDemo

如前所述,上述内容将为您的确切问题提供准确的解决方案。然而,考虑到它的作用,使用强制种子似乎不寻常。

下面解释了更多关于 Random、Random 的种子以及为什么有提供种子的规定。

Random 有两个构造函数:

Random()

Random(long seed)

还有一个实例方法

setSeed(long seed)

所有这些都会影响从 Random 实例获得的数字序列。实例方法,

setSeed(long seed)

将 Random 对象设置为与它刚刚使用与构造函数参数相同的种子实例化时的相同状态。仅使用种子值的低 48 位。

如果 Random 对象在没有种子的情况下被实例化,则种子将与系统时间相同,以毫秒为单位。这确保了除非两个 Random 对象在同一毫秒内被实例化,否则它们将产生不同的伪随机序列。仅使用种子值的低 48 位。这会导致不可预测的伪随机序列。每次调用 next 方法时获取一个新的 Random 实例是不必要且浪费计算资源的。

提供了 Random 的种子参数,以便可以实例化一个 Random 对象,该对象产生可重复的序列。对于给定的种子,无论何时使用该种子,都保证下一个方法中的值序列是相同的序列。这对于测试将使用伪随机序列的软件很有用,其中结果必须是可预测和可重复的。在操作中创建不同的不可预测的伪随机序列是没有用的。

【讨论】:

  • 如果您可以剪切并粘贴另一个问题的答案,您应该将此问题标记为重复。 (感谢您引用来源!)
  • 感谢您花时间向我解释随机功能,
【解决方案2】:

这应该每次都会给你随机数:

Time t = new Time();
t.setToNow();
mRandom = new Random(t.toMillis(false));
int rand = mRandom.nextInt(10);

【讨论】:

  • 来自Random() 构造函数文档:“初始状态(即种子)部分地基于当前时间(以毫秒为单位)。”因此,根据当前时间将其设置为 wholly 似乎不太随机。
【解决方案3】:

只创建一次 Random 对象(例如在应用程序的 onCreate 处),并且每次启动应用程序时它都会为您提供相对随机的结果。

【讨论】:

    【解决方案4】:

    要在Android中生成随机数,可以使用java.util.Random类。

    此类java.util.Random 提供了生成不同类型的伪随机数的方法,例如int、long、double 和float。

    它支持两个公共构造函数:

    1. Random() - 构造一个当前时间为 以毫秒为单位的天作为初始状态。

    2. Random(long seed) - 构造一个给定的随机生成器 种子作为初始状态。

    有关更多详细信息,请参阅以下链接:

    Generate random number in Android

    Generate Random number, Random()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-26
      • 1970-01-01
      • 1970-01-01
      • 2013-09-30
      • 2011-12-08
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多