【问题标题】:Always the same random numbers in HashSetHashSet 中的随机数总是相同的
【发布时间】:2013-12-09 15:28:22
【问题描述】:

我有以下课程:

public class MyClass
{
    private Random rand;
    private HashSet<Pair<Integer, Integer>> set;

    public MyClass()
    {
       rand = new Random(Double.doubleToLongBits(Math.random()));
       set = new HashSet<Pair<Integer, Integer>>();
    }


    public void doSomething(int len)
    {   
        set.clear();

        for (int i = 0; i < 1000; i++)
        {
            int index = rand.nextInt(len - 1) + 1;

            int min = 1 - index;
            int max = len - index - 1;
            int j = rand.nextInt(max - min + 1) + min;

            if (j != 0)
            {   
               set.add(new Pair<Integer, Integer>(index, j));
            }
        }
    }
}

Pair 是一个自定义类,我可以在其中存储两个整数。问题是每次我调用doSomething() HashSet 总是包含相同的值。

这怎么可能?我该如何解决这个问题?

编辑:

这是我的一对:https://stackoverflow.com/a/677248/1395740

【问题讨论】:

  • equalshashCode 类的 Pair 方法是什么?
  • 你是创建了新的 MyClass 实例,还是使用旧的?
  • @Gladiator 我只使用了 MyClass 的一个实例,所以旧的...
  • 为什么不直接使用 new Random()
  • 您将什么 int 值作为参数传递给 doSomething() 调用?

标签: java random hashset


【解决方案1】:

来自documentation

这个类的一个实例用于生成一个流 伪随机数。该类使用 48 位种子,已修改 使用线性同余公式。 (参见 Donald Knuth, 计算机编程,第 3 卷,第 3.2.1 节。)

如果 Random 的两个实例使用相同的种子创建,并且 为每个方法调用相同的序列,它们将生成和 返回相同的数字序列。

【讨论】:

  • 这就是我的想法,但种子本身是随机的(new Random(Double.doubleToLongBits(Math.random())))。我查看了 Random 的实现,new Random() 使用了System.nanotime()
【解决方案2】:

Math.random 返回一个 double 并且 Random 接收一个 long 作为其种子。所以可能你每次都得到 0 作为种子。尝试更改为 System.getNanoTime() 只是为了进行测试,看看会发生什么。

【讨论】:

  • 这不是 OP 正在做的事情,OP 使用 Double.doubleToLongBits
【解决方案3】:

关于您的代码,当使用 5 作为 len 参数运行它时,结果如下: [(4, -2), (4, -1), (4, -3), (2, -1), (3, -1), (3, -2), (1, 1), ( 2, 1), (1, 2), (3, 1), (2, 2), (1, 3)] [(4, -2), (3, -1), (4, -1), (4, -3), (3, -2), (2, -1), (1, 1), ( 2, 1), (1, 2), (3, 1), (2, 2), (1, 3)]

如果你跟踪你的代码,它不是同一对,每次 doSomething 方法生成新的随机数,但在循环中,所有领先 j !=0 的数字都将被忽略,所以你将拥有那对,

你在这段代码中的问题

    int index = rand.nextInt(len - 1) + 1;
    int min = 1 - index;
    int max = len - index - 1;
    int j = rand.nextInt(max - min + 1) + min;

    if (j != 0)
    {   
       set.add(new Pair<Integer, Integer>(index, j));
    }

我的意思是,无论随机数是多少,这段代码都会得到相同的数字。

【讨论】:

  • 那么解决问题的方法是……?
  • 此代码将生成小于 len(方法参数)的两个整数(对)的所有概率,因此每次您将有相同的对具有顺从顺序时,解决方案将与您的业务有关,
猜你喜欢
  • 2016-08-26
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多