logarithmic binning for the deviation-from-small-world costfunction.
diff --git a/sim.py b/sim.py --- a/sim.py +++ b/sim.py @@ -7,6 +7,7 @@ import numpy as np import pylab as pl import bisect from copy import deepcopy +import math def dist(loc0, loc1): """return the wraparound distance of 2 nodes in the [0,1) space.""" @@ -19,7 +20,7 @@ def distances(target, nodelist): lengths.append(dist(n,target)) return lengths -def randomnodes(num=1000): +def randomnodes(num=20000): """Generate num nodes with locations between 0 and 1.""" nodes = set() for n in range(num): @@ -29,7 +30,7 @@ def randomnodes(num=1000): nodes.add(n) return sorted(list(nodes)) -def generateflat(nodes, connectionspernode=10): +def generateflat(nodes, connectionspernode=20): """generate a randomly connected network with the given connectionspernode.""" net = {} for node in nodes: @@ -76,7 +77,7 @@ def smallworldtargetlocations(node, conn shuffle(locs) return locs[:connectionspernode] -def generatesmallworldunclean(nodes, connectionspernode=10): +def generatesmallworldunclean(nodes, connectionspernode=20): """generate an ideal small world network with the given connectionspernode.""" net = {} @@ -159,16 +160,22 @@ def dofold(target, prev, net): for conn in connections: net[conn] = sorted([c for c in net[conn] if not c == prev] + [realtarget]) -def deviationfromsmallworld(distribution, numbins=100): +def deviationfromsmallworld(distribution, numbins=5): """Calculate the deviation of the given local link length - distribution from a small world distribution.""" + distribution from a small world distribution. + + Use logarithmic binning to represent the relevant feature correctly. + + numbins should be clearly less than the number of connections + """ # first define the bin step: upper boundary. - bindefupper = [0.5/numbins*(i+1) for i in range(numbins)] + #: [0.0005, 0.005, 0.05, 0.5] + bindefupper = [0.5/10**((numbins-(i+1))) for i in range(numbins)] # then get the total number of links numlinks = len(distribution) # and define how an ideal bin distribution would look - idealbins = [1/((i+1)/numbins) for i in range(numbins)] - idealbins = [i/sum(idealbins) for i in idealbins] + idealbins = [1/numbins for i in range(numbins)] + #idealbins = [i/sum(idealbins) for i in idealbins] # now create the real bins realbins = [0 for i in range(numbins)] for link in distribution: @@ -178,7 +185,12 @@ def deviationfromsmallworld(distribution break #print ("ideal", idealbins) #print ("real", realbins) - diff = sum(abs(realbins[i] - idealbins[i]) for i in range(numbins)) + #print ("def", bindefupper) + # the difference is the cost + diff = sum(abs(realbins[i] - idealbins[i]) for i in range(numbins)) + # add additional cost for highest bin mismatch (they lose that too easily) + diff += abs(realbins[-1] - idealbins[-1]) + #print ([abs(realbins[i] - idealbins[i]) for i in range(numbins)]) #print("diff", diff) #print() return diff