All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.tweety.commons.util.SetTools Maven / Gradle / Ivy

There is a newer version: 1.17
Show newest version
/*
 *  This file is part of "Tweety", a collection of Java libraries for
 *  logical aspects of artificial intelligence and knowledge representation.
 *
 *  Tweety is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version 3 as
 *  published by the Free Software Foundation.
 *
 *  This program 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 this program. If not, see .
 *
 *  Copyright 2016 The Tweety Project Team 
 */
package net.sf.tweety.commons.util;

import java.util.*;

/**
 * This class provides some methods for set operations.
 * @author Matthias Thimm
 */
public class SetTools {

	/**
	 * This method computes all subsets of the given set of elements
	 * of class "E".
	 * @param elements a set of elements of class "E".
	 * @return all subsets of "elements".
	 */
	public Set> subsets(Collection elements){
		Set> subsets = new HashSet>();		
		if(elements.size() == 0){
			subsets.add(new HashSet());
		}else{
			E element = elements.iterator().next();
			Set remainingElements = new HashSet(elements);
			remainingElements.remove(element);
			Set> subsubsets = this.subsets(remainingElements);
			for(Set subsubset: subsubsets){
				subsets.add(new HashSet(subsubset));
				subsubset.add(element);
				subsets.add(new HashSet(subsubset));				
			}				
		}
		return subsets;
	}	
	
	/**
	 * This method computes all subsets of the given set of elements
	 * of class "E" with the given size.
	 * @param elements a set of elements of class "E".
	 * @param size some int.
	 * @return all subsets of "elements" of the given size.
	 */
	public Set> subsets(Collection elements, int size){
		if(size < 0)
			throw new IllegalArgumentException("Size must be at least zero.");
		Set> subsets = new HashSet>();		
		if(size == 0){
			subsets.add(new HashSet());
			return subsets;
		}		
		if(elements.size() < size)
			return subsets;		
		if(elements.size() == size){
			subsets.add(new HashSet(elements));
			return subsets;
		}			
		if(size == 1){
			for(E e: elements){
				Set set = new HashSet();
				set.add(e);
				subsets.add(set);
			}
			return subsets;				
		}
		E element = elements.iterator().next();
		Set remainingElements = new HashSet(elements);
		remainingElements.remove(element);
		Set> subsubsets = this.subsets(remainingElements,size-1);
		for(Set subsubset: subsubsets){
			subsubset.add(element);
			subsets.add(new HashSet(subsubset));				
		}
		subsubsets = this.subsets(remainingElements,size);
		for(Set subsubset: subsubsets)		
			subsets.add(new HashSet(subsubset));		
		return subsets;
	}	
	
	/**
	 * Computes all permutations of elements in partitions as follows.
	 * For any set A in the result and any set B in partitions it holds,
	 * that exactly one element of B is in A. For example
* permutations({{a,b},{c,d,e},{f}})
* equals to
* {{a,c,f},{b,c,f},{a,d,f},{b,d,f},{a,e,f},{b,e,f}} * @param partitions a set of sets of E. * @return a set of sets of E. */ public Set> permutations(Set> partitions){ if(partitions.size() == 0){ partitions.add(new HashSet()); return partitions; } Set> result = new HashSet>(); Set set = partitions.iterator().next(); Set> remaining = new HashSet>(partitions); remaining.remove(set); Set> subresult = this.permutations(remaining); for(Set subresultset: subresult){ for(E item: set){ Set newSet = new HashSet(); newSet.addAll(subresultset); newSet.add(item); result.add(newSet); } } return result; } /** * Computes the set of irreducible hitting sets of "sets". A hitting set * H is a set that has a non-empty intersection with every set in "sets". * H is irreducible if no proper subset of H is a hitting set. * @param sets a set of sets * @return the set of all irreducible hitting sets of "sets" */ public Set> irreducibleHittingSets(Set> sets){ // naive implementation, should be revised at some time Set> result; // if there is no set to hit, there are no hitting sets if(sets.size() == 0) return new HashSet>();; // if there is only one set to hit, every element of that set // forms a hitting set if(sets.size() == 1){ result = new HashSet>(); Set h; for(E e: sets.iterator().next()){ h = new HashSet(); h.add(e); result.add(h); } return result; } // if more than one set is to be hit, we recursively build up hitting sets Set current = sets.iterator().next(); Set> new_sets = new HashSet>(); new_sets.addAll(sets); new_sets.remove(current); // recursively solve the problem result = irreducibleHittingSets(new_sets); // now check whether the current set is already hit; if not add some element Set tmp; Set> new_result = new HashSet>(); for(Set h: result){ tmp = new HashSet(); tmp.addAll(current); tmp.retainAll(h); if(tmp.size() == 0){ for(E e: current){ tmp= new HashSet(); tmp.addAll(h); tmp.add(e); new_result.add(tmp); } }else new_result.add(h); } // check for irreducibility result.clear(); for(Set h: new_result){ result.add(h); for(Set h2: new_result){ if(h != h2) if(h.containsAll(h2)){ result.remove(h); break; } } } return result; } /** Checks whether the given set of sets has an empty intersection * @param sets some set of sets * @return true iff the all sets have an empty intersection. */ public boolean hasEmptyIntersection(Set> sets){ Set i = new HashSet(); i.addAll(sets.iterator().next()); for(Set s: sets) i.retainAll(s); return i.isEmpty(); } /** * Returns the union of the set of sets. * @param sets some set of sets * @return the union of the set. */ public Set getUnion(Set> sets){ Set result = new HashSet(); for(Set s: sets) result.addAll(s); return result; } /** * Computes every bipartition of the given set, e.g. for * a set {a,b,c,d,e,f} this method returns a set containing for example * {{a,b,c,d,e},{f}} and {{a,b,c,},{d,e,f}} and {{a,b,c,d,e,f},{}} * and {{a,d,e},{b,c,f}}. * @param set a set of E * @return the set of all bipartitions of the given set. */ public Set>> getBipartitions(Set set){ Set> subsets = this.subsets(set); Set>> bipartitions = new HashSet>>(); for(Set partition1: subsets){ Set partition2 = new HashSet(set); partition2.removeAll(partition1); Set> bipartition = new HashSet>(); bipartition.add(partition1); bipartition.add(partition2); bipartitions.add(bipartition); } return bipartitions; } /** * Returns the symmetric difference of the two sets s and t, i.e. * it returns (s \cup t) \setminus (s \cap t). * @param s some set * @param t some set * @return the symmetric difference of the two sets */ public Set symmetricDifference(Collection s, Collection t){ Set result = new HashSet(); Set isec = new HashSet(s); isec.retainAll(t); result.addAll(s); result.addAll(t); result.removeAll(isec); return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy