Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 经过多少次迭代后,SecureRandom将生成给定范围内的所有数字?_Java_Random - Fatal编程技术网

Java 经过多少次迭代后,SecureRandom将生成给定范围内的所有数字?

Java 经过多少次迭代后,SecureRandom将生成给定范围内的所有数字?,java,random,Java,Random,SecureRandom需要多少次迭代才能生成给定范围内的所有数字。 例如,我正在生成0-9之间的随机数(包括两个)。然后经过多少次迭代,所有数字(0,1,2,…,9)至少出现一次 假设SecureRandom是完全随机的(它的安全部分所渴望的)答案是,没有一个给定的数字可以保证所有数字至少出现一次。正确的答案正如CrazyCasta所说——没有给定的数字 引用斯科特·亚当斯的话:这就是随机性的问题,你永远无法确定:) 如前所述,无法保证生成这十个值需要多长时间。然而,概率定律确实使它更可能需要

SecureRandom需要多少次迭代才能生成给定范围内的所有数字。
例如,我正在生成0-9之间的随机数(包括两个)。然后经过多少次迭代,所有数字(0,1,2,…,9)至少出现一次

假设SecureRandom是完全随机的(它的安全部分所渴望的)答案是,没有一个给定的数字可以保证所有数字至少出现一次。

正确的答案正如CrazyCasta所说——没有给定的数字

引用斯科特·亚当斯的话:这就是随机性的问题,你永远无法确定:)


如前所述,无法保证生成这十个值需要多长时间。然而,概率定律确实使它更可能需要10次迭代而不是1000000次

我不够聪明,不能算出实际的概率。但是,可以编写一个程序,通过反复运行问题来对空间进行采样,计算每次迭代的次数,然后您可以确定,例如,它将花费不到n次迭代50%的时间

只是为了好玩,我写了一些东西,通过运行问题1000000次并汇总结果来尝试这个方法。运行3次后,我的结果显示:

  • 50%的时间,它将花费少于27次(含27次)的迭代(全部3次运行)
  • 90%的时间,它将花费少于44次(包括)迭代(全部3次运行)
  • 99%的时间,它将花费不到66次(含66次)迭代(全部3次运行)
  • 99.9%的时间,它将花费少于88次(含88次)的迭代(全部3次运行)
  • 每种情况下的最差运行都有所不同,但3个值分别为154次迭代、156次迭代和170次迭代
这是我的检查代码。它使用java.security.SecureRandom,但也包括一种使用java.util.Random的方法

import java.security.SecureRandom;

import java.util.Map;
import java.util.Random;
import java.util.TreeMap;

public class HowLong {

    public static final int MAX_TO_GENERATE = 10;

    public static final int TOTAL_RUNS = 1000000;
    public static final int TP50 = (int)(TOTAL_RUNS * 0.50);
    public static final int TP90 = (int)(TOTAL_RUNS * 0.90);
    public static final int TP99 = (int)(TOTAL_RUNS * 0.99);
    public static final int TP99_9 = (int)(TOTAL_RUNS * 0.999);
    public static final int TP100 = (int)(TOTAL_RUNS * 1);

    public static final String[] TP_NAMES = {"TP50", "TP90", "TP99", "TP99.9", "TP100"};
    public static final int[] TPS = { TP50, TP90, TP99, TP99_9, TP100 };

    public interface RandomSource {
        int next();
    }

    public static class MathRandomSource implements RandomSource {
        private final Random rand;

        public MathRandomSource() {
            rand = new Random();
        }

        public int next() {
            return rand.nextInt(MAX_TO_GENERATE);
        }
    }

    public static class SecureRandomSource implements RandomSource {
        private final SecureRandom rand;

        public SecureRandomSource() {
            rand = new SecureRandom();
        }

        public int next() {
            return rand.nextInt(MAX_TO_GENERATE);
        }
    }

    public static int waitForTen() {

        final boolean[] found = new boolean[MAX_TO_GENERATE];
        int remaining = found.length;

        final RandomSource source = new SecureRandomSource();
        int iterations = 0;
        while (remaining > 0) {
            int next = source.next();
            if (!found[next]) {
                found[next] = true;
                remaining -= 1;
            }
            iterations += 1;
        }

        return iterations;
    }

