我必须找到每个数组元素的第n个nextInt。 下面的代码确实很慢,因为数组元素超过40k,每个数组元素超过一百万。
int[] numbers ={1000000,1004300,2204000,1306000...40k+};
for (int i = 0; i <numbers.length; i++) {
Random ran = new Random(1234);
int nex = 0;
for (int n = 0; n <numbers[i]; n++) {
nex = ran.nextInt();
}
System.out.println("Next int value: " + nex);
}
是否有更快的方法来获取百万分之一的nextInt?如果是,请如何?
答案 0 :(得分:0)
您正在设置随机数生成器的“种子”值。这意味着每次运行此代码时,它将产生相同的随机数序列,因此该序列是可预测的。
如果您确实是在生成随机数,那么生成百万分之一的随机数将与生成第一个随机数相同,因为没人能分辨出这两个不可预测的结果之间的差异。
因此,第一个潜在的优化方法是:不要使用可预测的序列,而采用第一个随机数。这将需要一个很小的恒定时间。
接下来,如果您需要这种可重复性,则可以对其进行预先计算,并且您的代码将包含该结果表。然后,您可以在恒定时间内查看结果。
如果您需要看起来像随机的可重复序列,但不一定非要使用此特定序列,则可以使用其他伪随机数生成器。例如,您可以使用分组密码对“索引”(在您的示例中为100万)进行加密,然后从结果中使用一些字节。这也是恒定时间算法,与索引无关。
这是最后一个想法的实现:
public class PredictableSequenceGenerator {
private final int[] numbers;
public PredictableSequenceGenerator(int[] numbers) {
this.numbers = Objects.requireNonNull(numbers);
}
public int[] generate(long seed) {
ByteBuffer src = ByteBuffer.wrap(new byte[16]);
ByteBuffer dst = ByteBuffer.wrap(new byte[16]);
src.putLong(seed).putLong(seed);
SecretKey key = new SecretKeySpec(src.array(), "AES");
Cipher cipher;
try {
cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
} catch (GeneralSecurityException ex) {
throw new IllegalStateException("Failed to initialize generator.", ex);
}
int[] results = new int[numbers.length];
for (int idx = 0; idx < numbers.length; ++idx) {
src.clear();
src.putInt(0, idx);
dst.clear();
try {
cipher.doFinal(src, dst);
} catch (GeneralSecurityException ex) {
throw new IllegalStateException("Failed to transform index.", ex);
}
results[idx] = dst.flip().getInt();
}
return results;
}
public static void main(String... argv) {
int[] numbers = { 1000000, 1004300, 2204000, 1306000, /* 40k+ */ };
PredictableSequenceGenerator gen = new PredictableSequenceGenerator(numbers);
int[] random = gen.generate(1234);
for (int r : random)
System.out.println(r);
}
}
答案 1 :(得分:0)
您是否真的需要种子,以便每次的随机序列都相同?然后,您可以对数字数组进行升序排序。然后,对于第二个元素,您无需重置随机生成器,而只需继续您离开的位置即可。这样一来,您只需调用nextInt
的次数就可以与数组中最高的次数相同,而不是400亿次