00001
00002
00003 """
00004
00005 ScrumPy -- Metabolic Modelling with Python
00006
00007 Copyright Mark Poolman 1995 - 2002
00008
00009 This file is part of ScrumPy.
00010
00011 ScrumPy is free software; you can redistribute it and/or modify
00012 it under the terms of the GNU General Public License as published by
00013 the Free Software Foundation; either version 2 of the License, or
00014 (at your option) any later version.
00015
00016 ScrumPy is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 GNU General Public License for more details.
00020
00021 You should have received a copy of the GNU General Public License
00022 along with ScrumPy; if not, write to the Free Software
00023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00024
00025 """
00026 __doc__ = """
00027 M.G.Poolman 15/1/01 Set.py - basic set operations
00028
00029 Sets are lists with the precondition that :
00030 1 - all elements are unique
00031 2 - all elements are comparable with == and !=
00032 3 - no assumption is made as to the ordering of elements """
00033
00034
00035 def Union(a, b):
00036 rv = a[:]
00037 for el in b:
00038 if not el in a:
00039 rv.append(el)
00040
00041 return rv
00042
00043
00044 def Intersect(a, b):
00045 """ Intersection of a pair of sets """
00046 rv = []
00047 for el in a:
00048 if el in b:
00049 rv.append(el)
00050
00051 return rv
00052
00053 def Intersects(setl):
00054 """ pre: setl is a list of sets, len(setl) > 1
00055 post: the intersection of all sets in setl """
00056
00057 rv = setl[0]
00058 for s in setl[1:]:
00059 rv = Intersect(rv,s)
00060 return rv
00061
00062 def Difference(a,b):
00063 union = Union(a,b)
00064 intersect = Intersect(a,b)
00065 return Complement(union, intersect)
00066
00067 def Distance(a,b):
00068 union = Union(a,b)
00069 intersect = Intersect(a,b)
00070 diff = Complement(union, intersect)
00071 return float(len(diff))/len(union)
00072
00073
00074
00075 def Complement(a, b):
00076 rv = []
00077 for el in a:
00078 if el not in b:
00079 rv.append(el)
00080
00081 return rv
00082
00083
00084
00085 def DoesIntersect(a,b):
00086 for el in a:
00087 if el in b:
00088 return True
00089 return False
00090
00091
00092 def IsSubset(a, b):
00093 for el in a:
00094 if not el in b:
00095 return False
00096
00097 return True
00098
00099
00100 def IsEqual(a, b):
00101
00102 return IsSubset(a, b) and len(a) == len(b)
00103
00104
00105
00106 def Merge(SetList, __first=True):
00107 """ Pre: SetList is a list of sets, __first is private
00108 Post: Merge(SetList) == list of of sets, such that intersection in SetList are mereged,
00109 e.g. Merge([[1,2],[2,3],[4,5]]) => [[1,2,3],[4,5]]
00110 """
00111
00112 if __first:
00113 SetList = SetList[:]
00114 __first = False
00115
00116 Seen = 0
00117 lensets = len(SetList)
00118 rv = []
00119 for idx1 in range(lensets):
00120 if SetList[idx1] != Seen:
00121 newset = SetList[idx1]
00122 SetList[idx1] = Seen
00123 for idx2 in range(idx1+1, lensets):
00124 s2 = SetList[idx2]
00125 if s2 != Seen and DoesIntersect(newset, s2):
00126 newset = Union(newset,s2)
00127 SetList[idx2] = Seen
00128 rv.append(newset)
00129 if len(rv) < lensets:
00130 return Merge(rv, __first)
00131 else:
00132 return rv
00133
00134 def ElimSubs(SetList ):
00135 """ Pre: SetList is a list of sets
00136 Post: ElimSubs(sl) == a subset of the sets in SetList such that no set is a subset of any other
00137 """
00138
00139
00140 rv = []
00141 ssidxs = {}
00142 LenSetList = len(SetList)
00143 for i1 in range(LenSetList):
00144 for i2 in range(i1+1, LenSetList):
00145 s1 = SetList[i1]
00146 s2 = SetList[i2]
00147 if IsSubset(s1,s2):
00148 ssidxs[i1] = 1
00149 elif IsSubset(s2, s1):
00150 ssidxs[i2] = 1
00151
00152 ssidxs = ssidxs.keys()
00153 for i1 in range(LenSetList):
00154 if not i1 in ssidxs:
00155 rv.append(SetList[i1])
00156 return rv
00157
00158 """
00159 SetList = SetList[:]
00160 rv = []
00161 while len(SetList) > 0:
00162 set = SetList.pop()
00163 KeepIt = True
00164 for set2 in SetList:
00165 if IsSubset(set, set2):
00166 KeepIt = False
00167 break
00168 if IsSubset(set2, set):
00169 SetList.remove(set2)
00170 SetList.append(set)
00171 KeepIt = False
00172 if KeepIt:
00173 rv.append(set)
00174 return rv
00175 """
00176