def decode_sets(bytes): """ Decodes a set of sets encoded using encode_sets (see above). >>> b = BitStream(hex='0x00000000000000010503').tobytes(); write_sets(decode_sets(b)) '{{0,2},{0,1}}' >>> b = BitStream(hex='0x000000000000000100').tobytes(); write_sets(decode_sets(b)) '{{}}' >>> b = BitStream(hex='0x0000000000000001').tobytes(); write_sets(decode_sets(b)) '{}' """ from bitstring.bitstream import BitStream, pack bs = BitStream(bytes=bytes) bytesperset, content = bs.readlist('uint:64, bits') setOfSets = set() for bits in content.cut(bytesperset * 8): aSet = set() bits.reverse() for i, b in enumerate(bits): if b is True: aSet.add(i) setOfSets.add(frozenset(aSet)) return setOfSets
def decode_sets(bytes): """ Decodes a set of sets encoded using encode_sets (see above). >>> b = BitStream(hex='0x00000000000000010503').tobytes(); write_sets(decode_sets(b)) '{{0,2},{0,1}}' >>> b = BitStream(hex='0x000000000000000100').tobytes(); write_sets(decode_sets(b)) '{{}}' >>> b = BitStream(hex='0x0000000000000001').tobytes(); write_sets(decode_sets(b)) '{}' """ from bitstring.bitstream import BitStream, pack bs = BitStream(bytes=bytes) bytesperset, content = bs.readlist('uint:64, bits') setOfSets = set() for bits in content.cut(bytesperset*8): aSet = set() bits.reverse() for i,b in enumerate(bits): if b is True: aSet.add(i) setOfSets.add(frozenset(aSet)) return setOfSets
def encode_sets(setOfSets): """ Encode a set of sets (e.g., a set of conflict sets or a set of hitting sets) in a binary format, where each of the sets is represented as a word whose bits indicate which elements are part of the set. The first 64bit unsigned big-endian integer indicates the number of bytes used per set. For example, the set of sets {{a,c},{a,b}} contains three components: [a, b, c]. As we only use full bytes (i.e. 8 bits, 16 bits, ...), we use 1 byte to encode each set in this example. Therefore, the first 64 bit of the encoded value are 0x0000000000000001. The set {a,c} contains components number 1 and 3: a = 0b001 c = 0b100 --------- = 0b101 = 0x5 = 0x05 The set {a,b} contains components number 1 and 2: a = 0b001 b = 0b010 --------- = 0b011 = 0x3 = 0x03 Thus, the encoded value of {{a,c},{a,b}} is 0x00000000000000010503. Examples: >>> b = encode_sets(read_sets('{{a,c},{a,b}}')); BitStream(bytes=b).hex '0x00000000000000010503' >>> b = encode_sets(read_sets('{{0,2},{0,1}}')); BitStream(bytes=b).hex '0x00000000000000010503' Corner case: setOfSets contains just one empty set: >>> b = encode_sets(frozenset([frozenset([])])); BitStream(bytes=b).hex '0x000000000000000100' Corner case: setOfSets is empty itself: >>> b = encode_sets(frozenset([])); BitStream(bytes=b).hex '0x0000000000000001' """ from bitstring.bitstream import BitStream, pack comp = sorted(list(set().union(*setOfSets))) bytesperset = max(1, int(ceil(float(len(comp)) / 8))) bs = BitStream() bs.append(pack('uint:64', bytesperset)) for aSet in setOfSets: result = 0 for element in aSet: result |= 2**(comp.index(element)) bs.append(pack('uint:%d' % (bytesperset * 8), result)) return bs.tobytes()
def encode_sets(setOfSets): """ Encode a set of sets (e.g., a set of conflict sets or a set of hitting sets) in a binary format, where each of the sets is represented as a word whose bits indicate which elements are part of the set. The first 64bit unsigned big-endian integer indicates the number of bytes used per set. For example, the set of sets {{a,c},{a,b}} contains three components: [a, b, c]. As we only use full bytes (i.e. 8 bits, 16 bits, ...), we use 1 byte to encode each set in this example. Therefore, the first 64 bit of the encoded value are 0x0000000000000001. The set {a,c} contains components number 1 and 3: a = 0b001 c = 0b100 --------- = 0b101 = 0x5 = 0x05 The set {a,b} contains components number 1 and 2: a = 0b001 b = 0b010 --------- = 0b011 = 0x3 = 0x03 Thus, the encoded value of {{a,c},{a,b}} is 0x00000000000000010503. Examples: >>> b = encode_sets(read_sets('{{a,c},{a,b}}')); BitStream(bytes=b).hex '0x00000000000000010503' >>> b = encode_sets(read_sets('{{0,2},{0,1}}')); BitStream(bytes=b).hex '0x00000000000000010503' Corner case: setOfSets contains just one empty set: >>> b = encode_sets(frozenset([frozenset([])])); BitStream(bytes=b).hex '0x000000000000000100' Corner case: setOfSets is empty itself: >>> b = encode_sets(frozenset([])); BitStream(bytes=b).hex '0x0000000000000001' """ from bitstring.bitstream import BitStream, pack comp = sorted(list(set().union(*setOfSets))) bytesperset = max(1,int(ceil(float(len(comp))/8))) bs = BitStream() bs.append(pack('uint:64', bytesperset)) for aSet in setOfSets: result = 0 for element in aSet: result |= 2**(comp.index(element)) bs.append(pack('uint:%d' % (bytesperset*8), result)) return bs.tobytes()