当前位置: 首页 > 面试题库 >

随机数分布

鱼渝
2023-03-14
问题内容

我有两种代码选择:

选项1

int myFunc() {
  return new Random().nextInt();
}

要么:

选项2

private static final Random random = new Random();

int myFunc() {
  return random.nextInt();
}

我了解这option 2更惯用。我想知道的有效性option 1

option 1我将只使用由给定的种子产生的第一个号码。在“ option 2我选择一个种子”并n使用该种子生成数字。IIUC在此用例上保证了随机性。

因此,我的问题是,如果我option 1多次打电话,是否能保证产出分配的均匀性?


问题答案:

我真正的问题是选项1在数学上是否有效。

让我们从选项2开始。所使用的随机数生成器java.util.Random在javadoc中指定如下:

该类使用48位种子,可以使用线性同余公式对其进行修改。(请参见Donald Knuth,计算机编程艺术,第2卷,第3.2.1节)。

各种方法的javadocs中有更具体的细节。

但是关键是我们正在使用由线性同余公式生成的序列,并且这些公式具有很大程度的自相关…这可能是有问题的。

现在,在选项1中,您Random每次都使用一个具有新种子的不同实例,并应用一轮LC公式。因此,您得到的数字序列可能与种子自相关。但是,种子的生成方式不同,具体取决于Java版本。

Java 6这样做:

 public Random() { this(++seedUniquifier + System.nanoTime()); }
 private static volatile long seedUniquifier = 8682522807148012L;

…这不是完全随机的。如果您Random以固定的间隔创建实例,则种子很可能间隔很近,因此,选项#1产生的随机数序列可能会自动关联。

相比之下,Java 7和8做到了:

 public Random() {
     this(seedUniquifier() ^ System.nanoTime());
 }

 private static long seedUniquifier() {
     // L'Ecuyer, "Tables of Linear Congruential Generators of
     // Different Sizes and Good Lattice Structure", 1999
     for (;;) {
         long current = seedUniquifier.get();
         long next = current * 181783497276652981L;
         if (seedUniquifier.compareAndSet(current, next))
             return next;
     }
 }

 private static final AtomicLong seedUniquifier
     = new AtomicLong(8682522807148012L);

由上述方法产生的种子的序列可能是(真实)随机性的更好近似。这可能会使您的选择#1优于选择#2。

Java 6至8中的#1选项的缺点是,System.nanoTime()可能的调用涉及系统调用。那是比较昂贵的。

因此,简短的答案是,从数学的角度来看,选项#1和选项#2中哪个产生了更好的质量“随机”数字,这是Java版本所特有的。

在这两种情况下,在足够大的样本量下,数字的分布将是均匀的,尽管我不确定在确定性过程中谈论概率分布是否有意义。

但是,这两种方法都不适合用作“密码强度”随机数生成器。



 类似资料:
  • 问题内容: 我试图识别/创建一个函数(在Java中),该函数给我一个非均匀的分布式数字序列。如果我有一个函数说它将给我一个从到的随机数。 该函数最适合任何给定的函数,下面仅是我想要的示例。 但是,如果我们说函数将返回来自分布式的s nonuni。 我想例如说 约占所有案件的20%。 大约是所有情况的50%。 约占所有案件的20%。 大约是所有情况的10。 总之somting,给我一个数字,如正态分

  • 本文向大家介绍python随机数分布random测试,包括了python随机数分布random测试的使用技巧和注意事项,需要的朋友参考一下 因为概率问题,所以需要测试一下python的随机数分布。到底是平均(均匀)分布,还是正态(高斯)分布。 测试代码如下: 测试结果: Test random.choice()---------------------------: loop num:  1000

  • 每次产生一个随机数。 用法 Your browser does not support the video tag. 案例:掷骰子 功能:设置随机数范围1-6,每按一下按钮,产生一个随机数 工作原理 当输入由no变为yes时,一个随机数将会被传送到输出。你可以通过配置改变随机数的范围 例如:一个随机变色的灯

  • 问题内容: 我知道如果我使用Java的Random生成器,并使用nextInt生成数字,则数字将均匀分布。但是,如果我使用2个Random实例,并使用两个Random类生成数字,会发生什么。数字是否会均匀分布? 问题答案: 每个实例生成的数字将均匀分布,因此,如果将两个实例生成的随机数序列组合在一起,则它们也应均匀分布。 请注意,即使结果分布是均匀的,您也可能要注意种子,以避免两个生成器的输出之间

  • 主要内容:实例,实例,概率分布,实例,实例,实例,实例,实例,实例,实例,数据分析,实例,实例,实例随机数 Verilog 中使用系统任务 $random(seed) 产生随机数,seed 为随机数种子。 seed 值不同,产生的随机数也不同。如果 seed 相同,产生的随机数也是一样的。 可以为 seed 赋初值,也可以忽略 seed 选项,seed 默认初始值为 0。 不使用 seed 选项和指定 seed 并对其修改来调用 $random 的代码如下所示: 实例     //seed va

  • 问题内容: 最重要的答案是建议使用switch语句来完成这项工作。但是,如果我要考虑的情况很多,那么代码看起来就很笨拙。我有一个巨大的switch语句,在每种情况下都一遍又一遍地重复非常相似的代码。 当您要考虑的概率很大时,是否有更好,更干净的方法来选择具有一定概率的随机数?(例如〜30) 问题答案: 这是一个Swift实现,受各种答案的影响很大,这些答案会生成具有给定(数字)分布的随机数 对于