Johnson Trotter Algorithm

前端 未结 4 658
醉酒成梦
醉酒成梦 2020-12-06 23:53

Overview:

I am trying to implement the Johnson Trotter Algorithm in Java so that I can solve a problem on Project Euler. I have looked and looked bu

4条回答
  •  无人及你
    2020-12-07 00:00

    I looked at the suggested link with Even's speedup and think it is unnecessarily inefficient, using compares. My understanding is that Even's speedup means you don't need compares.

    Here's my code; this iterative form (unlike the recursive solution) allows you to call a getNext iterator to generate and return the next permutation.

    // Johnson-Trotter algorithm (http://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm)
    public class Permuter {
        private int[] perms;
        private int[] indexPerms;
        private int[] directions;
        private int[] iSwap;
        private int N; //permute 0..N-1
        private int movingPerm=N;
    
        static int FORWARD=+1;
        static int BACKWARD=-1;
    
    
        Permuter(int N) {
            this.N = N;
            perms =  new int[N];     // permutations
            indexPerms = new int[N];     // index to where each permutation value 0..N-1 is
            directions = new int[N];     // direction = forward(+1) or backward (-1)
            iSwap = new int[N]; //number of swaps we make for each integer at each level
            for (int i = 0; i < N; i++) {
                directions[i] = BACKWARD;
                perms[i]  = i;
                indexPerms[i] = i;
                iSwap[i] = i;
            }
            movingPerm = N;
        }
    
        int[] getNext() {
            //each call returns the next permutation
            do{
                if (movingPerm == N) {
                    movingPerm--;
                    return perms;
                } else if (iSwap[movingPerm] > 0) {
                    //swap
                    int swapPerm = perms[indexPerms[movingPerm] + directions[movingPerm]];
                    perms[indexPerms[movingPerm]] = swapPerm;
                    perms[indexPerms[movingPerm] + directions[movingPerm]] = movingPerm;
                    indexPerms[swapPerm] = indexPerms[movingPerm];
                    indexPerms[movingPerm] = indexPerms[movingPerm] + directions[movingPerm];
                    iSwap[movingPerm]--;
                    movingPerm=N;
                } else {
                    iSwap[movingPerm] = movingPerm;
                    directions[movingPerm] = -directions[movingPerm];
                    movingPerm--;
                }
            } while (movingPerm > 0);
            return null;
        }
    

提交回复
热议问题