# Permutations[Range[12]] produces an error instead of a list

This input:

Permutations[Range[12]]


Results in this (error) output:

Permutations::outsize:
The result of evaluating Permutations[{1,2,3,4,5,6,7,8,9,10,11,12}]
would be a packed array with 5748019200 elements, but the number of elements
in a packed array must be a machine integer. >>


That number (5748019200) is interesting, because it's exactly 12 times 12! (that's factorial, not exclamation point)

Presumably, Mathematica is trying to store all 12! length 12 lists in a single monolithic array. I can imagine this failing.

Usually, Mathematica shields me from these types of problems. For example, I had no trouble calculating 12*12!.

My intention is to Select some elements from this list, so I don't need to have every permutation in memory at once.

Question: Is there a different way to generate the permutations that avoids this problem?

-
Run the same code on a 64-bit machine ;-) Seriously though, it is possible to iterate over permutations but I'm not sure if the algorithm is implemented directly in Mathematica. – David Zaslavsky Feb 4 '12 at 3:28
@David It doesn't work on a 64-bit machine either. Harold: Apparently the maximum size of a packed array is 2^31-1. This is a huge array: a 2^31 - 1-element packed array of machine integers (i.e. assuming the most efficient storage possible) would take up 8 GB of contiguous memory. You need to have a lot of memory in your computer to be able to store such an array (definitely much more than 8 GB because of the contiguous memory block requirement) – Szabolcs Feb 4 '12 at 20:13

Combinatorica has the function NextPermutation which allows you to iterate over the permutations. There may be ways of generating a smaller subset if you have more information about what you are looking for.

-
On that note: the algorithms in Combinatorica are based on old FORTRAN routines discussed in this book; OP might want to take a look at the book and see what other strategies might be appropriate for his circumstances. – J. M. Feb 4 '12 at 3:48
@J.M., that book looks to be a tremendous resource. I'm glad I asked this question now. – Harold Feb 4 '12 at 4:52
@Harold note, the functionality in Combinatorica  is being slowly folded into the kernel functions. So, loading it will give a warning message to that effect, but NextPermutation doesn't (yet?) seem to have been moved over. – rcollyer Feb 4 '12 at 4:55
@J.M. Thanks a lot for the link to that book. Looks excellent – TomD Feb 4 '12 at 9:34

Consider than the permutations of {1, 2, 3, 4, 5} are each of the permutations of {1, 2, 3, 4} with 5 inserted at each possible place. One can therefore examine the permutations of {1, 2, 3, 4, 5} in blocks like this:

p4 = Permutations@Range@4;

Table[
ReplaceList[x, {h___, t___} :> {h, 5, t}],
{x, p4}
]


For example, making a certain selection:

Table[
Select[
ReplaceList[x, {h___, t___} :> {h, 5, t}],
# + #2 - #3*#4/#5 > 7 & @@ # &
],
{x, p4}
]


The same can be applied to the permutations of Range@12.

-

Well from computational point of view, if you wanted the whole list or some part of it then the size of output would be the main problem.

Assuming plaintext output is used ... by my rough estimation it would take over 225 GB (gigabytes) to store the whole list on a disk. Furthermore it would take about 4 days to compute them all on this laptop.

You need data like:

filename = "f://out.txt";
seed = Range[12];
size = 10;


Recursive method call like:

seed = MPermutations[seed, size, filename]


Other useful lines:

FilePrint[filename]
DeleteFile[filename]


This is an example of what MPermutations could look like if flat file output is used. It computes next count number of permutations of list, prints them in filename and returns the last element.

MPermutations[list_, count_Integer, filename_String] := Module[
{n = 1, current = list},
OpenAppend[filename];
While[
n < count, current = NextPermutation[current];
n++;
Write[filename, current]];
Close[filename];
current]


Return result is needed to make recursive method call possible. Recomputing that line will add next size amount of results to file (assuming that data is in a different cell).

-