001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019
020package org.dllearner.algorithms.decisiontrees.utils;
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.Collections;
024import java.util.List;
025
026/**
027 * Methoden zur Erzeugung von Kombinationen.
028 */
029
030public class Combination {
031
032    /* ______________________________________________________________________________________________________________ *\
033    \* Konstanten                                                                                                     */
034
035    /* ______________________________________________________________________________________________________________ *\
036    \* Klassenvariablen                                                                                               */
037
038    /* ______________________________________________________________________________________________________________ *\
039    \* Instanzvariablen                                                                                               */
040
041    /* ______________________________________________________________________________________________________________ *\
042    \* Konstruktoren                                                                                                  */
043
044    /**
045     * Erzeugt eine Instanz dieser Klasse.
046     *
047     * Da verhindert werden soll, dass Instanzen dieser Klasse ausserhalb dieser Klasse erzeugt werdem, ist dieser
048     * Konstruktor 'private' deklariert.
049     */
050
051    private Combination()
052    {
053        super();
054    }
055
056    /* ______________________________________________________________________________________________________________ *\
057    \* Instanzmethoden                                                                                                */
058
059    /* ______________________________________________________________________________________________________________ *\
060    \* Klassenmethoden                                                                                                */
061    
062    
063    /**
064     * Liefert eine Liste aller Kombinationen (ohne Duplikate) der Elemente der angegebenen Liste. 
065     * 
066     * Beispiel: Angenommen, die angegebene Liste ist "[a, b, c]", dann wre das Ergebnis eine Liste aus Listen wie
067     * folgend: "[[], [a], [a, b], [a, c],[b], [b, c], [c]]".
068     *
069     * @param <T>               Der Typ der ELemente
070     * @param elements          Die Elemente
071     * @return                  Alle Kombinationen der Elemente 
072     */
073    
074    @SuppressWarnings({ "rawtypes", "unchecked" })
075        public static <T extends Comparable<? super T>> List<List<T>> findCombinations(Collection elements)
076    {
077        List<List<T>> result = new ArrayList<>();
078        
079        for (int i = 0; i <= elements.size(); i++)
080            result.addAll(findCombinations(elements, i));
081
082        return result;
083    }
084    
085    
086    /**
087     * Liefert eine Liste aller Kombinationen (ohne Duplikate) der Elemente der angegebenen Liste, die eine bestimmte
088     * Anzahl umfasst. 
089     * 
090     * Beispiel 1: Angenommen, die angegebene Liste ist "[a, b, c, d]" und die Anzahl ist 2, dann wre das Ergebnis eine
091     * Liste aus Listen wie folgend: "[[a, b], [a, c], [a, d], [b, c], [b, d], [], [c, d]]".
092     * 
093     * Beispiel 2: Angenommen, die angegebene Liste ist "[a, b, c]" und die Anzahl ist 3, dann wre das Ergebnis eine
094     *
095     * @param <T>               Der Typ der ELemente
096     * @param elements          Die Elemente
097     * @param n                 Die Anzahl der Elemente
098     * @return                  Alle Kombinationen der Elemente 
099     */
100    
101    public static <T extends Comparable<? super T>> List<List<T>> findCombinations(Collection<T> elements, int n)
102    {
103        List<List<T>> result = new ArrayList<>();
104        
105        if (n == 0)
106        {
107            result.add(new ArrayList<>());
108            
109            return result;
110        }
111        
112        List<List<T>> combinations = findCombinations(elements, n - 1);
113        for (List<T> combination: combinations)
114        {
115            for (T element: elements)
116            {
117                if (combination.contains(element))
118                {
119                    continue;
120                }
121                
122                List<T> list = new ArrayList<>();
123
124                list.addAll(combination);
125                
126                if (list.contains(element))
127                    continue;
128                
129                list.add(element);
130                Collections.sort(list);
131                
132                if (result.contains(list))
133                    continue;
134                
135                result.add(list);
136            }
137        }
138        
139        return result;
140    }
141
142    /* ______________________________________________________________________________________________________________ *\
143    \* Klassen                                                                                                        */
144
145}
146
147/*\
148 * _____________________________________________________________________________________________________________________
149 * 
150 * This software is distributed under the terms of the BSD License:
151 * 
152 * Copyright  2006 Klaus Rogall, Hamburg, Germany (klaus.rogall@web.de). All rights reserved.
153 * 
154 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
155 * following conditions are met:
156 * 
157 * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
158 *   disclaimer.
159 * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
160 *   disclaimer in the documentation and/or other materials provided with the distribution.
161 * - Neither the name of the Klaus Rogall nor the names of its contributors may be used to endorse or promote products
162 *   derived from this software without specific prior written permission.
163 *   
164 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
165 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
166 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
167 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
168 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
169 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
170 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
171 * _____________________________________________________________________________________________________________________
172\*/