def main_Prim_2(self, grp, src=0): # 1) initialize vtx = [0 if i != src else 1 for i in range(len(grp))] dis = [None if i != src else 0 for i in range(len(grp))] pre = [None] * len(grp) hp = MinBinaryHeap(key=lambda x: x[1]) for i, w in grp[src]: dis[i] = w pre[i] = src hp.push((i, dis[i])) # 2) build MST by greedily selecting vertexes from heap mst = [] while len(hp) > 0: i, w = hp.pop() assert (dis[i] is not None and w >= dis[i]) if w > dis[i] or vtx[i] != 0: continue mst.append(((i, pre[i]), dis[i])) vtx[i] = 1 for j, v in grp[i]: if vtx[j] == 0 and (dis[j] is None or dis[j] > v): dis[j] = v pre[j] = i hp.push((j, dis[j])) assert (len(mst) == len(grp) - 1) assert (sum(vtx) == len(vtx)) return mst
class Collision(): def __init__(self, particles): assert (all(isinstance(x, Particle) for x in particles)) self.particles = particles[:] self.evtQue = None def predict(self, pa, time, limit): assert (pa != None and isinstance(pa, Particle)) for pb in self.particles: if pb != pa: dt = pa.timeToHit(pb) if dt != None and time + dt <= limit: self.evtQue.push(Event(time + dt, pa, pb)) dt = pa.timeToHitVerticalWall() if time + dt <= limit: self.evtQue.push(Event(time + dt, pa, None)) dt = pa.timeToHitHorizontalWall() if time + dt <= limit: self.evtQue.push(Event(time + dt, None, pa)) def simulate(self, limit, hz): # reset and restart time = 0 self.evtQue = MinBinaryHeap(key=lambda x: x.time) self.evtQue.push(Event(time, None, None)) map(lambda x: self.predict(x, time, limit), self.particles) # main loop while len(self.evtQue) > 0: # get the nearest event evt = self.evtQue.pop() if not evt.isValid(): continue # update all particles for pa in self.particles: pa.move(evt.time - self.time) self.time = evt.time # handle collision and predict the future if evt.pa != None and evt.pb != None: evt.pa.bounceOff(evt.pb) self.predict(evt.pa, time, limit) self.predict(evt.pb, time, limit) elif evt.pa != None and evt.pb == None: evt.pa.bounceoffVerticalWall() self.predict(evt.pa, time, limit) elif evt.pa == None and evt.pb != None: evt.pb.bounceOffHorizontalWall() self.predict(evt.pb, time, limit) else: self.redraw(hz) def redraw(self, hz): pass
def main(self, chst): assert (isinstance(chst, dict) and len(chst) > 2) # makes sense # build Huffman tree hp = MinBinaryHeap(map(lambda (c, f): self.__class__.Node(f, c), chst.items()), lambda x: x.key) while len(hp) > 1: left = hp.pop() right = hp.pop() node = self.__class__.Node(left.key + right.key, None, left, right) hp.push(node) # check tree and prepare for code generation assert (len(hp) == 1) node = hp.pop() assert (node.key == sum(map(lambda x: x[1], chst.items())) and node.value is None) node.key = None # generate Huffman code by traversing Huffman tree que = Queue() que.push(node) while len(que) > 0: node = que.pop() if node.value is not None: assert (isinstance(node.key, str) and isinstance(node.value, str)) chst[node.value] = node.key assert (node.left is None and node.right is None) elif node.key is None: # node is root if node.left: node.left.key = '0' que.push(node.left) if node.right: node.right.key = '1' que.push(node.right) else: assert (isinstance(node.key, str)) if node.left: node.left.key = node.key + '0' que.push(node.left) if node.right: node.right.key = node.key + '1' que.push(node.right) return chst
def main_2(grp, src): vtx = [0] * len(grp) dis = [None] * len(grp) hp = MinBinaryHeap(key=lambda x: x[1]) dis[src] = 0 vtx[src] = 1 for i, w in grp[src]: dis[i] = w hp.push((i, dis[i])) while len(hp) > 0: i, w = hp.pop() if vtx[i] == 1 or dis[i] < w: continue vtx[i] = 1 for j, v in grp[i]: if vtx[j] == 0 and (dis[j] == None or dis[j] > v): dis[j] = v hp.push((j, dis[j])) return sum(dis)
def f4(grp, src): vtx = [0] * len(grp) vtx[src] = 1 dis = [None] * len(grp) dis[src] = 0 hp = MinBinaryHeap(key=lambda x: x[1]) for i, w in grp[src]: dis[i] = w hp.push((i, dis[i])) ret = [] while len(hp) > 0: i, w = hp.pop() if vtx[i] == 1 or w > dis[i]: continue vtx[i] = 1 for j, v in grp[i]: if vtx[j] == 0 and (dis[j] is None or dis[j] > dis[i] + v): dis[j] = dis[i] + v hp.push((j, dis[j])) ret.append(w) return sum(ret)
def main_Dijkstra_2(self, grp, src): # 1) initialize vtx = [0 if i != src else 1 for i in range(len(grp))] dis = [None if i != src else 0 for i in range(len(grp))] pre = [None] * len(grp) hp = MinBinaryHeap(key=lambda x: x[1]) for i, w in grp[src]: dis[i] = w pre[i] = src hp.push((i, dis[i])) # 2) calculate by greedily selecting vertexes from heap while len(hp) > 0: i, w = hp.pop() assert dis[i] is not None and w >= dis[i] if w > dis[i] or vtx[i] != 0: continue vtx[i] = 1 for j, v in grp[i]: if vtx[j] == 0 and (dis[j] is None or dis[j] > dis[i] + v): dis[j] = dis[i] + v pre[j] = i hp.push((j, dis[j])) # 3) build shortest-path tree return dis, pre
def main_Dijkstra_2(self, grp, src): # 1) initialize vtx = [0 if i != src else 1 for i in range(len(grp))] dis = [None if i != src else 0 for i in range(len(grp))] pre = [None] * len(grp) hp = MinBinaryHeap(key=lambda x: x[1]) for i, w in grp[src]: dis[i] = w pre[i] = src hp.push((i, dis[i])) # 2) calculate by greedily selecting vertexes from heap while len(hp) > 0: i, w = hp.pop() assert (dis[i] is not None and w >= dis[i]) if w > dis[i] or vtx[i] != 0: continue vtx[i] = 1 for j, v in grp[i]: if vtx[j] == 0 and (dis[j] is None or dis[j] > dis[i] + v): dis[j] = dis[i] + v pre[j] = i hp.push((j, dis[j])) # 3) build shortest-path tree return dis, pre