Created
August 27, 2021 19:42
-
-
Save ihaque/ee2f6de2091b5755219d8533b9bdfd15 to your computer and use it in GitHub Desktop.
Generate set of 64-bit FPs with fully unique pairwise Tanimotos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0x831A122F5DED0F74 | |
0xF1E6F872274DB4B4 | |
0x8940578CC91025A7 | |
0x5DFE2CABD588AB8A | |
0xF17DA5DF5A7438AB | |
0x8F97D17115314C0D | |
0xAFCF937513811F3B | |
0xDE69E942303BA44D | |
0x64D37E0B37C3B362 | |
0x09171FE07590059D | |
0x721B780423404B05 | |
0xD9EDEBF5C845228D | |
0x1FF6DFEA53D3D91D | |
0x01105E18B5017860 | |
0x00414301D8203AC1 | |
0x66DE9C6AF591BD0D | |
0xFD6FF4DF2FFF3EFB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Uses int.bit_count from Python 3.10rc1 | |
from fractions import Fraction | |
from random import randint, seed | |
from sys import stdout | |
from time import time | |
def rand64(): | |
return randint(0,0xFFFFFFFFFFFFFFFF) | |
def tanimoto(a,b): | |
return Fraction((a&b).bit_count(), (a|b).bit_count()) | |
if __name__ == '__main__': | |
start = time() | |
seed() | |
fps = [rand64(), rand64()] | |
all_tans = {tanimoto(fps[0], fps[1])} | |
tried_since_pass = 0 | |
while True: | |
new = rand64() | |
new_tans = {tanimoto(new, x) for x in fps} | |
# If all Tanimotos in this row are unique and do not overlap with | |
# previously calculated Tanimotos, then the full matrix will continue | |
# to be unique | |
if (len(new_tans) == len(fps)) and len(new_tans & all_tans) == 0: | |
fps.append(new) | |
all_tans = all_tans | new_tans | |
print('\nTook %d tries to add, now at %d, %d tans, et %.1fs' % | |
(tried_since_pass, len(fps), len(all_tans), time() - start)) | |
for fp in fps: | |
print('0x%016X' % fp) | |
assert(len(all_tans) == (len(fps) * (len(fps)-1))/2) | |
tried_since_pass = 0 | |
else: | |
tried_since_pass += 1 | |
if tried_since_pass % 10000 == 0: | |
stdout.write('.') | |
stdout.flush() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from fractions import Fraction | |
fps = [] | |
tans = set() | |
def tanimoto(a,b): | |
return Fraction((a & b).bit_count() , (a | b).bit_count()) | |
for line in sys.stdin: | |
num = int(line.rstrip(),16) | |
print('0x%016X' % num) | |
assert num not in fps | |
fps.append(num) | |
for i in fps: | |
for j in fps: | |
if i == j: | |
continue | |
tan = tanimoto(i,j) | |
assert tan not in tans | |
tans.add(tan) | |
print('Pass! %d Tanimotos, %d FPs' % (len(tans), len(fps))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment