随机数最少的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)。