1

I read a question in an algorithm book:

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

I know how to generate random permutations with Knuth's algorithm. but does there exist any fast algorithms to generate large amount of permutations ?

Ankit Tyagi
  • 2,381
  • 10
  • 19
ssd
  • 83
  • 6
  • 1
    you can precompute all permutations, store them in an array and then generate a random number between ```[0,n!-1]``` ```x``` times (here x = 100). If precomputation is allowed. – Mateusz Dymczyk Sep 11 '14 at 04:31
  • 1
    That's a solution, but is there an algorithm for fast generation? – ssd Sep 11 '14 at 04:34
  • how fast do you want to go? a simple algorithm would go in ```n!*n``` by using an ```n-long``` bit vector to generate all of them. With Knuth you will go in ```O(k*n)``` with no precomputation, here you go down to ```O(k)``` and ```O(n!)``` space and some (a lot) of precomputation. – Mateusz Dymczyk Sep 11 '14 at 04:43
  • 1
    If you're sampling permutations to estimate what fraction of them have a certain property, then you can generate each successive permutation by generating two (not necessarily distinct) indexes and swapping them. The number of permutations required for a given level of accuracy will increase, but the overall time to generate them should decrease. – David Eisenstat Sep 11 '14 at 05:11
  • @ssd, you may not store all permutations. Generate random in [1,n!] and build permutation by it number. It's usual homework problem and you can invent it on your own or just google it) –  Sep 11 '14 at 05:27
  • @Baurzhan Do you mean every time I create a permutation beginning with a random number instead of pre-compute all of them? – ssd Sep 12 '14 at 04:08
  • @DavidEisenstat I am sampling permutations!Can you explain more or give me some links to read? – ssd Sep 12 '14 at 04:12
  • @MateuszDymczyk Your solution is good! I am just trying to find some algorithms. It's problem in an algorithm book so I think the author doesn't mean pre-computation here. – ssd Sep 12 '14 at 04:15
  • Whatever you do with `k` permutations of length `n` will probably require at least `O (k * n)` operations to visit each element of each permutation. Knuth's shuffle already gives you these permutations in `O (k * n)`, so that's likely to be what you need anyway. If it is not, please reformulate the question and specify why. – Gassa Sep 12 '14 at 09:22
  • @ssd See a book on randomized algorithms (Motwani--Raghavan or Mitzenmacher--Upfal should have coverage). That optimization isn't worth it unless you can test each permutation in sublinear time. – David Eisenstat Sep 12 '14 at 13:08

2 Answers2

4

Knuth shuffles require you to do n random swaps for a permutation of n elements (see http://en.wikipedia.org/wiki/Random_permutation#Knuth_shuffles) so the complexity is O(n) which is about the best you can expect if you receive a permutation on n elements.

Is this causing you a practical problem? If so, perhaps you could look at what you are doing with all those permutations in practice. Apart from simply getting by on less, you could think about deferring generating a permutation until you are sure you need it. If you need a permutation on n objects but only look at k of those n objects, perhaps you need a scheme for generating only those k elements. For small k, you could simply generate k random numbers in the range [0, n) at random, repeating generations which return numbers which have already come up. For small k, this would be unlikely.

mcdowella
  • 19,301
  • 2
  • 19
  • 25
3

There exist N! permutations of numbers from 1 to N. If you sort them lexicographically, like in a dictionary, it's possible to construct permutation knowing it order in a list of sorted permutations.

For example, let N=3, lexicographically sorted list of permutations is {123,132,213,231,312,321}. You generate number between 1 and 3!, for example 5. 5-th permutaion is 312. How to construct it?

Let's find the 1-st number of 5-th permutation. Let's divide permutations into blocks, criteria is 1-st number, I means such groups - {123,132},{213,231},{312,321}. Each group contains (n-1)! elements. The first number of permutation is the block number. 5-th permutation is in ceil(5/(3-1)!)=3 block. So, we've just found the first number of 5-th permutation it's 3.

Now I'm looking for not 5-th but (5-(n-1)!*(ceil(5/2)-1))=5-2*2=1-th permutation in {3,1,2},{3,2,1}. 3 is determined and the same for all group members, so I'm actually searching for 1-th permutation in {1,2},{2,1} and N now is 2. Again, next_num = ceil(1/(new_N-1)!) = 1.

Continue it N times.

Hope you got the idea. Complexity is O(N) - because you constructing permutation elements one by one with arithmetical tricks.

UPDATE

When you got next number by arithmetical opearions you should also keep used array and instead of X take X-th unused Complexity becomes NlogN because logN needed for getting X-th unused element