Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.57 KB | None | 0 0
  1. import copy
  2.  
  3. class Graph:
  4. def __init__(self):
  5. self.vertices = {}
  6. self.invVertices = []
  7. self.adjList = []
  8. self.size = 0
  9.  
  10. def insert_node(self, name):
  11. self.invVertices.append(name)
  12. self.vertices[name] = self.size
  13. self.adjList.append([])
  14. self.size += 1
  15.  
  16. def insert_edge(self, src, dest, weight = 1):
  17. self.adjList[self.vertices[src]].append((self.vertices[dest], weight))
  18.  
  19. def bfs(self, source):
  20. source = self.vertices[source]
  21. visit = [True for i in xrange(self.size)]
  22. queue = [source]
  23. visit[source] = False
  24. pi = {source : source}
  25.  
  26. while len(queue) != 0:
  27. c = queue.pop()
  28. print "Node: ", self.invVertices[c], "\t Pi(", self.invVertices[c], "): ", self.invVertices[pi[c]]
  29.  
  30. for n,w in self.adjList[c]:
  31. if visit[n]:
  32. queue.insert(0, n)
  33. pi[n] = c
  34. visit[n] = False
  35.  
  36. def dfs_iterative(self, source):
  37. source = self.vertices[source]
  38. visit = [True for i in xrange(self.size)]
  39. stack = [source]
  40. pi = {source : source}
  41.  
  42. while len(stack) != 0:
  43. c = stack.pop()
  44.  
  45. if visit[c]:
  46. print "Node: ", self.invVertices[c], "\t Pi(", self.invVertices[c], "): ", self.invVertices[pi[c]]
  47.  
  48. visit[c] = False
  49.  
  50. for n,w in self.adjList[c]:
  51. if visit[n]:
  52. stack.append(n)
  53. pi[n] = c
  54.  
  55. def vertices_decreasing_finish_time_visit(self, root, visit, sortedVertices):
  56. visit[root] = False
  57.  
  58. for node, wt in self.adjList[root]:
  59. if visit[node]:
  60. self.vertices_decreasing_finish_time_visit(node, visit, sortedVertices)
  61.  
  62. sortedVertices.insert(0, root)
  63.  
  64. def vertices_decreasing_finish_time(self):
  65. visit = [True for i in xrange(self.size)]
  66. sortedVertices = []
  67.  
  68. for i in xrange(self.size):
  69. if visit[i]:
  70. self.vertices_decreasing_finish_time_visit(i, visit, sortedVertices)
  71.  
  72. return sortedVertices
  73.  
  74. def get_transpose(self):
  75. transpose = copy.deepcopy(self)
  76. transpose.adjList = [[] for i in xrange(transpose.size)]
  77.  
  78. for i in xrange(self.size):
  79. for node, wt in self.adjList[i]:
  80. transpose.adjList[node].append((i, wt))
  81.  
  82. return transpose
  83.  
  84. def strongly_connected_components(self):
  85. transpose = self.get_transpose()
  86. visit = [True for i in xrange(self.size)]
  87. scc = []
  88.  
  89. for i in self.vertices_decreasing_finish_time():
  90. if visit[i]:
  91. l = []
  92. transpose.vertices_decreasing_finish_time_visit(i, visit, l)
  93. scc.append(l)
  94.  
  95. return scc
  96.  
  97. def dijkstra(self, rt):
  98. root = self.vertices[rt]
  99. size = self.size
  100. INF = float('inf')
  101. m = Heap(size = size, inf = INF)
  102. dist = [INF for i in xrange(size)]
  103. pi = [0 for i in xrange(size)]
  104.  
  105. m.update(root, 0)
  106. pi[root] = root
  107. dist[root] = 0
  108.  
  109. for i in xrange(size):
  110. root = m.extract_top()
  111.  
  112. if dist[root] == INF:
  113. break
  114.  
  115. for node, wt in self.adjList[root]:
  116. if dist[root] + wt < dist[node]:
  117. dist[node] = dist[root] + wt
  118. m.update(node, dist[node])
  119. pi[node] = root
  120.  
  121. for i in xrange(size):
  122. if dist[i] != INF:
  123. print "Node: ", self.invVertices[i],"\tDistance: ",dist[i],"\tPi(",self.invVertices[i],"): ",self.invVertices[pi[i]]
  124.  
  125. class UndirectedGraph(Graph):
  126. def __init__(self):
  127. Graph.__init__(self)
  128.  
  129. def insert_edge(self, node1, node2, wt = 1):
  130. Graph.insert_edge(self, node1, node2, wt)
  131. Graph.insert_edge(self, node2, node1, wt)
  132.  
  133. def span_tree_prim(self, rt, isMin = True):
  134. root = self.vertices[rt]
  135. size = self.size
  136. INF = float('inf') * (1 if isMin else -1)
  137. m = Heap(size = size, inf = INF, isMin = isMin)
  138. dist = [INF for i in xrange(size)]
  139. pi = [0 for i in xrange(size)]
  140. visit = [True for i in xrange(size)]
  141.  
  142. m.update(root, 0)
  143. pi[root] = root
  144. dist[root] = 0
  145.  
  146. for i in xrange(size):
  147. root = m.extract_top()
  148. visit[root] = False
  149.  
  150. if dist[root] == INF:
  151. break
  152.  
  153. for node, wt in self.adjList[root]:
  154. if visit[node] and (wt < dist[node] if isMin else wt > dist[node]):
  155. dist[node] = wt
  156. m.update(node, dist[node])
  157. pi[node] = root
  158.  
  159. for i in xrange(size):
  160. if dist[i] != INF:
  161. print "Node: ", self.invVertices[i],"\tEdge Weight: ",dist[i],"\tPi(",self.invVertices[i],"): ",self.invVertices[pi[i]]
  162.  
  163. def span_forest_kruskal(self, isMin = True):
  164. edgeList = []
  165.  
  166. for i in xrange(self.size):
  167. for node, wt in self.adjList[i]:
  168. if node >= i:
  169. edgeList.append((i, node, wt))
  170.  
  171. sorted(edgeList, key = lambda x: x[2], reverse = isMin)
  172.  
  173. spanForest = [[] for i in xrange(self.size)]
  174. getComp = [i for i in xrange(self.size)]
  175. sizeComp = [1 for i in xrange(self.size)]
  176.  
  177. for curredge in edgeList:
  178. if getComp[curredge[0]] != getComp[curredge[1]]:
  179. minSizeComp = getComp[curredge[0]]
  180. maxSizeComp = getComp[curredge[1]]
  181. if sizeComp[minSizeComp] > sizeComp[maxSizeComp]:
  182. minSizeComp, maxSizeComp = maxSizeComp, minSizeComp
  183.  
  184. for edge in spanForest[minSizeComp]:
  185. getComp[edge[0]] = maxSizeComp
  186. getComp[edge[1]] = maxSizeComp
  187.  
  188. sizeComp[maxSizeComp] += sizeComp[minSizeComp]
  189. sizeComp[minSizeComp] = 0
  190.  
  191. spanForest[maxSizeComp].append(curredge)
  192. getComp[curredge[0]] = maxSizeComp
  193. getComp[curredge[1]] = maxSizeComp
  194.  
  195. spanForest[minSizeComp] = []
  196.  
  197. for tree in spanForest:
  198. if tree:
  199. print "Tree:"
  200. for edge in tree:
  201. print "Node 1: ",self.invVertices[edge[0]],"\tNode 2: ",self.invVertices[edge[1]],"\tEdge Weight: ",edge[2]
  202.  
  203. class Heap:
  204. @staticmethod
  205. def parent(n):
  206. return (n-1)/2
  207.  
  208. @staticmethod
  209. def left(n):
  210. return 2*n + 1
  211.  
  212. @staticmethod
  213. def right(n):
  214. return 2*n + 2
  215.  
  216. def compare(self, a, b):
  217. return (a < b if self.isMin else a > b)
  218.  
  219. def swap(self, i, j):
  220. self.pos[self.heap[i][0]] = j
  221. self.pos[self.heap[j][0]] = i
  222. self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
  223.  
  224. def __init__(self, size, inf, isMin = True):
  225. self.pos = [i for i in xrange(size)]
  226. self.heap = [[i, inf] for i in xrange(size)]
  227. self.size = size
  228. self.isMin = isMin
  229.  
  230. def update(self, i, newVal):
  231. if self.compare(self.heap[self.pos[i]][1], newVal):
  232. self.heap[self.pos[i]][1] = newVal
  233. self.top_down_heapify(self.pos[i])
  234.  
  235. else:
  236. self.heap[self.pos[i]][1] = newVal
  237. self.bottom_up_heapify(self.pos[i])
  238.  
  239. def extract_top(self):
  240. retVal = self.heap[0][0]
  241. self.size -= 1
  242. self.swap(0, self.size)
  243. self.heap.pop()
  244. self.top_down_heapify(0)
  245. return retVal
  246.  
  247. def top_down_heapify(self, i):
  248. l = Heap.left(i)
  249. r = Heap.right(i)
  250. j = i
  251.  
  252. while r < self.size:
  253. j = l if self.compare(self.heap[l][1], self.heap[r][1]) else r
  254.  
  255. if self.compare(self.heap[i][1], self.heap[j][1]):
  256. break
  257.  
  258. else:
  259. self.swap(i, j)
  260. i = j
  261. l = Heap.left(i)
  262. r = Heap.right(i)
  263.  
  264. if l == self.size - 1 and self.compare(self.heap[l][1], self.heap[j][1]):
  265. self.swap(l, j)
  266.  
  267. def bottom_up_heapify(self, i):
  268. p = Heap.parent(i)
  269. while(p >= 0):
  270. if self.compare(self.heap[i][1], self.heap[p][1]):
  271. self.swap(i, p)
  272. i = p
  273. p = Heap.parent(i)
  274.  
  275. else:
  276. break
  277.  
  278. if __name__ == "__main__":
  279. a = UndirectedGraph()
  280.  
  281. a.insert_node('A')
  282. a.insert_node('B')
  283. a.insert_node('C')
  284. a.insert_node('D')
  285. a.insert_node('E')
  286. a.insert_node('F')
  287. a.insert_node('G')
  288. a.insert_node('H')
  289. a.insert_node('I')
  290.  
  291. a.insert_edge('A', 'B', 4)
  292. a.insert_edge('B', 'C')
  293. a.insert_edge('D', 'B', 3)
  294. a.insert_edge('E', 'D', 7)
  295. a.insert_edge('E', 'C', 8)
  296. a.insert_edge('C', 'F')
  297. a.insert_edge('E', 'A', 3)
  298. a.insert_edge('G', 'H', 5)
  299. a.insert_edge('G', 'I', 10)
  300. a.insert_edge('H', 'I', 4)
  301.  
  302. print "BFS:"
  303. a.bfs('A')
  304.  
  305. print "\nDFS:"
  306. a.dfs_iterative('A')
  307.  
  308. print "\nDijkstra:"
  309. a.dijkstra('A')
  310.  
  311. print "\nMinimum Span Tree Prim's:"
  312. a.span_tree_prim('A')
  313.  
  314. print "\nMaximum Span Tree Prim's:"
  315. a.span_tree_prim('A', False)
  316.  
  317. print "\nMinimum Span Forest Kruskal's:"
  318. a.span_forest_kruskal()
  319.  
  320. print "\nMaximum Span Tree Kruskal's:"
  321. a.span_forest_kruskal(False)
  322.  
  323. print "\nStrongly Connected Components:"
  324. print a.strongly_connected_components()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement