Esempio n. 1
0
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
Esempio n. 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