11

I'm having a problem about derangements that I'm trying to solve. Given a set $S = \{1,\ldots,n\}$, I want to generate a random derangement.

I've considered generating a permutation and checking whether or not this is a derangement, but since the ratio of derangements to permutations is quite low, this will prove to be ineffective for large $n$. For reference, the limit of the ratio is (wiki): $$\lim_{n\to\infty} {!n \over n!} = {1 \over e} \approx 0.3679\dots$$

Are there any ways to generate a derangement that guaranteed (or have a high probability) to actually result in a derangement?

It might perhaps help that my starting set is always of the same format: $S = \{1,2,3,\ldots,n\}$, although the value of $n$ might differ.

Any ideas?

ViHdzP
  • 4,977
  • 2
  • 21
  • 53
Mythio
  • 1,007
  • 4
    Do you want the distribution to be uniform? – joriki Feb 13 '13 at 11:02
  • 10
    The limit you quote seems to indicate that you'd expect to find a derangement after trying less than three random permutations on average, even for large $n$. That doesn't sound particularly inefficient to me. – hmakholm left over Monica Feb 13 '13 at 11:36
  • @joriki: Yes, uniform would be important. I've googled it and found some algorithms that work by generating permutations and checking whether it is a derangement. This is a pretty obvious approach, but like Henning hinted at I wondered if its possible to do this with probability 1 instead of 0.34, or at least with probability $> 0.5$ – Mythio Feb 13 '13 at 12:15
  • @Mythio: I don't understand. Where do the algorithms I linked to generate permutations that aren't derangements? – joriki Feb 13 '13 at 12:39
  • The point is that the actual algorithm used generates a permutation and the "shell" algorithm around it checks whether it is a derangement. This is requires on average 3 runs.

    What I'm looking for is an algorithm that generates a derangement in a single run. In other words, you're not generating permutations in between.

    – Mythio Feb 13 '13 at 13:04
  • 1
    @Mythio: I don't see how that's consistent with their cost analysis. They find that they expect to make $2n+O(\log^2n)$ calls to the random number generator, whereas as you point out yourself the rejection method should be expected to make $\mathrm e\cdot n$ calls. $2n$ isn't $\gt0.5$, but at least it's $=0.5$. Am I missing something? – joriki Feb 13 '13 at 17:55
  • http://www.dsi.unifi.it/~merlini/papers/Derangements.pdf – Sriram S Feb 14 '13 at 03:40
  • @joriki, I guess thats the best possible at the moment then. Thanks for your help! If you can post it as an answer I can identify it as such if you want. – Mythio Feb 14 '13 at 09:31
  • @Mythio: I wasn't trying to say you can't do any better; I was just pointing out that algorithm, trying to understand why you hadn't mentioned it and whether it solves your problem. My suggestion would be to note that algorithm in the question, including the fact that it claims a factor $2$, and ask if we can do better -- that's still an interesting question. – joriki Feb 14 '13 at 10:34
  • a related article discussing derangement as a permutatiion which consists of non-trivial cycle factors, so by listing or generating non-trivial cycles, you can generate a derangement as well (having a way to generate partitions of $n$ can come in handy) – Nikos M. May 30 '15 at 17:19

1 Answers1

9

The algorithm that joriki linked to is described in more detail in Martínez, Conrado, Alois Panholzer, and Helmut Prodinger. "Generating Random Derangements." ANALCO. 2008. http://epubs.siam.org/doi/pdf/10.1137/1.9781611972986.7

It's NOT a rejection-based algorithm (I'm not sure why Mythio thinks it is). The permutation is generated one element at a time, from high index to low index, and the result is a derangement 100% of the time.

There is something like a rejection component in the internal loop, when choosing the next element. The remaining candidates are classified as "marked" and "unmarked" and the algorithm must choose one of the unmarked ones. The authors implemented this as a trial-and-error process, but it could instead be implemented as a set, which would reduce each element selection to a single RNG call.

After an element is selected there is another RNG call to decide marked/unmarked.

  • 2
    From what I understand from it, the algorithm generates a permutation, determines whether it is a derangement, if yes -> good, if no -> next. Whether this is done by marking or deleting from the set or anything else doesn't really matter. The underlying technique is rejection based because you generate permutations and not derangements. But maybe I understand it wrong :-) – Mythio Jul 28 '14 at 12:05
  • 3
    @Mythio has misunderstood; the algorithm directly generates a random derangement without any rejection or backtracking. The "marking" is about preventing an element from being swapped, thereby closing the current cycle. That is done with a specific probability so as to ensure a uniform generation of derangements. There is a C version of the algorithm in this book which is perhaps easier to understand: https://maths-people.anu.edu.au/~brent/pd/Arndt-thesis.pdf – cristoper Dec 09 '20 at 04:22