From dd06091452418f6659305b1b4ef8d030140e9af1 Mon Sep 17 00:00:00 2001 From: Zach S Date: Tue, 11 Jul 2017 23:10:22 -0700 Subject: [PATCH 1/3] Added invert function --- python/subsets.py | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/python/subsets.py b/python/subsets.py index 04a30d7..7cfd23c 100755 --- a/python/subsets.py +++ b/python/subsets.py @@ -72,7 +72,7 @@ def test(self): b = self.generateSubset(l, k, i) if b is None: break - print "%i %i %s: %s"%(l, k, i, b) + print("%i %i %s: %s"%(l, k, i, b)) i += 1 i = 0 @@ -80,14 +80,39 @@ def test(self): b = self.generateSubset(25, 24, i) if b is None: break - print "%i %i %s: %s"%(25, 24, i, b) + print("%i %i %s: %s"%(25, 24, i, b)) i += 1 self.precacheChoose(10000, 12) i = 160000 b = self.generateSubset(100, 3, i) - print "%i %i %s: %s"%(100, 3, i, b) + print("%i %i %s: %s"%(100, 3, i, b)) i = 160000000000000000000000000000 b = self.generateSubset(10000, 12, i) - print "%i %i %s: %s"%(10000, 12, i, b) + print("%i %i %s: %s"%(10000, 12, i, b)) + + def invert(self,n,l): + k=len(l) + assert(k<=n) #assert subset of {1,...,n} + assert(k==len(set(l)))#assert unique elements + assert(max(l) Date: Tue, 11 Jul 2017 23:59:09 -0700 Subject: [PATCH 2/3] Added algebraic invert --- python/__pycache__/subsets.cpython-34.pyc | Bin 0 -> 3823 bytes python/subsets.py | 227 ++++++++++++---------- 2 files changed, 120 insertions(+), 107 deletions(-) create mode 100644 python/__pycache__/subsets.cpython-34.pyc diff --git a/python/__pycache__/subsets.cpython-34.pyc b/python/__pycache__/subsets.cpython-34.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bca0aaec3d77448cf621f3903069f565fcc7d2a2 GIT binary patch literal 3823 zcmai1O>Y~?5v?8$DUzZj%8n&kFl>5}-Suo1QjibG2oxo|ma%a@6a(DA2oo}vCI%n#UOE;%j&uADit^Y}l~EXe4elFb$S%sHz%JOX<}UDIVr+qnLBViC!LCP7IcgSIKz^TOH^-o)nxg8 zczhICKMp#L<0nxNM{T%Se|$P<_s}9lg>*$uL|Qn$K-cVgCds$`_CbJw8wI_+KZtd) z?#1TDPols^8%+o|c7o_I?hiIDZL~3X9v}3>jVRrBeegUfwp!h=8@E~vx`>;L8LwT^ zT%Rm!6E*(0Z5~a}`UM6jj+_`dbj4PQU?ZMPK~O`4oIsmV)}Bu z;kmo#xPqM11LOHH*!Sb^v!H(X9nVd2N8KHS8;9iBHTdnY(6OyNr0c!R{1r+M5DC#0$|AIV_63 zt+!`lIkE=qYrq;896b;?0q-f!Y0iIx2#&r&32_8!Ogr+#ik!L%3KTGaGaNC)A0wH* zDUUP&bGx>Pjn9dI=Ol%Z^~3!@FX`nK2wQ>3GIX1{!&bMM3tQb+Fi92%Hqaoxrx4!2 z;;4*{@LV%%_&2U!hT~y7=!+9nrXiNa(`iXY@2eu%4~l=36KFWH3B{9=DwZyEA*)f5 z-bmwd69$G>9zlZ1Rh)+D^EZjHVwwx^ldI93r*&n>)B^M9g~V_bh(1dZ-G24%Y3g%F z?lSA(<|0OTs0nPox(RfKOPO2UT{{OD)wkoN5BvT4ksm&m*osl(yaKU0L;;|Y!)oVl+oN!@z2R?9aod;M-xg>^qD|8O{r-Jw&fv0 zFGi(?BPNUBy**b};6Vcw#M>r3HQYwpZJ<@*qnE9xCFnKQ|2$)Ty6E-RKSRucB5^RS zVN7&XFh+>-DoPoO*mR5Zz|+YYlc;kSN^0s=rOD*15^LFFMkS1>b9zBTa9nw_TjyW& zEwuCN6xPsnt8ZgOZt2R4wh&8?SHm`fa}# zZDWusd8H)R3&Lday$Ih_Ecy4X?OS^VcJMLakMQXQ@>51k3aORE?RBG=(n0n~kXAxH z7|UUH-1MXx?;d7-wCGFd1Yvc>+%z@NSH%<=WX|h83ew%CfmDDd5xIvJ{T?0S1jPYZ zGmsp4s{b`G^cw1bMiQKG@e1l9x|wrPH%E_^p0sFS<<8?DvW_BoXLV3U5HhvYD`_C{ z>*|#yY8Fc=s%^sd@F7^oh4*LO2(;eBx$PZx{8CEt`cdH(W(vy`MUnq;+6R!9QsE=tCf^nt)qVDxW{p&)fyiA zy;NcecUlO^B}y*#4UXtbOQM*e5j~)K+CWf5ix$zbh*g%Cij~`y8K|5CK zc7t0OznMqqwnF= upperBound: - return None - - zeros = 0 - low = 0 - high = self.choose(n-1, k-1) - while i >= high: - zeros += 1 - low = high - high += self.choose(n-zeros-1, k-1) - - if (zeros + k) > n: - raise Exception("Too many zeros!") - - b.add(offset + zeros) - if k == 1: - return sorted(b) - else: - n -= zeros + 1 - k -= 1 - i -= low - offset += zeros+1 - - def test(self): - for l in xrange(1, 10): - for k in xrange(1, min(l, 5)): - i = 0 - while 1: - b = self.generateSubset(l, k, i) - if b is None: - break - print("%i %i %s: %s"%(l, k, i, b)) - i += 1 - - i = 0 - while 1: - b = self.generateSubset(25, 24, i) - if b is None: - break - print("%i %i %s: %s"%(25, 24, i, b)) - i += 1 - - self.precacheChoose(10000, 12) - i = 160000 - b = self.generateSubset(100, 3, i) - print("%i %i %s: %s"%(100, 3, i, b)) - - i = 160000000000000000000000000000 - b = self.generateSubset(10000, 12, i) - print("%i %i %s: %s"%(10000, 12, i, b)) - - def invert(self,n,l): - k=len(l) - assert(k<=n) #assert subset of {1,...,n} - assert(k==len(set(l)))#assert unique elements - assert(max(l)n): + return 0 + k = min(k, n-k) + if k == 0: + return 1 + elif k < 0: + raise Exception("negative k?") + elif k == 1: + return n + # handle caching and subcalls + c = (n,k) + if c not in self.cache: + self.cache[c] = self.choose(n-1, k) + self.choose(n-1, k-1) + return self.cache[c] + + def precacheChoose(self, n, k=None): + # adjust your bounds + if k is None: + k = (n+1)//2 - 1 + for k_i in xrange(1, k+1): + for n_i in xrange(k_i, n+1): + self.choose(n_i, k_i) + + def generateSubset(self, n, k, i): + # non-recursive generateSubset(n, k, i), which will choose the i'th + # subset of size k from n items (numbered 0..n-1) + b = None + offset = 0 + while 1: + if b is None: + b = set() + + upperBound = self.choose(n,k) + if i >= upperBound: + return None + + zeros = 0 + low = 0 + high = self.choose(n-1, k-1) + while i >= high: + zeros += 1 + low = high + high += self.choose(n-zeros-1, k-1) + + if (zeros + k) > n: + raise Exception("Too many zeros!") + + b.add(offset + zeros) + if k == 1: + return sorted(b) + else: + n -= zeros + 1 + k -= 1 + i -= low + offset += zeros+1 + + def test(self): + for l in xrange(1, 10): + for k in xrange(1, min(l, 5)): + i = 0 + while 1: + b = self.generateSubset(l, k, i) + if b is None: + break + print("%i %i %s: %s"%(l, k, i, b)) + i += 1 + + i = 0 + while 1: + b = self.generateSubset(25, 24, i) + if b is None: + break + print("%i %i %s: %s"%(25, 24, i, b)) + i += 1 + + self.precacheChoose(10000, 12) + i = 160000 + b = self.generateSubset(100, 3, i) + print("%i %i %s: %s"%(100, 3, i, b)) + + i = 160000000000000000000000000000 + b = self.generateSubset(10000, 12, i) + print("%i %i %s: %s"%(10000, 12, i, b)) + + def invert(self,n,l): + k=len(l) + assert(k<=n) #assert subset of {1,...,n} + assert(k==len(set(l)))#assert unique elements + assert(max(l) Date: Wed, 12 Jul 2017 00:01:11 -0700 Subject: [PATCH 3/3] cleaned up main --- python/subsets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/subsets.py b/python/subsets.py index 6883cd1..0918447 100755 --- a/python/subsets.py +++ b/python/subsets.py @@ -115,7 +115,7 @@ def algebraicInvert(self,n,l): if __name__=='__main__': a = EnumeratedSubsets() max_n = 15 - for n in range(8,max_n): + for n in range(1,max_n): for k in range(1,n+1): for i in range(0,a.choose(n,k)): l= a.generateSubset(n,k,i)