Here you can find the source of permutedGroups(List> elementLists)
public static <E> List<List<List<E>>> permutedGroups(List<List<E>> elementLists)
//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; } }