简体   繁体   English

java从分组元素生成powerset排列

[英]java generate powerset permutations from grouped elements

I have a set of N groups, each group contains a variable number of elements. 我有一组N组,每组包含可变数量的元素。 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. 我想要一个函数,它将返回所有元素的所有可能的排列(长度为1到N),其中每个组中只有一个元素可以出现在任何排列中。

For example, consider the 2 groups {A, B} , and {C, D, E} 例如,考虑2组{A, B}{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: 找到作为输入给出的'集合'的powerset:

{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: 然后,计算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. 有一些方法可以递归地计算powerset,笛卡尔积和置换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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