简体   繁体   中英

java generate powerset permutations from grouped elements

I have a set of N groups, each group contains a variable number of elements. I want a function which will return all possible permutations (of length 1 to N) of all elements, where only one element per group can appear in any permutation.

For example, consider the 2 groups {A, B} , and {C, D, E}
Then I want to return the following Lists:

{A}, {B}, {C}, {D}, {E},
{AC}, {AD}, {AE}, {BC}, {BD}, {BE}, {CA}, {CB}, {DA}, {DB}, {EA}, {EB}

I tried writing a recursive function, but I can't seem to make it work... Here's what I have so far. Any help in getting it to work would be much appreciated.

public class Test {
    public static void main(String[] args) {

        List<String> g1 = new ArrayList<String>();
        g1.add("a");
        g1.add("b");
        List<String> g2 = new ArrayList<String>();
        g2.add("c");
        g2.add("d");
        g2.add("e");
        List<List<String>> groups = new ArrayList<List<String>>();
        groups.add(g1);
        groups.add(g2);
        int size = 2;

        List<List<String>> perms = generatePermutations(groups, size);
        System.out.println(perms.size());

    }

    private static List<List<String>> generatePermutations(List<List<String>> groups, int size) {
        List<List<String>> permutations = new ArrayList<List<String>>();
        if ( groups.size() == 0 ) {
            return permutations;
        }
        int n = groups.size();
        for ( int i=0; i<n; i++ ) {
            List<List<String>> otherGroups = new ArrayList<List<String>>(groups);
            otherGroups.remove(i);
            for ( int j=0; j<groups.get(i).size(); j++ ) {
                String aKey = groups.get(i).get(j);
                for ( List<String> subPerm : generatePermutations(otherGroups, size - 1) ) {
                    List<String> newList = new ArrayList<String>();
                    newList.add(aKey);
                    newList.addAll(subPerm);
                    permutations.add(newList);
                }
            }
        }
        return permutations;
    }
}

When I have to solve problems like these, I always try do divide them in smaller tasks, each one resulting in a distinct method call instead of using many inner loops since the beginning.

I would do something like this

public class Main {

    public static void main(String[] args) {
        char[] x={'A','B'},y={'C','D','E'},z={'F','G','H','I'};
        char[][]group={x,y,z};
        perm(group);
    }

    static void perm(char[][]g){
        // Reorganize "g" changing the order of the components (x, y and z in this case)
        // in all possible ways and call perm2().
        // Here you perform the "upper level" permutation between sets.
        // In this case it will result in 6 calls
            perm2(g);
    }

    static void perm2(char[][]g){
        // perform a "lower level" permutation on the given order of x, y, z
    }

}

that is easier to test and verify. Eventually, when you find the solution, you can think of "compressing" the solution in one method with multiple inner loops.

Hope it helps!

Maybe I'm misunderstanding the problem... but I think the problem is a bit convoluted. I'd like to help but I need to understand the problem a bit better. If I understood it properly you need to:

Find the powerset ot the 'set of sets' given as input:

{A,B} {C,D,E} --> {} {A,B} {C,D,E} {{A,B},{C,D,E}}

Then, compute the cartesian product of each member of the powerset:

{} {A,B} {C,D,E} {{A,B},{C,D,E}} --> {} {A,B} {C,D,E} {AC,AD,AE,BC,BD,BE}

And then compute permutations over the contents of the sets obtained:

{} {A,B} {C,D,E} {AC,AD,AE,BC,BD,BE} --> {} {A,B} {C,D,E} {AC,AD,AE,BC,BD,BE,CA,DA,EA,CB,DB,EB}

Finally, all sets would be 'flattened' in a single set:

{A,B,C,D,EAC,AD,AE,BC,BD,BE,CA,DA,EA,CB,DB,EB}

Is that so? There are ways to compute powerset, cartesian product and permutation recursively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM