class MovingMedian: def __init__(self, window_size=-1): self.window_size = window_size self.median = 0 self.iter = 0 self.history = deque() if window_size > 0 else None self.lower = IndexedHeap() self.upper = IndexedHeap() def update(self, v): if not self.upper.size(): self.upper.push((v, 0)) if self.window_size > 0: self.history.append((v, 0)) self.median = v return self.iter += 1 if self.window_size > 0 and len(self.history) == self.window_size: oldest, i = self.history.popleft() if self.lower.has((-oldest, i)): self.lower.decrease((-oldest, i), (float('-inf'),) * 2) self.lower.pop() elif self.upper.has((oldest, i)): self.upper.decrease((oldest, i), (float('-inf'),) * 2) self.upper.pop() else: raise Exception('oldest value not found {}'.format(oldest)) if v > self.upper.peek()[0]: self.upper.push((v, self.iter)) if self.window_size > 0: self.history.append((v, self.iter)) else: self.lower.push((-v, self.iter)) if self.window_size > 0: self.history.append((v, self.iter)) if self.upper.size() - self.lower.size() > 1: item = self.upper.pop() self.lower.push((-item[0], item[1])) if self.lower.size() - self.upper.size() > 1: item = self.lower.pop() self.upper.push((-item[0], item[1])) if self.upper.size() > self.lower.size(): self.median = self.upper.peek()[0] elif self.lower.size() > self.upper.size(): self.median = -self.lower.peek()[0] else: self.median = (-self.lower.peek()[0] + self.upper.peek()[0]) / 2.0
def minimum_spanning_tree(self, root=0): """ Implementacion del algoritmo de Prim. Da por sentado que esta instancia de Digrafo es un Grafo. Es decir, que una arista esta representada por dos aristas dirigidas del mismo peso. Inicia el algoritmo desde el vertice raiz "root", por defecto = 0. :return Digraph: arbol de tendido minimo dirigido """ # Setup visited = [False] * self.V() # edge_to = {dstVertex: Edge(srcVertex, dstVertex, weight)} edge_to = {} # heap inicializado con vertice raiz del arbol heap = IndexedHeap() heap._push(root, 0) # Execution while heap: v = heap.pop() visited[v] = True for e in self.adj_e(v): if not visited[e.dst]: new_priority = e.weight if e.dst in heap: if new_priority < heap[e.dst]: edge_to[e.dst] = e heap._decreaseKey(e.dst, new_priority) else: edge_to[e.dst] = e heap._push(e.dst, new_priority) # Return tree = Digraph(self.V()) for edge in edge_to.values(): tree.add_edge(edge.src, edge.dst, edge.weight) return tree