import time import random from multiprocessing import Process, Pool def main(): start = time.time() # number process k=int(input('Number of parallel processes: ')) # data points per process m=int(input('Number of data points per process: ')) # vertices per graph n=int(input('Number of vertices per graph: ')) # probability of each edge appearing p=float(input('Probability of an edge connecting two vertices: ')) numlinks=[] pool = Pool(k) results=[pool.apply_async(generate_data,args=(n,m,p,)) for i in range(k)] count=[] for result in results: result.wait() output = result.get() count=merge_data(count,output) print('Distribution of linking numbers: ' + str(count)) sum_squared=0 for i in range(len(count)): sum_squared+= i*i* count[i] avg = 1. * sum_squared/k/m print('Average sum of linking number squared: ' + str(avg)) end = time.time() print('Total time: ' + str(end-start)) def generate_data(n,m,p): count = [] for i in range(m): # generate random graph data = random_graph(n,p) # merge data merge_data(count,data) return count def merge_data(count, data): while len(count)< len(data): count.append(0) for i in range(len(data)): count[i]+=data[i] return count def generate_coords(len): #pts = [[1,1,1], [2,2,2], [3,3,3], [4,4,4], [5,5,5], [6,6,6]] pts=[] for i in range(len): pts.append([random.random(),random.random(),random.random()]) return pts def generate_adj(len,p): adj = [] for i in range(len): adj.append([]) for j in range(len): if j>i: if random.random()2 and len(link2)>2: return [[link1, link2]] else: return [] else: output = [] output+=generate_components(link1+[points[0]], link2, points[1:]) output+=generate_components(link1,link2,points[1:]) if len(link1)>0: output+=generate_components(link1,link2+[points[0]],points[1:]) return output def permute_cycle(perm, remainder,adj): if len(remainder) == 0: # remove duplicates with reverse orientation if perm[1] < perm[-1]: # also check if last and first are connected if adj[perm[0]][perm[-1]]==1: return [perm] else: return [] else: return [] if len(perm) == 0: return permute_cycle([remainder[0]], remainder[1:],adj) else: output=[] for i in range(len(remainder)): if adj[perm[-1]][remainder[i]]==1: output+= permute_cycle(perm +[remainder[i]], remainder[:i]+remainder[i+1:],adj) return output def linking_number(link1,link2,pts): len1 = len(link1) len2 = len(link2) cross_num=0 for i in range(len1): for k in range(len2): j=(i+1) % len1 l=(k+1) % len2 p1=pts[link1[i]] p2=pts[link1[j]] q1=pts[link2[k]] q2=pts[link2[l]] cross_num+=check_crossing(p1,p2,q1,q2) # string output for mathematica comp1 = '' comp2 = '' for i in range(len1): comp1 += '{' + str(link1[i])[1:-1] + '},' for k in range(len2): comp2 += '{' + str(link2[k])[1:-1] + '},' comp1 += '{' + str(link1[0])[1:-1] + '}' comp2 += '{' + str(link2[0])[1:-1] + '}' #print('Graphics3D[{Red,Line[{'+comp1+'}],Blue,Line[{'+comp2+'}]}]') return abs(cross_num // 2) def check_crossing(p1,p2,q1,q2): # solve linear system for when two lines cross dxp = p2[0]-p1[0] dyp = p2[1]-p1[1] dxq = q2[0]-q1[0] dyq = q2[1]-q1[1] dxc = q1[0]-p1[0] dyc = q1[1]-p1[1] det=dyp*dxq-dxp*dyq t=( dxq*dyc-dyq*dxc ) / det s=( dxp*dyc-dyp*dxc ) / det # check if the lines cross inside the segments from p1 to p2 and q1 to q2 if (0 (q1[2]+s*(q2[2]-q1[2])): overunder= 1 else: overunder= -1 else: overunder= 0 # now determine sign of crossing if (det*overunder >0): return 1 elif (det*overunder < 0): return -1 else: return 0 if __name__ == "__main__": main() #Number of parallel processes: 1 #Number of data points per process: 1 #Number of vertices per graph: 12 #Distribution of linking numbers: [21803078, 12436371, 1439391, 70623, 1826, 20] #Average sum of linking number squared: 18859258.0 #Total time: 6144.5997149944305 #Number of parallel processes: 4 #Number of data points per process: 25 #Number of vertices per graph: 11 #Distribution of linking numbers: [197717315, 88252703, 6298213, 152203, 2447, 18, 1] #Average sum of linking number squared: 1148550.2 #Total time: 11594.052151679993 #Number of parallel processes: 4 #Number of data points per process: 25 #Number of vertices per graph: 10 #Distribution of linking numbers: [18121918, 6927567, 347324, 5051, 40] #Average sum of linking number squared: 83629.62 #Total time: 925.2083818912506 #Number of parallel processes: 10 #Number of data points per process: 100 #Number of vertices per graph: 10 #Distribution of linking numbers: [181141920, 69334838, 3495202, 46635, 404, 1] #Average sum of linking number squared: 83741.85 #Total time: 4584.27324009 #Number of parallel processes: 4 #Number of data points per process: 25 #Number of vertices per graph: 9 #Distribution of linking numbers: [1747822, 543817, 16180, 81] #Average sum of linking number squared: 6092.66 #Total time: 84.65731692314148 #Number of parallel processes: 4 #Number of data points per process: 25 #Number of vertices per graph: 8 #Distribution of linking numbers: [167672, 42308, 720] #Average sum of linking number squared: 451.88 #Total time: 9.123421669006348 #Number of parallel processes: 4 #Number of data points per process: 25 #Number of vertices per graph: 7 #Distribution of linking numbers: [14437, 3046, 17] #Average sum of linking number squared: 31.14 #Total time: 3.5018203258514404 #Number of parallel processes: 4 #Number of data points per process: 25 #Number of vertices per graph: 6 #Distribution of linking numbers: [838, 162] #Average sum of linking number squared: 1.62 #Total time: 3.2760980129241943