It seems that the best way to approach this is to build an iterator that could create a permutation list, rather than using a function like permn that generates the entire list up (expensive operation).
A great place to look for guidance on creating such objects is the itertools module in the Python standard library. Itertools was partially reimplemented for R as a package with the same name .
The following is an example of using R itertools to implement a Python generator port that creates iterators for permutations:
require(itertools) permutations <- function(iterable) {
It is incorrect to use Knuth : "Beware of errors in the above code, I just tried, I did not prove that it is correct."
For the first 3 permutations of the 1:10 sequence, permn pays a heavy price for computing unnecessary permutations:
> system.time( first_three <- permn(1:10)[1:3] ) user system elapsed 134.809 0.439 135.251 > first_three [[1]] [1] 1 2 3 4 5 6 7 8 9 10 [[2]] [1] 1 2 3 4 5 6 7 8 10 9 [[3]] [1] 1 2 3 4 5 6 7 10 8 9)
However, the iterator returned by permutations can only be requested for the first three elements, which eliminate a lot of computation:
> system.time( first_three <- as.list(ilimit(permutations(1:10), 3)) ) user system elapsed 0.002 0.000 0.002 > first_three [[1]] [1] 1 2 3 4 5 6 7 8 9 10 [[2]] [1] 1 2 3 4 5 6 7 8 10 9 [[3]] [1] 1 2 3 4 5 6 7 9 8 10
The Python algorithm generates permutations in a different order than permn .
Computing all permutations is still possible:
> system.time( all_perms <- as.list(permutations(1:10)) ) user system elapsed 498.601 0.672 499.284
Although much more expensive since the Python algorithm uses loops heavily compared to permn . Python actually implements this algorithm in C, which compensates for the inefficiency of interpreted loops.
The code is available in GitHub style . If anyone has a better idea, fork off!