Guest User

Untitled

a guest
Jul 18th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.31 KB | None | 0 0
  1. from typing import Dict, Tuple
  2. from pprint import pformat
  3.  
  4. # Example graph
  5. graph_slides = {
  6. 0: {1: 8, 2: 2},
  7. 1: {0: 8, 2: 7, 3: 9, 4: 5},
  8. 2: {0: 2, 1: 7, 4: 6},
  9. 3: {1: 9, 4: 3, 5: 1},
  10. 4: {2: 6, 1: 5, 3: 3, 5: 4},
  11. 5: {3: 1, 4: 4}
  12. }
  13.  
  14. graph_slides_2 = {
  15. 0: {1: 1, 2: 7, 4: 2},
  16. 1: {0: 1, 3: 8, 4: 2, 5: 4},
  17. 2: {0: 7, 4: 3},
  18. 3: {1: 8, 5: 3},
  19. 4: {0: 2, 1: 2, 2: 3, 5: 9},
  20. 5: {1: 4, 3: 3, 4: 9}
  21. }
  22.  
  23. test_graph_1 = {
  24. 0: {1: 4, 3: 8},
  25. 1: {0: 4, 2: 5, 3: 7},
  26. 2: {1: 5, 3: 6},
  27. 3: {0: 8, 2: 6}
  28. }
  29.  
  30.  
  31. class PriorityQueue():
  32. """ Worst possible implementation of a priority queue - get's the job done
  33. for now
  34. """
  35.  
  36. def __init__(self):
  37. self._queue = []
  38.  
  39. def enqueue(self, node: int, value: int):
  40. """ Adds to the queue
  41.  
  42. :param node: Node
  43. :param value: Weight
  44. """
  45. self._queue.append((node, value))
  46. self._sort()
  47.  
  48. def _sort(self):
  49. """ Sorts """
  50. self._queue.sort(key=lambda a: a[1])
  51.  
  52. def contains(self, node: int) -> bool:
  53. """ Checks if a node is still in the queue
  54.  
  55. :param node: Node
  56. :returns: Node is in queue or not
  57. """
  58. for i in range(len(self._queue)):
  59. if self._queue[i][0] == node:
  60. return True
  61. return False
  62.  
  63. def pop(self) -> Tuple[int, int]:
  64. """ removes the first element
  65.  
  66. :returns: (node, value)
  67. """
  68. return self._queue.pop(0)
  69.  
  70. def decrease_key(self, node: int, value: int) -> bool:
  71. """ Changes a value if it is smaller than the existing one
  72.  
  73. :param node: Node
  74. :param value: New value
  75. :returns: Key changed
  76. """
  77. for i in range(len(self._queue)):
  78. if self._queue[i][0] == node:
  79. if self._queue[i][1] > value:
  80. self._queue[i] = (node, value)
  81. self._sort()
  82. return True
  83. break
  84.  
  85. return False
  86.  
  87. @property
  88. def empty(self) -> bool:
  89. """ Checks if the queue is empty """
  90. return len(self._queue) == 0
  91.  
  92.  
  93. class Prim(object):
  94. """ Prim algorithm as described in Informatik 2 """
  95.  
  96. def __init__(self, s: int, graph: Dict[int, Dict[int, int]]):
  97. """ Init """
  98. self.graph = graph
  99. self.queue = PriorityQueue()
  100.  
  101. # Initialize
  102. self.t = []
  103. self.dis = {i: float("inf") for i in graph.keys()}
  104. self.pre = {i: -1 for i in graph.keys()}
  105.  
  106. # Initialize Priority Queue
  107. for node, _ in self.graph.items():
  108. self.queue.enqueue(node, float("inf"))
  109.  
  110. self.queue.decrease_key(s, 0)
  111.  
  112. def compute(self):
  113. """ Prim algorithm """
  114. while not self.queue.empty:
  115. # Get node with smallest path
  116. u, w_prev = self.queue.pop()
  117.  
  118. # Add to t
  119. if self.pre[u] != -1:
  120. self.t.append((self.pre[u], u))
  121.  
  122. # print(u)
  123. # Iter over all path
  124. for v, w in self.graph[u].items():
  125. if self.queue.contains(v):
  126. if self.queue.decrease_key(v, w):
  127. self.pre[v] = u
  128.  
  129.  
  130. if __name__ == "__main__":
  131. p = Prim(0, graph_slides)
  132. p.compute()
  133. print(f"T: {pformat(p.t)}")
Add Comment
Please, Sign In to add comment