Java List Permutate permutedGroups(List> elementLists)

Here you can find the source of permutedGroups(List> elementLists)

Description

Generate all permuted groups from each list of elements.

License

Open Source License

Return

a list of groups (lists of lists).

Declaration

public static <E> List<List<List<E>>> permutedGroups(List<List<E>> elementLists) 

Method Source Code


//package com.java2s;
/*/* ww  w .  j ava 2 s.c  om*/
Copyright 2009 Semantic Discovery, Inc. (www.semanticdiscovery.com)
    
This file is part of the Semantic Discovery Toolkit.
    
The Semantic Discovery Toolkit is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
The Semantic Discovery Toolkit is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.
    
You should have received a copy of the GNU Lesser General Public License
along with The Semantic Discovery Toolkit.  If not, see <http://www.gnu.org/licenses/>.
*/

import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

import java.util.Iterator;

public class Main {
    /**
     * Generate all permuted groups from each list of elements.
     * <p>
     * Beware of the combinatorics here; it may be necessary to use group and
     * addin to incrementally build the groups.
     * <p>
     * For example for a=(a b), b=(1 2), c=(x y), permutedGroups({a, b, c})
     * yields:
     * (((a 1 x) (b 2 y)) ((a 2 x) (b 1 y)) ((a 1 y) (b 2 x)) ((a 2 y) (b 1 x)))
     * <p>
     * The sizes of all element lists must be equal, or a NullPointerException
     * will be thrown.
     * <p>
     * @return a list of groups (lists of lists).
     */
    public static <E> List<List<List<E>>> permutedGroups(List<List<E>> elementLists) {
        List<List<List<E>>> result = new ArrayList<List<List<E>>>();

        if (elementLists == null || elementLists.size() == 0) {
            return result;
        }

        int size = elementLists.size();
        if (size == 1) {
            List<E> elements = elementLists.get(0);
            List<List<E>> groups = new ArrayList<List<E>>();
            for (E elt : elements) {
                List<E> group = new ArrayList<E>();
                group.add(elt);
                groups.add(group);
            }
            result.add(groups);
        } else {
            List<E> first = elementLists.get(0);
            List<E> second = elementLists.get(1);
            result = group(first, second);

            for (int i = 2; i < size; ++i) {
                List<E> next = elementLists.get(i);
                result = addin(result, next);
            }
        }

        return result;
    }

    /**
     * Group each element from list1 with an element from list2, using every
     * element exactly once. Proper function is guaranteed only when the sizes
     * of both lists are equal.
     * <p>
     * For example (a b) grouped with (1 2) yields:
     * (((a 1) (b 2)) ((a 2) (b 1)))
     * <p>
     * @return a list of groups (lists of lists) or null if the sizes of the
     *         lists are not equal.
     */
    public static <E> List<List<List<E>>> group(List<E> list1, List<E> list2) {
        if (list1 == null || list2 == null && list1.size() == list2.size()) {
            return null;
        }

        List<List<List<E>>> result = new ArrayList<List<List<E>>>();
        List<List<E>> p2 = permute(list2);
        int size = list1.size();
        for (List<E> g2 : p2) {
            List<List<E>> nextList = new ArrayList<List<E>>();
            for (int i = 0; i < size; ++i) {
                E elt1 = list1.get(i);
                E elt2 = g2.get(i);
                List<E> list = new ArrayList<E>();
                list.add(elt1);
                list.add(elt2);
                nextList.add(list);
            }
            result.add(nextList);
        }
        return result;
    }

    /**
     * Add in another list of elements to the given groups.
     * <p>
     * addin(groups(a, b), c) would be the equivalent of groups(a, b, c).
     * <p>
     * This allows permuted groups to be constructed incrementally, which is
     * often necessary to apply incremental filters and keep the overall
     * combinatorics manageable
     * <p>
     * For example for a=(a b), b=(1 2), c=(x y), addin(groups(a, b), c)
     * yields:
     * (((a 1 x) (b 2 y)) ((a 2 x) (b 1 y)) ((a 1 y) (b 2 x)) ((a 2 y) (b 1 x)))
     * <p>
     * The size of list1 must be equal the sizes of the lists used to build
     * the group, or a NullPointerException will be thrown.
     * <p>
     * @return a list of groups (lists of lists).
     */
    public static <E> List<List<List<E>>> addin(List<List<List<E>>> groups, List<E> list1) {
        List<List<List<E>>> result = new ArrayList<List<List<E>>>();

        List<List<E>> list2 = permute(list1);
        for (List<E> p : list2) {
            result.addAll(addinAux(groups, p));
        }

        return result;
    }

    /**
     * Create a list of all permutations (lists) of the elements within
     * the given list.
     */
    public static <E> List<List<E>> permute(List<E> list1) {
        List<List<E>> result = new ArrayList<List<E>>();

        if (list1 != null) {
            int s1 = list1.size();

            if (s1 > 0) {
                int index = 0;
                for (Iterator<E> it = list1.iterator(); it.hasNext(); ++index) {
                    E elt = it.next();
                    List<E> list2 = new LinkedList<E>(list1.subList(0, index));
                    list2.addAll(list1.subList(index + 1, s1));
                    List<List<E>> p2 = permute(list2);

                    for (List<E> curList : p2) {
                        ((LinkedList<E>) curList).addFirst(elt);
                        result.add(curList);
                    }
                }
            } else {
                result.add(new LinkedList<E>());
            }
        }

        return result;
    }

    /**
     * Auxiliary to addin, deals with adding one new permutation to the groups.
     */
    private static <E> List<List<List<E>>> addinAux(List<List<List<E>>> groups, List<E> list1) {
        List<List<List<E>>> result = new ArrayList<List<List<E>>>();
        int size = list1.size();

        for (List<List<E>> group : groups) {
            if (group.size() != size) {
                return null;
            }

            List<List<E>> newGroup = new ArrayList<List<E>>();
            for (int i = 0; i < size; ++i) {
                List<E> grouppiece = group.get(i);
                E elt = list1.get(i);

                List<E> newGroupPiece = new ArrayList<E>(grouppiece);
                newGroupPiece.add(elt);
                newGroup.add(newGroupPiece);
            }
            result.add(newGroup);
        }

        return result;
    }
}

Related

  1. permute(List s1, List s2)
  2. permute(List arr)
  3. permute(List list1)
  4. permute(List list, int index, List> result)
  5. permute(T[] arr, List p)
  6. permuteList(List list, int[] permutations)
  7. permuteList(List in, int seed)
  8. permuteList(List list, Integer[] permutation)
  9. permVisit(int[] value, int n, int k, List res)