Advertisement
Guest User

Untitled

a guest
Apr 9th, 2020
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.88 KB | None | 0 0
  1. class IndexMinPQ:
  2.    
  3.     def __init__(self, n):
  4.         self.vals = [None for i in range(n)]
  5.         self.pm = [-1 for i in range(n)] # position map
  6.         self.pq = [-1 for i in range(n)] # priority queue
  7.         self.n = 0
  8.    
  9.     def less(self, i, j):
  10.         return self.vals[self.pq[i]] < self.vals[self.pq[j]]
  11.    
  12.     def swap(self, i, j):
  13.         self.pm[self.pq[i]], self.pm[self.pq[j]] = self.pm[self.pq[j]], self.pm[self.pq[i]]
  14.         self.pq[i], self.pq[j] = self.pq[j], self.pq[i]
  15.    
  16.     def swim(self, index):
  17.         parent = (index - 1) // 2
  18.         if index > 0 and self.less(index, parent):
  19.             self.swap(index, parent)
  20.             self.swim(parent)
  21.    
  22.     def sink(self, index):
  23.         left = 2 * index + 1
  24.         right = 2 * index + 2
  25.         child = left
  26.         if right < self.n and self.less(right, left):
  27.             child = right
  28.         if left >= self.n or self.less(index, child):
  29.             return
  30.         self.swap(index, child)
  31.         self.sink(child)
  32.    
  33.     def insert(self, key, val):
  34.         if self.contains(key):
  35.             raise ValueError("The supplied key is already in the priority queue. Try using update method.")
  36.         self.vals[key] = val
  37.         self.pm[key] = self.n
  38.         self.pq[self.n] = key
  39.         self.swim(self.n)
  40.         self.n += 1
  41.    
  42.     def update(self, key, val):
  43.         if self.empty():
  44.             raise ValueError("The priority queue is empty.")
  45.         oldval = self.vals[key]
  46.         self.vals[key] = val
  47.         index = self.pm[key]
  48.         self.sink(index)
  49.         self.swim(index)
  50.         return oldval
  51.    
  52.     def delete(self, key):
  53.         index = self.pm[key]
  54.         self.n -= 1
  55.         self.swap(index, self.n)
  56.         self.vals[key] = None
  57.         self.pq[self.n] = -1
  58.         self.pm[key] = -1
  59.         self.sink(index)
  60.         self.swim(index)
  61.    
  62.     def decrease(self, key, val):
  63.         if self.empty():
  64.             raise ValueError("The priority queue is empty.")
  65.         if val < self.vals[key]:
  66.             self.vals[key] = val
  67.             self.swim(self.pm[key])
  68.    
  69.     def increase(self, key, val):
  70.         if self.empty():
  71.             raise ValueError("The priority queue is empty.")
  72.         if self.vals[key] < val:
  73.             self.vals[key] = val
  74.             self.sink(self.pm[key])
  75.    
  76.     def del_min(self):
  77.         if self.empty():
  78.             return None
  79.         key = self.get_min_key()
  80.         self.delete(key)
  81.         return key
  82.    
  83.     def value_of(self, key):
  84.         return self.vals[key]
  85.    
  86.     def get_min_val(self):
  87.         return self.vals[self.pq[0]]
  88.    
  89.     def get_min_key(self):
  90.         return self.pq[0]
  91.    
  92.     def contains(self, key):
  93.         return self.pm[key] != -1
  94.    
  95.     def empty(self):
  96.         return self.n == 0
  97.    
  98.     def size(self):
  99.         return self.n
  100.    
  101.     def __str__(self):
  102.         out = ""
  103.         out += str([self.pq[i] for i in range(self.n)])
  104.         out += "\n"
  105.         #out += str(self.pm)
  106.         #out += "\n"
  107.         l = lambda i: self.vals[self.pq[i]] if self.pq[i] != -1 else None
  108.         out += str([l(i) for i in range(self.n)])
  109.         #out += str(self.vals)
  110.         return out
  111.  
  112. class BaseSPT:
  113.    
  114.     def __init__(self, g, s):
  115.         self.s = s
  116.         self.distance = [float("inf") for i in range(g.v())]
  117.         self.path = [None for i in range(g.v())]
  118.    
  119.     def source(self):
  120.         return self.s
  121.    
  122.     def dist(self, v):
  123.         return self.distance[v]
  124.    
  125.     def path_to(self, v):
  126.         path = gs.Stack()
  127.         e = self.path[v]
  128.         while e is not None:
  129.             path.push(e)
  130.             e = self.path[e.from_v()]
  131.         return path
  132.    
  133.     def relax(self, e):
  134.         v, w = e.from_v(), e.to_v()
  135.         if self.distance[w] > self.distance[v] + e.weight():
  136.             self.distance[w] = self.distance[v] + e.weight()
  137.             self.path[w] = e
  138.    
  139.     def __str__(self):
  140.         out = ""
  141.         out += str(self.distance)
  142.         out += "\n"
  143.         out += str(self.path)
  144.         return out
  145.    
  146.     def __repr__(self):
  147.         return self.__Str__()
  148.  
  149.  
  150. class DijkstrasSPT(BaseSPT):
  151.    
  152.     def __init__(self, g, s):
  153.         super().__init__(g, s)
  154.         self.q = IndexMinPQ(g.v())
  155.         self.search(g, s)
  156.    
  157.     def search(self, g, s):
  158.         self.distance[s] = 0.0
  159.         self.q.insert(s, 0.0)
  160.         while not self.q.empty():
  161.             v = self.q.del_min()
  162.             for e in g.adj(v):
  163.                 self.relax(e)
  164.    
  165.     def relax(self, e):
  166.         v, w = e.from_v(), e.to_v()
  167.         if self.distance[w] > self.distance[v] + e.weight():
  168.             self.distance[w] = self.distance[v] + e.weight()
  169.             self.path[w] = e
  170.             if self.q.contains(w):
  171.                 self.q.decrease(w, self.distance[w])
  172.             else:
  173.                 self.q.insert(w, self.distance[w])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement