如何快速生成随机排列

时间:2014-09-11 04:27:29

标签: algorithm permutation

我在算法书中读到了一个问题:

"Given a positive integer n, choose 100 random permutations of [1,2,...,n],..."

我知道如何使用Knuth算法生成随机排列。但是否存在任何快速算法来产生大量的排列?

2 个答案:

答案 0 :(得分:3)

Knuth shuffles要求你进行n个随机交换以获得n个元素的排列(参见http://en.wikipedia.org/wiki/Random_permutation#Knuth_shuffles),因此复杂度为O(n),如果你收到n个元素的排列,那么这是最好的预期。

这是否会导致您遇到实际问题?如果是这样,也许你可以看看你在实践中对所有这些排列做了什么。除了简单地减少之外,您可以考虑推迟生成排列,直到您确定需要它为止。如果你需要在n个对象上进行排列,但只需要查看那些n个对象的k,也许你需要一个只生成那些k个元素的方案。对于小k,你可以随机生成[0,n]范围内的k个随机数,重复几代返回已经出现的数字。对于小k,这是不可能的。

答案 1 :(得分:3)

从1到N存在N!个数字排列。如果按字典顺序对它们进行排序,就像在字典中一样,可以构造排列,知道它在排序排列列表中排序。

例如,设N = 3,按字典顺序排列的排列列表为{123,132,213,231,312,321}。你生成1到3之间的数字!例如5.第5个permutaion是312.如何构造它?

让我们找到第5个排列的第1个数字。让我们将排列分成块,标准是第一个数字,我的意思是这样的组 - {123,132},{213,231},{312,321}。每个组包含(n-1)!个元素。 第一个排列数是块数。第5个排列在ceil(5/(3-1)!) = 3块中。所以,我们刚刚找到了第5个排列的第一个数字,它就是3个。

现在我正在寻找不是第5个但是 (5-(n-1)!*(ceil(5/2)-1)) = 5-2 * 2 =第1个排列 {3,1,2},{3,2,1}。对于所有组成员确定3并且相同,所以我实际上在{1,2},{2,1}中搜索第1个排列,并且N现在是2.再次,next_num = ceil(1/(new_N-1)!) = 1.

继续N次。

希望你明白了。复杂性是O(N) - 因为你用算术技巧逐个构造排列元素。

<强>更新

当您通过算术操作获得下一个数字时,您还应保留used数组,而不是XX-th unused复杂性变为NlogN因为获取X-th需要logN未使用的元素