【问题标题】:Is it possible to divide a pseudorandom是否可以划分伪随机数
【发布时间】:2016-05-11 18:04:39
【问题描述】:

我需要分发一个使用伪随机数的 Java 系统。系统的每个节点都必须处理一定数量的随机数。

结果必须是可重现的,因此随机数必须依赖于种子作为参数。

Random random = new Random(long seed);

例如,如果我需要处理 100 个随机数并且我有 2 个节点,则第一个节点必须处理 1 到 50,第二个节点必须处理 51 到 100。

问题在于伪随机数需要迭代自己,以便每次都产生相同的随机数序列(对于相同的种子)。

在前面的例子中,有没有办法从第 51 个随机数开始在第二个节点中生成随机数? (因此,避免了在此节点中生成和丢弃 1 到 50 的随机数)。

【问题讨论】:

  • 不是特别的。你最好弄清楚如何在节点之间划分随机数的另一种方案,例如两个节点将使用每隔一个随机数,而不是前 50 个和后 50 个。即使您更改节点数,您是否需要它是可重现的?如果不是这样,可以通过使用第一个 Random 生成的种子来键入其他 Random 实例来使事情变得更容易。
  • 嗯...这不能解决我的问题,因为每个节点无论如何都必须处理到第 100 个随机数。
  • 不要使用伪随机序列,而是使用哈希函数。第一个节点将处理 1..50 的哈希值,第二个节点将处理 51..100 的哈希值
  • 怎么不是解决方案?跳过某些输入的特定节点与处理每个输入不同。
  • 因为这个过程不是很复杂。问题的复杂性在于必须生成的随机数。例如,500'000.000。

标签: java random random-seed


【解决方案1】:

random.nextInt(50) + 50 呢?

您可以使用相同的种子,在一个节点上执行“+ 0”,在另一个节点上执行“+ 50”。

如果您不喜欢这样,您现在将在两个节点上获得相同的序列,相差 50,您可以使用相同的种子从随机生成器为每个节点构造一个种子。

节点 1:

Random seedGenerator = new Random(globalSeed)
Random myRandom = new Random(seedGenerator.nextInt())
int something = myRandom.nextInt(50)

节点 2:

Random seedGenerator = new Random(globalSeed)
seedGenerator.nextInt() // node 1's seed
Random myRandom = new Random(seedGenerator.nextInt())
int something = myRandom.nextInt(50) + 50

节点 1 将为您提供 0 到 50 之间的整数,节点 2 将为您提供 50 到 100 之间的整数。

【讨论】:

  • 这个策略的问题是,如果我需要改变处理随机数的节点数量,它就行不通了。然后我会用第三个节点做什么?例如,我必须在随机数中添加 +100。然后从 1 到 100 的随机序列就不一样了。
  • 我不认为这是想要 0 到 50 之间的 数字,而是需要 Random 生成的前 50 个数字和第二个 50 的数字Random 会生成。
【解决方案2】:

您可以使用另一种方法来生成伪随机序列:考虑改用哈希函数(整数 -> 整数类型),并将其全部转换为自然数,因此序列中的项目将改为 hash(0), hash(1), hash(2)seed, step(seed), step(step(seed))。这样您就可以访问O(1) 中伪随机序列中的ith 元素,并且可以根据需要分配工作负载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2013-08-24
    相关资源
    最近更新 更多