    public static void main(String[] args) {
        System.out.println("Attempting to generate all numbers below: " + MAX_TO_GENERATE);
        System.out.println("Performing n iterations: " + TOTAL_RUNS);

        TreeMap<Integer, Integer> results = new TreeMap<Integer, Integer>();
        for (int i = 0; i < TOTAL_RUNS; i += 1) {
            Integer iterations = waitForTen();
            Integer currentCount = results.get(iterations);
            if (currentCount == null) {
                results.put(iterations, 1);
            } else {
                results.put(iterations, currentCount + 1);
            }
        }
        int currTP = 0;
        int count = 0;
        for (Map.Entry<Integer, Integer> entry: results.entrySet()) {
            count += entry.getValue();
            while (currTP < TPS.length && count >= TPS[currTP]) {
                System.out.println(TP_NAMES[currTP] + ": " + entry.getKey());
                currTP += 1;
            }
        }
    }

}
导入java.security.SecureRandom;
导入java.util.Map;
导入java.util.Random;
导入java.util.TreeMap;
公务舱{
公共静态最终int MAX_TO_GENERATE=10;
公共静态最终整数运行总数=1000000;
公共静态最终int TP50=(int)(总运行次数*0.50);
公共静态最终int TP90=(int)(总运行次数*0.90);
公共静态最终int TP99=(int)(总运行次数*0.99);
公共静态最终int TP99_9=(int)(总运行次数*0.999);
公共静态最终int TP100=(int)(总运行次数*1);
公共静态最终字符串[]TP_name={“TP50”、“TP90”、“TP99”、“TP99.9”、“TP100”};
公共静态final int[]TPS={TP50,TP90,TP99,TP99_9,TP100};
公共接口随机源{
int next();
}
公共静态类MathRandomSource实现了RandomSource{
私有最终随机兰德;
公共数据源(){
rand=新随机数();
}
公共int next(){
返回rand.nextInt(要生成的最大值);
}
}
公共静态类SecureRandomSource实现了RandomSource{
私人终审法院;
公共安全源(){
rand=新的SecureRandom();
}
公共int next(){
返回rand.nextInt(要生成的最大值);
}
}
公共静态int-waitForTen(){
final boolean[]found=新布尔值[MAX_TO_GENERATE];
剩余整数=找到的长度;
最终随机源=新的SecureRandomSource();
int迭代次数=0;
而(剩余>0){
int next=source.next();
如果(!找到[下一步]){
发现[下一个]=真;
剩余-=1;
}
迭代次数+=1;
}
返回迭代;
}
公共静态void main(字符串[]args){
System.out.println(“试图生成以下所有数字:“+MAX\u to\u generate”);
System.out.println(“执行n次迭代:+总运行次数”);
TreeMap results=新的TreeMap();
对于(int i=0;i<总运行次数;i+=1){
整数迭代次数=waitForTen();
整数currentCount=results.get(迭代次数);
如果(currentCount==null){
结果:put(迭代次数,1);
}否则{
结果.put(迭代次数,currentCount+1);
}
}
int currTP=0;
整数计数=0;
for(Map.Entry:results.entrySet()){
count+=entry.getValue();
而(currTP=TPS[currTP]){
System.out.println(TP_名称[currTP]+“:“+entry.getKey());
currTP+=1;
}
}
}
}

应该是随机的。因此可能是10或1000000(尽管后者不太可能)@jbnize前者也不太可能你问这个问题是因为一个特殊的原因吗?例如,您的目标是实际按随机顺序排列数字0-9吗?请展示您的代码,以便我们了解您是如何生成数字的。我对java.security.SecureRandom特别感兴趣,它是一个伪随机数生成器。@CodeDance不,它不是一个伪随机数生成器。来自
SecureRandom
的文档:“此外,SecureRandom必须产生非确定性输出。”。因此,至少有一些保证的随机性,因此它不是伪随机。
SecureRandom
有时是伪随机的:当它使用
SHA1PRNG
算法时。默认情况下,它使用非确定性源设置种子,但您也可以指定种子。相关的: