-
Notifications
You must be signed in to change notification settings - Fork 0
/
netsimu.py
133 lines (115 loc) · 3.27 KB
/
netsimu.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import random
import math
from itertools import product
import pylab as plt
import math
from util import *
SHOW = False
dimention = 1
def randpos(space):
return tuple([random.random()*space for i in xrange(dimention)])
def cell(pos, near):
return tuple(map(lambda x: int(x / near), pos))
def adjacent_grid(centre, near):
near = int(near)
steps = product(range(-near, near + 1), repeat=len(centre))
return (tuple(c + d for c, d in zip(centre, delta)) for delta in steps)
def distance(p1, p2):
res = 0.0
for i in range(len(p1)):
res += (p1[i] - p2[i]) ** 2
return res ** (1.0 / len(p1))
def ptkey(p):
s = '_'.join(['%.10f' for i in p])
return s % p
def getgamma(near=1.0, steps=10, space=100, surviveratio=0.1):
def mergecluster(From, to):
nodes[to] += nodes[From]
edges[to] += edges[From]
for i in nodes[From]:
rdic[i] = to
del nodes[From]
del edges[From]
def getallometry():
x, y = [], []
for k, v in nodes.iteritems():
x.append(len(v))
y.append(len(edges[k]) + 1) # add 1 to edge, to avoid 0
x, y = map(lambda i:math.log(i), x), map(lambda i:math.log(i), y)
x, y = zip(*(sorted(zip(x, y))))
return calclinalg(x, y)
assert near > 0
if SHOW:
plt.ion()
colors = list(iter('bgrcmyk'))
p = randpos(space)
cel = cell(p, near)
celldic = {cell: [p]}
nodes = {p: [p]}
edges = {p:[]}
rdic = {p:p}
visited = set([p])
drawnode(p)
for c in range(steps):
print c,
p = randpos(space)
if p in visited:
continue
cel = cell(p, near)
survive = False
visit = set()
for i in adjacent_grid(cel, near):
for p2 in celldic.get(i, []):
if distance(p, p2) <= near:
survive = True
visit.add(p2)
if survive:
clus = set([rdic[i] for i in visit])
head = clus.pop()
for i in clus:
mergecluster(i, head)
nodes[head].append(p)
for i in visit:
edges[head].append((p, i))
drawedge(p, i)
rdic[p] = head
secondlife = False
if not survive and random.random() < surviveratio:
nodes[p] = [p]
edges[p] = []
rdic[p] = p
secondlife = True
if survive or secondlife:
celldic.setdefault(cel, [])
celldic[cel].append(p)
visited.add(p)
drawnode(p)
assert len(nodes) == len(edges)
assert len(visited) == len(rdic)
gamma = getallometry()
return gamma[0]
def drawnode(p):
if not SHOW:
return
if len(p) > 1:
plt.plot((p[0]), (p[1]), 'b.')
else:
plt.plot(0, p, 'b')
plt.draw()
def drawedge(p, p2, show=False):
if not SHOW:
return
xy = zip(p, p2)
if len(xy) > 1:
plt.plot(xy[0], xy[1], 'b')
if show:
plt.draw()
def main():
Ns = [(i + 1) * 100 for i in range(1, 10)]
Ms = []
for N in Ns:
Ms.append(getgamma(10, N, 400))
calclinalg(Ns, Ms, True)
plt.draw()
if __name__ == '__main__':
main()