我想知道java.util.Random.next(n)
是否与n呈线性比例或是一个常数?有人可以帮我这个或者告诉我如何确定复杂性吗?
答案 0 :(得分:9)
来自文档:
Random.nextInt(n)使用Random.next()平均不到两次 使用它一次,如果获得的值高于最高倍数 在MAX_INT以下的n再次尝试,否则返回该值 modulo n(这可以防止高于n的最大倍数的值 低于MAX_INT偏差分布),所以返回一个值 均匀分布在0到n-1的范围内。
根据文档,java.util.Random.next
实现如下
synchronized protected int next(int bits) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
}
因此复杂性为O(1)
旁注: -
您可以使用多种工具来测量微基准测试的复杂性。您可以在here上找到一个列表。但是,如果运行时复杂性对您很重要,您可以使用Fast Mersenne Twister。(这是一个外部库来衡量运行时复杂性,因为Javas随机数生成器非常快,但统计上很糟糕)
答案 1 :(得分:8)
next
的Javadoc解释
方法
next
由Random类实现,通过原子方式将种子更新为
(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
并返回
(int)(seed >>> (48 - bits))
显然,这些表达式中没有O(n)复杂性的痕迹。
答案 2 :(得分:3)
如果this source code example仍然相关,则运行时为O(1)
。
173: protected synchronized int next(int bits)
174: {
175: seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
176: return (int) (seed >>> (48 - bits));
177: }
我认为这是由于Oracle对如何生成随机数in this page的解释所致。
此类的实例用于生成伪随机流 数字。该类使用48位种子,使用a修改 线性同余公式。 (见唐纳德克努特,计算机艺术 编程,第2卷,第3.2.1节。)