Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.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置换_Java_Math_Random_Permutation_Knuth - Fatal编程技术网

随机数最少的Java置换

随机数最少的Java置换,java,math,random,permutation,knuth,Java,Math,Random,Permutation,Knuth,我想生成数组a的排列,不想使用等实用函数 排列应该是随机的,并且每一个排列都应该是可能发生的-但是不需要均匀分布的概率。 以下代码实现了这一点,但性能较差: // array holding 1,...,n // initialized somewhere else int[] a = new int[N]; for (int i = 0; i < a.length ; i++) { int r = (int) (Math.random() * (i+1));

我想生成
数组a的排列
,不想使用
等实用函数
排列应该是随机的,并且每一个排列都应该是可能发生的-但是不需要均匀分布的概率。 以下代码实现了这一点,但性能较差:

// array holding 1,...,n
// initialized somewhere else
int[] a = new int[N];

for (int i = 0; i < a.length ; i++) {
     int r = (int) (Math.random() * (i+1));     
     swap(r,i,a);
  }

private static void swap(int j, int k, int[] array){
      int temp = array[k];
      array[k] = array[j];
      array[j] = temp;
}
//数组包含1,…,n
//在其他地方初始化
int[]a=新的int[N];
for(int i=0;i

问题:
是否有可能减少用于生成置换的随机数总数

如果有人在这方面有所改进,我会感到惊讶。是O(n)

它需要O(n)个随机数,这对我来说是不够的

声明了一个O(nlogn)算法

我们都希望看到O(logn)或O(1)

O(logn)算法通常依赖于“分而治之”的二等分,这会让人想到切割甲板并将每一半分割


但是我忍不住想,如果能找到一个更快的算法,Knuth就会找到它。

如果有人改进了这个算法,我会感到惊讶。是O(n)

它需要O(n)个随机数,这对我来说是不够的

声明了一个O(nlogn)算法

我们都希望看到O(logn)或O(1)

O(logn)算法通常依赖于“分而治之”的二等分,这会让人想到切割甲板并将每一半分割


但是我忍不住想,如果能找到一个更快的算法,Knuth就会找到它。

我能想到的唯一可能的优化就是使随机数生成器更快。一个简单的解决方案是首先生成随机整数:

import java.util.Random;
Random rand = new Random();

for (int i = 0; i < a.length ; i++) {
    swap(rand.nextInt(i+1), i, a);
}

...
import java.util.Random;
Random rand=新的Random();
for(int i=0;i

或者,您可以发明一种更快的方法来生成更多或更少的随机数(均匀分布或不均匀分布,适合您的需要)。但是,您无法克服O(n)限制。

我能想到的唯一可能的优化是使随机数生成器更快。一个简单的解决方案是首先生成随机整数:

import java.util.Random;
Random rand = new Random();

for (int i = 0; i < a.length ; i++) {
    swap(rand.nextInt(i+1), i, a);
}

...
import java.util.Random;
Random rand=新的Random();
for(int i=0;i

或者,您可以发明一种更快的方法来生成更多或更少的随机数(均匀分布或不均匀分布,适合您的需要)。但是,没有办法克服O(n)限制。

长度n的序列有n!排列。如果每个置换都是可能的,那么每个置换都必须有一个可能的随机数序列

为了随机排列长度为n的数组,您可以从1..n范围内生成一个随机数!均匀地随机地。这标识了一个排列,然后可以应用它

您可以改进您的问题,询问需要多少随机位。根据相同的参数,这将是log(n!)。为了让您了解该函数的渐近行为,请考虑:

设n>3:

n=log(2^n)
因此n个随机位是不够的(对于n>3)。事实上,我们可以证明log(n!)不在O(n)中。

长度n的序列有n!排列。如果每个置换都是可能的,那么每个置换都必须有一个可能的随机数序列

为了随机排列长度为n的数组,您可以从1..n范围内生成一个随机数!均匀地随机地。这标识了一个排列,然后可以应用它

您可以改进您的问题,询问需要多少随机位。根据相同的参数,这将是log(n!)。为了让您了解该函数的渐近行为,请考虑:

设n>3:

n=log(2^n)
因此n个随机位是不够的(对于n>3)。事实上,我们可以证明log(n!)不在O(n)中。

感谢您提供的有趣链接。。。这也解释了为什么我无法找到更快的解决方案-谢谢你那有趣的链接。。。这也解释了为什么我无法找到更快的解决方案-我看到你把我纠正的拼写错误和粗体字的过度使用都卷走了。有什么原因吗?有什么原因需要避免shuffle()吗?我看到你把我纠正的拼写错误和粗体字的过度使用都退回了。有什么原因吗?有什么原因需要避免shuffle()?但是如果你阅读Knuth引文,你会发现它确实是O(n)。没有。该算法表示,您可以从[0,1]范围内找到具有O(n)个随机实数的随机排列,其中数字的表示精度足以在n个不同的数组索引中进行选择。这不能用固定位的随机数来实现。很容易看出,至少第一个随机数需要logn位,导致O(n logn)的位复杂性。但如果你阅读Knuth引文,你会发现它确实是O(n)。不。该算法表示,您可以从[0,1]范围内找到具有O(n)个随机实数的随机排列,其中数字的表示精度足以在n个不同的数组索引中进行选择。这不能用固定位的随机数来实现。很容易看出,至少第一个随机数需要logn位,导致位复杂度为O(n logn)。