net.sf.tweety.commons.util.SetTools Maven / Gradle / Ivy
/*
* 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 extends E> 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 extends E> 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