comparison SmallWorldGraph.py @ 24:5c2c4ce095ef

A stab at the L(p)/L(0) plot. I still don't quite get how the graphs in the Watts and Strogatz paper were generated. My results have basically the same shape, but don't converge to 0. I'm not sure how this is possible if the rewire function does not remove edges.
author Brian Neal <bgneal@gmail.com>
date Thu, 03 Jan 2013 18:41:13 -0600
parents 74c9d126bd05
children a46783561538
comparison
equal deleted inserted replaced
23:74c9d126bd05 24:5c2c4ce095ef
5 import random 5 import random
6 6
7 from Graph import Edge 7 from Graph import Edge
8 from RandomGraph import RandomGraph 8 from RandomGraph import RandomGraph
9 9
10
11 INFINITY = float('Inf')
10 12
11 class SmallWorldGraph(RandomGraph): 13 class SmallWorldGraph(RandomGraph):
12 """A small world graph for 4.4, exercise 4 in Think Complexity.""" 14 """A small world graph for 4.4, exercise 4 in Think Complexity."""
13 15
14 def __init__(self, vs, k, p): 16 def __init__(self, vs, k, p):
24 26
25 """ 27 """
26 super(SmallWorldGraph, self).__init__(vs=vs) 28 super(SmallWorldGraph, self).__init__(vs=vs)
27 self.add_regular_edges(k) 29 self.add_regular_edges(k)
28 self.rewire(p) 30 self.rewire(p)
31
32 # give each edge a default length of 1; this is used by the
33 # shortest_path_tree() method
34 for e in self.edges():
35 e.length = 1
29 36
30 def rewire(self, p): 37 def rewire(self, p):
31 """Assuming the graph is initially a regular graph, rewires the graph 38 """Assuming the graph is initially a regular graph, rewires the graph
32 using the Watts and Strogatz algorithm. 39 using the Watts and Strogatz algorithm.
33 40
83 90
84 # The clustering coefficient is the average of all C sub v values 91 # The clustering coefficient is the average of all C sub v values
85 if len(cv): 92 if len(cv):
86 return sum(cv.values()) / float(len(cv)) 93 return sum(cv.values()) / float(len(cv))
87 return 0.0 94 return 0.0
95
96 def shortest_path_tree(self, source, hint=None):
97 """Finds the length of the shortest path from the source vertex to all
98 other vertices in the graph. This length is stored on the vertices as an
99 attribute named 'dist'. The algorithm used is Dijkstra's.
100
101 hint: if provided, must be a dictionary mapping tuples to already known
102 shortest path distances. This can be used to speed up the algorithm.
103
104 """
105 if not hint:
106 hint = {}
107
108 for v in self.vertices():
109 v.dist = hint.get((source, v), INFINITY)
110 source.dist = 0
111
112 queue = [v for v in self.vertices() if v.dist < INFINITY]
113 sort_flag = True
114 while len(queue):
115
116 if sort_flag:
117 queue.sort(key=lambda v: v.dist)
118 sort_flag = False
119
120 v = queue.pop(0)
121
122 # for each neighbor of v, see if we found a new shortest path
123 for w, e in self[v].iteritems():
124 d = v.dist + e.length
125 if d < w.dist:
126 w.dist = d
127 queue.append(w)
128 sort_flag = True
129
130 def big_l(self):
131 """Computes the "big-L" value for the graph as per Watts & Strogatz.
132
133 big_l() is defined as the number of edges in the shortest path between
134 two vertices, averaged over all vertices.
135
136 """
137 d = {}
138 for v in self.vertices():
139 self.shortest_path_tree(v, d)
140 t = [((w, v), w.dist) for w in self.vertices() if v is not w]
141 d.update(t)
142
143 if len(d):
144 return sum(d.values()) / float(len(d))
145 return 0.0