comparison SmallWorldGraph.py @ 26:f6073c187926

Added a version of Dijkstra that uses a heap.
author Brian Neal <bgneal@gmail.com>
date Sat, 05 Jan 2013 13:30:58 -0600
parents a46783561538
children 305cc03c2750
comparison
equal deleted inserted replaced
25:a46783561538 26:f6073c187926
1 """This module contains the SmallWorldGraph class for 4.4, exercise 4. 1 """This module contains the SmallWorldGraph class for 4.4, exercise 4.
2 2
3 """ 3 """
4 import heapq
4 import itertools 5 import itertools
5 import random 6 import random
6 7
7 from Graph import Edge 8 from Graph import Edge
8 from RandomGraph import RandomGraph 9 from RandomGraph import RandomGraph
124 d = v.dist + e.length 125 d = v.dist + e.length
125 if d < w.dist: 126 if d < w.dist:
126 w.dist = d 127 w.dist = d
127 queue.append(w) 128 queue.append(w)
128 sort_flag = True 129 sort_flag = True
130
131 def shortest_path_tree2(self, source):
132 """Finds the length of the shortest path from the source vertex to all
133 other vertices in the graph. This length is stored on the vertices as an
134 attribute named 'dist'. The algorithm used is Dijkstra's with a Heap
135 used to sort/store pending nodes to be examined.
136
137 """
138 for v in self.vertices():
139 v.dist = INFINITY
140 source.dist = 0
141
142 queue = []
143 heapq.heappush(queue, (0, source))
144 while len(queue):
145
146 _, v = heapq.heappop(queue)
147
148 # for each neighbor of v, see if we found a new shortest path
149 for w, e in self[v].iteritems():
150 d = v.dist + e.length
151 if d < w.dist:
152 w.dist = d
153 heapq.heappush(queue, (d, w))
129 154
130 def all_pairs_floyd_warshall(self): 155 def all_pairs_floyd_warshall(self):
131 """Finds the shortest paths between all pairs of vertices using the 156 """Finds the shortest paths between all pairs of vertices using the
132 Floyd-Warshall algorithm. 157 Floyd-Warshall algorithm.
133 158
156 return dist 181 return dist
157 182
158 def big_l(self): 183 def big_l(self):
159 """Computes the "big-L" value for the graph as per Watts & Strogatz. 184 """Computes the "big-L" value for the graph as per Watts & Strogatz.
160 185
161 big_l() is defined as the number of edges in the shortest path between 186 L is defined as the number of edges in the shortest path between
162 two vertices, averaged over all vertices. 187 two vertices, averaged over all vertices.
163 188
164 Uses the shortest_path_tree() method, called once for every node. 189 Uses the shortest_path_tree() method, called once for every node.
165 190
166 """ 191 """
175 return 0.0 200 return 0.0
176 201
177 def big_l2(self): 202 def big_l2(self):
178 """Computes the "big-L" value for the graph as per Watts & Strogatz. 203 """Computes the "big-L" value for the graph as per Watts & Strogatz.
179 204
180 big_l() is defined as the number of edges in the shortest path between 205 L is defined as the number of edges in the shortest path between
181 two vertices, averaged over all vertices. 206 two vertices, averaged over all vertices.
182 207
183 Uses the all_pairs_floyd_warshall() method. 208 Uses the all_pairs_floyd_warshall() method.
184 209
185 """ 210 """
188 result = [dist[i, j] for i in vertices for j in vertices if i is not j] 213 result = [dist[i, j] for i in vertices for j in vertices if i is not j]
189 214
190 if len(result): 215 if len(result):
191 return sum(result) / float(len(result)) 216 return sum(result) / float(len(result))
192 return 0.0 217 return 0.0
218
219 def big_l3(self):
220 """Computes the "big-L" value for the graph as per Watts & Strogatz.
221
222 L is defined as the number of edges in the shortest path between
223 two vertices, averaged over all vertices.
224
225 Uses the shortest_path_tree2() method, called once for every node.
226
227 """
228 d = {}
229 for v in self.vertices():
230 self.shortest_path_tree2(v)
231 t = [((v, w), w.dist) for w in self.vertices() if v is not w]
232 d.update(t)
233
234 if len(d):
235 return sum(d.values()) / float(len(d))
236 return 0.0
237