Question

Heap's algorithm is a systematic way to cycle through all permutations of N elements "one exchange at a time". For odd N, it's especially neat because the final permutation seems to be only one exchange different from the first permutation.

But, for even N, this wrap-around does not occur. For example, for N=4, the order of permutations is:

1234
2134
3124
1324
2314
3214
4213
2413
1423
4123
2143
1243
1342
3142
4132
1432
3412
4312
4321
3421
2431
4231
3241
2341

So, does anyone have an exchange algorithm which wraps around for even N? If not, how about just for N=4?

Was it helpful?

Solution

By inspection, one possible sequence that satisfies the constraint would be:

1234
1432
3412
4312
1342
3142
4132
4231
2431
3421
4321
2341
3241
1243
2143
4123
1423
2413
4213
3214
2314
1324
3124
2134
1234

At each step there should be just two elements that are exchanged.

For larger N I would recommend you try to implement the Steinhaus–Johnson–Trotter algorithm which I believe will generate these permutations using just swaps of adjacent elements, and will leave you one swap away from the initial position.

Python code based on rosetta code:

N=4
def s_permutations(seq):
    def s_perm(seq):
        if not seq:
            return [[]]
        else:
            new_items = []
            for i, item in enumerate(s_perm(seq[:-1])):
                if i % 2:
                    new_items += [item[:i] + seq[-1:] + item[i:]
                                  for i in range(len(item) + 1)]
                else:
                    new_items += [item[:i] + seq[-1:] + item[i:]
                                  for i in range(len(item), -1, -1)]
            return new_items

    return [(tuple(item), -1 if i % 2 else 1)
            for i, item in enumerate(s_perm(seq))]

for x,sgn in s_permutations(range(1,N+1)):
    print ''.join(map(str,x))

OTHER TIPS

For a fixed, small number such as N=4, you could pre-calculate all of the permutations of the indexes of your array and run through the data using each permutation of indices to arrive at all permutations of the data, e.g. in pseudo-code

originalData[] = { 1111, 2222, 3333, 4444 }
indexPermuations[0] = { 0, 1, 2, 3 }
indexPermuations[1] = { 0, 1, 3, 2 }
// Etc for all 16 permutations of 4 indices

foreach (ip in indexPermutations) 
{
    for (i = 0 to 3)
    {
        dataPermuation[ip][i] = originalData[indexPermutation[ip][i]];
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top