Example #1
0
def Prim(V, s):
    """Prim algorithm. Returns list T containing edges of minimum spanning tree and T_sum, the sum of its weights."""
    # initialize structures
    Q = set()
    D = MinHeap()
    P = {}

    # set initial values
    for v in V:
        Q.add(v)
        D[v] = float('inf')
    D[s] = 0
    P[s] = None

    while len(Q) != 0:
        v, _ = D.extract_min()
        Q.remove(v)
        for w, d in v.get_neighbors():
            if w in Q:
                if d < D[w]:
                    D[w] = d
                    P[w] = v

    tree = []
    tree_sum = 0
    for v in P:
        if P[v] is not None:
            tree.append((P[v], v))
            tree_sum += D[v]

    return tree, tree_sum
 def __init__(self, maze_file):
     self.close = dict()
     self.open = MinHeap()
     self.open_dict = dict()
     self.grid = []
     self.start_state = None
     self.goal_state = None
     for i in range(max_size):
         self.grid.append([])
     with open(maze_file, 'r') as f:
         line_row = 0
         for line in f:
             self.grid.append([])
             line = line.rstrip()
             if not line:
                 continue
             if not self.start_state:
                 self.start_state = line_to_coord(line)
                 self.start_state.g = 0
                 continue
             if not self.goal_state:
                 self.goal_state = line_to_coord(line)
                 continue
             for pos in line:
                 self.grid[line_row].append(True if pos == '1' else False)
             line_row += 1
def dijkstra(graph, root):
    vertices = graph.keys()
    n = len(vertices)

    # Initialize the priority queue
    inf = float("inf")
    pq = MinHeap([(v, inf) for v in graph.keys()]) 
    pq.change_priority(root, 0)
    # Other initializations
    parent = collections.defaultdict(lambda: None)
    selected = set()
    cost = collections.defaultdict(lambda: inf)
    cost[root] = 0

    while len(selected) < n:
        u = pq.min()
        du = cost[u] = pq.get_priority(u)
        selected.add(u)
        pq.take_min()
        for (v, w) in graph[u].items():
            if v not in selected and pq.get_priority(v) > du + w:
                pq.change_priority(v, du + w)
                parent[v] = u
    
    return cost, parent
def get_trie(s):
    # get frequencies:
    frequencies = {}
    for c in s:
        if c not in frequencies:
            frequencies[c] = 1
        else:
            frequencies[c] += 1

    # build trie:
    heap = MinHeap()
    for c in frequencies:
        heap.insert(Node(frequencies[c], c))
    while heap.size() > 1:
        left = heap.extractmin()
        right = heap.extractmin()
        assert (left is not None)
        assert (right is not None)
        assert (left.frequency >= 0)
        assert (right.frequency >= 0)
        frequency = left.frequency + right.frequency
        node = Node(frequency)
        node.left = left
        node.right = right
        heap.insert(node)
    return heap.extractmin()
Example #5
0
    def dijkstra(
        self, valor_vertice_origem
    ) -> (Dict[Vertice, DistanciaVerticeOrigem], Dict[Vertice, Vertice]):
        distancia = {}
        pai = {}
        vertice_origem = self.obtem_vertice(valor_vertice_origem)
        if not vertice_origem:
            return None

        fila_min_heap = MinHeap()
        #inicialização
        for vertice in self.vertices.values():
            distancia[vertice] = DistanciaVerticeOrigem(vertice, float("inf"))
            pai[vertice] = None
            fila_min_heap.insere(distancia[vertice])
        #print(f"HEAP: {fila_min_heap}")
        #print(f"Vertice Origem: {vertice_origem.valor}")

        #escreva o código abaixo para preencher as veriaveis distancia e pai adequadamente
        distancia[vertice_origem].distancia = 0
        while fila_min_heap.pos_ultimo_item > 0:
            vertice = self.obtem_vertice(
                fila_min_heap.retira_min().vertice.valor)
            for adjacencia in vertice.adjacencias:
                self.dijkstra_relax(fila_min_heap, vertice, adjacencia,
                                    distancia, pai)

        return distancia, pai
class Calendar(object):
    def __init__(self):
        self.events = MinHeap()
        self.mapper = {}

    def add(self, record):
        self.events.add(record.timestamp)
        if record.timestamp in self.mapper:
            self.mapper[record.timestamp].append(record)
        else:
            self.mapper[record.timestamp] = [record]

    def getlatest(self):
        rec_time = self.events.extractMin()
        rec_list = self.mapper[rec_time]
        # Logic here decides how to handle simultaneous events.
        # Current Implementation - extract departure events first
        record = None
        index = -1
        for idx in range(len(rec_list)):
            if rec_list[idx].event_type == "E":
                index = idx
                break
        if index < 0:
            record = rec_list.pop(0)
        else:
            record = rec_list.pop(index)
        if not len(rec_list):
            del self.mapper[rec_time]
        return record
Example #7
0
def merge_sorted_lists():
    k = 10
    n = 10
    min_value = 0
    max_value = 30
    sorted_lists = generate_sorted_lists(k,n,min_value,max_value)
    sorted_list = SingleLinkedList()
    heap = MinHeap([], 0)
    # fill in the 1st batch
    for i, l in sorted_lists.items():
        heap.add(IdAndValue(i, l.pop(0)))

    while len(sorted_lists) > 0:
        item = heap.pop()
        sorted_list.append(item.get_value())

        list_id = item.get_id()

        if list_id in sorted_lists:
            value = sorted_lists[list_id].pop(0)
            if len(sorted_lists[list_id]) <= 0:
                sorted_lists.pop(list_id)

            heap.add(IdAndValue(list_id, value))

        else:
            list_id, list = sorted_lists.items()[0]
            heap.add(IdAndValue(list_id, list.pop(0)))

            if len(list) <= 0:
                sorted_lists.pop(list_id)
    while not heap.is_empty():
        sorted_list.append(heap.pop())

    print k*n, len(sorted_list), sorted_list
Example #8
0
def Dijkstra(V, s):
    """Dijkstra algorithm. Returns MinHeap D containing minimum distances and dict P containing previous node."""
    # initialize structures
    Q = set()
    D = MinHeap()
    P = {}

    # set initial values
    for v in V:
        Q.add(v)
        D[v] = float('inf')
    D[s] = 0
    P[s] = None

    while len(Q) != 0:
        v, _ = D.extract_min()
        Q.remove(v)
        for w, d in v.get_neighbors():
            new_d = D[v] + d
            if w in Q:
                if new_d < D[w]:
                    D[w] = new_d
                    P[w] = v

    return D, P
Example #9
0
def heap_sort(items):
    heap = MinHeap(items)
    sorted_list = []

    for i in xrange(len(items)):
        sorted_list.append(heap.remove_min())

    return sorted_list
Example #10
0
def k_smallest(arr, k):
    h = MinHeap()
    for item in arr:
        h.insert(item)
    for i in range(k):
        smallest = h.extract()
        print(smallest)
    return
Example #11
0
def test1():
    minhp = MinHeap()
    for idx in range(10):
        minhp.add(idx + 1)
        minhp.add(20 - idx)
    minhp.printer()

    for idx in range(20):
        print minhp.extractMin()
def single_item_test():
    h = MinHeap()
    h.insert(1)
    assert h.heap_data[0] == 1
    assert_size(h, 1)

    elem = h.extract()
    assert elem == 1
    assert_size(h, 0)
Example #13
0
def test_exch(count):
    """Test exchange method."""
    heap = MinHeap()
    _ = [heap.insert(randint(0, 100)) for i in range(MAX_ITER)]
    pos_a = randint(0, len(heap.heap) - 1)
    val_a = heap.heap[pos_a]
    pos_b = randint(0, len(heap.heap) - 1)
    val_b = heap.heap[pos_b]
    heap.exch(val_a, val_b)
    assert heap.heap[pos_a] == val_b and heap.heap[pos_b] == val_a
Example #14
0
def sort_k_sorted(array, k):
    sorted = []
    min_heap = MinHeap(array[:k + 2])

    for i in range(len(array)):
        sorted.append(min_heap.extract_min())
        if i + k + 2 < len(array):
            min_heap.insert(array[i + k + 2])

    return sorted
Example #15
0
def heapSort(arr):
    """
    Sorts an array by creating a heap and continually extracting minimums.
    Array is not sorted in place.
    :type arr: List[]
    :rtype: List[]
    """
    heap = MinHeap()
    heap.createMinHeap(arr)
    return heap.extractAll()
Example #16
0
    def test_insere(self):
        arr_test = [1, -8, -11, -14]
        arr_heap_esperado = [
            [None, -12, -9, -6, -4, -3, -5, -2, -1, 1],
            [None, -12, -9, -6, -8, -3, -5, -2, -1, -4],
            [None, -12, -11, -6, -9, -3, -5, -2, -1, -4],
            [None, -14, -12, -6, -9, -3, -5, -2, -1, -4],
        ]

        #testa inserção no heap vazio
        for val_inserir in arr_test:
            objHeap = MinHeap()
            objHeap.insere(val_inserir)
            self.assertListEqual(
                [None, val_inserir], objHeap.arr_heap,
                f"Inserção incorreta ao inserir o valor {val_inserir} no heap {[None,12,9,6,4,3,5,2,1]}, esperado: {[None,val_inserir]} obtido: {objHeap.arr_heap}"
            )

        for i, val_inserir in enumerate(arr_test):
            objHeap = MinHeap()
            objHeap.arr_heap = [None, -12, -9, -6, -4, -3, -5, -2, -1]
            objHeap.insere(val_inserir)
            self.assertListEqual(
                arr_heap_esperado[i], objHeap.arr_heap,
                f"Inserção incorreta ao inserir o valor {val_inserir} no heap {[None,12,9,6,4,3,5,2,1]}, esperado: {arr_heap_esperado[i]} obtido: {objHeap.arr_heap}"
            )
Example #17
0
 def dijkstra_relax(self, fila_min_heap: MinHeap, vertice_u: Vertice,
                    vertice_v: Vertice,
                    distancia: Dict[Vertice, DistanciaVerticeOrigem],
                    pai: Dict[Vertice, Vertice]):
     distancia_aresta = vertice_u.adjacencias[vertice_v]
     if distancia[vertice_v].distancia > (distancia[vertice_u].distancia +
                                          distancia_aresta):
         distancia[vertice_v].distancia = distancia[
             vertice_u].distancia + distancia_aresta
         pai[vertice_v] = vertice_u
         fila_min_heap.insere(distancia[vertice_v])
Example #18
0
 def dijkstra_relax(self, fila_min_heap: MinHeap, vertice_u: Vertice,
                    vertice_v: Vertice,
                    distancia: Dict[Vertice, DistanciaVerticeOrigem],
                    pai: Dict[Vertice, Vertice]):
     dist = distancia[vertice_u].distancia
     vert = vertice_u.adjacencias
     dist = dist + vert[vertice_v]
     if distancia[vertice_v].distancia > dist:
         distancia[vertice_v].distancia = dist
         pai[vertice_v] = vertice_u
         fila_min_heap.insere(distancia[vertice_v])
Example #19
0
def heapFullTest():
    """
    Various tests for Heap class, using both MinHeaps and MaxHeaps, including sorting and random operations.
    """
    print("Testing MinHeap: sorting")
    for i in range(1, 21):
        if heapRandomSort(250, True):
            print "Test", i, "successful"
        else:
            print "Test", i, "failed"

    print("\nTesting MaxHeap: sorting")
    for i in range(1, 21):
        if heapRandomSort(250, False):
            print "Test", i, "successful"
        else:
            print "Test", i, "failed"

    print("\nTesting MinHeap: general")
    for i in range(1, 21):
        if heapRandomTest(250, True):
            print "Test", i, "successful"
        else:
            print "Test", i, "failed"

    print("\nTesting MaxHeap: general")
    for i in range(1, 21):
        if heapRandomTest(250, False):
            print "Test", i, "successful"
        else:
            print "Test", i, "failed"

    print("\nTesting MinHeap: other operations")
    ar = [1, 4, 501, -200, 32, 7, 65, -1, 20000, -34, 17]
    min_heap = MinHeap()
    min_heap.createMinHeap(ar)

    print min_heap.extractMin()
    print min_heap.extractMin()
    print min_heap.extractMin()

    max_heap = MaxHeap()
    max_heap.createMaxHeap(ar)

    print max_heap.extractMax()
    print max_heap.extractMax()
    print max_heap.extractMax()

    print "Max: ar", max(
        ar), "min_heap", min_heap.maximum(), "max_heap", max_heap.maximum()
    print "Min: ar", min(
        ar), "min_heap", min_heap.minimum(), "max_heap", max_heap.minimum()
Example #20
0
    def test_empty(self):
        mh = MinHeap()
        self.assertTrue(mh.empty())

        mh.append(1)
        self.assertFalse(mh.empty())

        mh.pop()
        self.assertTrue(mh.empty())
def incomplete_tree_test():
    h = MinHeap()
    h.insert(2)
    h.insert(1)
    assert h.heap_data[0] == 1
    assert h.heap_data[1] == 2
    assert_size(h, 2)

    elems = []
    elems.append(h.extract())
    elems.append(h.extract())
    assert elems == [1, 2]
    assert_size(h, 0)
Example #22
0
def heap_sort(arr):

    sorted_arr = []

    min_heap = MinHeap(array=arr)

    for i in range(len(arr)):

        sorted_arr.append(min_heap.extract_min())
        
    for i in range(len(sorted_arr)):

        arr.append(sorted_arr[i])
Example #23
0
def sort(array):
    heap = MinHeap()
    for i in array:
        heap.push(i)

    out = []
    while True:
        try:
            out.append(heap.pop())
        except:
            break

    return out
Example #24
0
class PriorityQueue:
	
	def __init__(self):
		self.heap = MinHeap()
	
	def enqueue(self, priority, item):
		self.heap.push(PriorityQueueItem(priority, item))
	
	def dequeue(self):
		try:
			return self.heap.pop().value
		except:
			return None
Example #25
0
    def BFS(self, v):
        """ Runs breadth-first search from the source vertex v. Returns a matrix with distances from v, or None if v does not exist. """
        if v >= self.vertexCount():
            return None  # can't be run; vertex doesn't exist

        # initialize the vertex queue, the "visited" set s, and the distances from v
        q = MinHeap()
        s = set()
        distance = [float("inf")] * self.vertexCount()

        # insert the source vertex into q and set its distance as 0
        q.insert(KeyValuePair(0, v))
        s.add(v)
        distance[v] = 0

        # loop through all vertices, in order of distance from v, relaxing edges out of current vertex
        kvp = q.extractMin()
        while kvp:
            v = kvp.value
            d = kvp.key

            # relax all edges out of current vertex v
            edges = self._adj[v]
            for e in edges:
                if e.dest not in s:
                    s.add(e.dest)
                    distance[e.dest] = d + 1
                    q.insert(KeyValuePair(distance[e.dest], e.dest))

            # get next-lowest distance vertex
            kvp = q.extractMin()

        return distance
Example #26
0
def prim(graph, root):
    vertices = graph.keys()
    n = len(vertices)

    # Initialize the priority queue
    inf = float("inf")
    pq = MinHeap([(v, inf) for v in graph.keys()])
    pq.change_priority(root, 0)
    # Other initializations
    parent = collections.defaultdict(lambda: None)
    selected = set()
    cost = 0
    mst = []

    while len(selected) < n:
        u = pq.take_min()
        selected.add(u)
        for (v, w) in graph[u].items():
            if not v in selected and w < pq.get_priority(v):
                pq.change_priority(v, w)
                parent[v] = u
        pu = parent[u]
        if pu != None:
            mst.append((min(u, pu), max(u, pu)))
            cost += graph[u][pu]

    return cost, mst
Example #27
0
    def test_len(self):
        mh = MinHeap()
        self.assertTrue(len(mh) == 0)

        mh.append(1)
        self.assertTrue(len(mh) == 1)

        mh.append(1)
        self.assertTrue(len(mh) == 2)

        mh.pop()
        self.assertTrue(len(mh) == 1)

        mh.pop()
        self.assertTrue(len(mh) == 0)
Example #28
0
def sort_k_sorted(arr, k):
    ans = []
    h = MinHeap()
    for i in range(k + 1):
        h.insert(arr[i])
    for i in range(k + 1, len(arr)):
        smallest = h.extract()
        ans.append(smallest)
        h.insert(arr[i])
    while not h.is_empty():
        smallest = h.extract()
        ans.append(smallest)
    return ans
Example #29
0
    def dijkstra_relax(self, fila_min_heap: MinHeap, vertice_u: Vertice,
                       vertice_v: Vertice,
                       distancia: Dict[Vertice, DistanciaVerticeOrigem],
                       pai: Dict[Vertice, Vertice]):
        '''
		print(f"U: {vertice_u.obtem_valor()} | V: {vertice_v.obtem_valor()}")
		print(distancia)
		print(pai)
		print(fila_min_heap)
		'''
        #"vertice_u.adjacencias[vertice_v]" -> peso da aresta (y,v).
        if distancia[vertice_v].distancia > (distancia[vertice_u].distancia +
                                             vertice_u.adjacencias[vertice_v]):
            distancia[vertice_v].distancia = (distancia[vertice_u].distancia +
                                              vertice_u.adjacencias[vertice_v])
            pai[vertice_v] = vertice_u
            fila_min_heap.insere(distancia[vertice_v])
Example #30
0
def kLargestElement(arr, k):
    minH = MinHeap(arr[:k])
    minH.convertToHeap()

    for x in arr[k:]:
        min_ele = minH.getMin()
        if min_ele < x:
            minH.replaceMin(x)

    return minH.getMin()
Example #31
0
class Median:
    def __init__(self):
        self.h_low = MaxHeap()
        self.h_high = MinHeap()

    def add_element(self, value):
        if self.h_low.heap_size == 0 or value < self.h_low.max():
            self.h_low.insert(value)
            if self.h_low.heap_size - self.h_high.heap_size > 1:
                self.h_high.insert(self.h_low.extract_max())
        else:
            self.h_high.insert(value)
            if self.h_high.heap_size - self.h_low.heap_size > 1:
                self.h_low.insert(self.h_high.extract_min())

    def get_median(self):
        if (self.h_low.heap_size + self.h_high.heap_size) % 2 == 0:
            return self.h_low.max(), self.h_high.min()
        else:
            if self.h_low.heap_size > self.h_high.heap_size:
                return self.h_low.max()
            else:
                return self.h_high.min()

    def get_maxheap_elements(self):
        return self.h_low.heap

    def get_minheap_elements(self):
        return self.h_high.heap
Example #32
0
    def cria_arv_geradora_minima(
            self, valor_vertice_inicial) -> Dict[Vertice, Vertice]:
        pai = {}
        set_ja_explorado = set()
        peso = {}
        vertice_inicial = self.obtem_vertice(valor_vertice_inicial)
        if not vertice_inicial:
            return None

        fila_min_heap = MinHeap()
        for vertice in self.vertices.values():
            pai[vertice] = None
            peso[vertice] = PesoVertice(vertice, float("inf"))

        peso[vertice_inicial].peso = 0
        fila_min_heap.insere(peso[vertice_inicial])
        #print(f"HEAP: {fila_min_heap}")
        #print(f"Vertice Origem: {vertice_inicial.valor}")
        #print(f"HEAP vertice origem: {fila_min_heap.retira_min().vertice_destino.valor}")

        while len(fila_min_heap.arr_heap) > 1:
            vertice = self.obtem_vertice(
                fila_min_heap.retira_min().vertice_destino.valor)
            set_ja_explorado.add(vertice)
            for adjacencia in vertice.adjacencias:
                distancia_aresta = vertice.adjacencias[adjacencia]
                if adjacencia not in set_ja_explorado and distancia_aresta < peso[
                        adjacencia].peso:
                    pai[adjacencia] = vertice
                    peso[adjacencia].peso = distancia_aresta
                    fila_min_heap.insere(peso[adjacencia])

        return pai
Example #33
0
def prim(graph, root):
    vertices = graph.keys()
    n = len(vertices)

    # Initialize the priority queue
    inf = float("inf")
    pq = MinHeap([(v, inf) for v in graph.keys()]) 
    pq.change_priority(root, 0)
    # Other initializations
    parent = collections.defaultdict(lambda: None)
    selected = set()
    cost = 0
    mst = []

    while len(selected) < n:
        u = pq.take_min()
        selected.add(u)
        for (v, w) in graph[u].items():
            if not v in selected and w < pq.get_priority(v):
                pq.change_priority(v, w)
                parent[v] = u
        pu = parent[u]
        if pu != None:
            mst.append( (min(u,pu), max(u,pu)) )
            cost += graph[u][pu]
    
    return cost, mst
Example #34
0
def get_static_top_k(nums, k):
    """
    get top-K of static data
    :param nums:
    :param k:
    :return:
    """
    if len(nums) <= k:
        return nums
    min_h = MinHeap(nums[:k], k)  # one time use
    min_h.build_heap()
    # compare data with heap top
    for n in range(k, len(nums)):
        tmp = min_h.get_top()
        if nums[n] > tmp:  # if larger, change data
            min_h.remove_top()
            min_h.insert(nums[n])
    return min_h.get_data()
class MedianMaintenance:
    def __init__(self):
        self.hlow_heap = MaxHeap()
        self.hhigh_heap = MinHeap()

    def compute_median(self, i):
        self.insert_heap(i)
        self.balance_heap()
        return self.median()

    def balance_heap(self):
        if self.hhigh_heap.size - self.hlow_heap.size > 1 : # rebalance heap to keep it balanced
            high = self.hhigh_heap.extract_min()
            self.hlow_heap.insert(high)
        elif self.hlow_heap.size - self.hhigh_heap.size > 1:
            low = self.hlow_heap.extract_max()
            self.hhigh_heap.insert(low)

    def insert_heap(self, i):
        if self.hlow_heap.is_empty():
            low = None
        else:
            low = self.hlow_heap.peek_max()
        if self.hhigh_heap.is_empty():
            high = None
        else:
            high = self.hhigh_heap.peek_min()
        if low is None or i < low:
            self.hlow_heap.insert(i)
        elif high is not None and i > high:
            self.hhigh_heap.insert(i)
        else:# i wedged inbetween insert in first heap by default
            self.hlow_heap.insert(i)

    def median(self):
        if self.hhigh_heap.size - self.hlow_heap.size == 1:
            return self.hhigh_heap.peek_min()
        else:# default choice when hlow is bigger/same size as hhigh
            return self.hlow_heap.peek_max()
    def test_min_heap_sorting(self):

        # seed for consistant testing and reproductibility
        for seed in xrange(10):
            random.seed(seed)

            heap = MinHeap()
            shuffled_nums = [int(random.random() * 20 - 10) for _ in xrange(1000)]
            nums = sorted(shuffled_nums)
            for n in shuffled_nums:
                heap.insert(n)

            for n in nums:
                self.assertEqual(n, heap.pop())

            heap.heapify(shuffled_nums)

            for n in nums:
                self.assertEqual(n, heap.pop())
Example #37
0
class SinglePercentileTracker(object):
    ''' A class that tracks a single percentile'''
    def __init__(self, percentile):
        self.percentile_tracked = percentile
        self.lheap = MaxHeap()
        self.rheap = MinHeap()
        self.size = 0
        self.percentile = None

    def add(self, num):
        # An addition to a list is O(log n) since look up is O(1)
        # insertions are O(log n), and worst case pop is O(log n)
        # and everything is done a constant number of times. In these
        # cases, n is the size of the larger of the two heaps
        self.size += 1
        n = (self.percentile_tracked / 100.0) * (self.size + 1)
        # The left heap should always be the floor of n, so we have the
        # floor(n)th ranked node as the max node in the left heap, and the
        # min node of the right heap will be the nth+1 ranked node.
        lsize = int(math.floor(n))
        # Push the num on to the proper heap
        if num > self.percentile:
            self.rheap.push(num)
        else:
            self.lheap.push(num)

        # if the left heap isn't the right size, push or pop the nodes
        # to make sure it is.
        if self.lheap.size() < lsize:
            self.lheap.push(self.rheap.pop())
        elif self.lheap.size() > lsize:
            self.rheap.push(self.lheap.pop())
        # Take the integer part of n and grab the nth and nth+1
        # ranked nodes. Then take the nth node as the base
        # and add the fractional part of n * nth+1 ranked node to get a
        # weighted value between the two. This is your percentile.
        ir = int(n)
        fr = n - ir
        low_data = self.lheap.get(0)
        high_data = self.rheap.get(0)
        self.percentile = fr * (high_data - low_data) + low_data

    def add_list(self, lst):
        # Add list is O(k * log n) where k is len(lst) and n is
        # the size of the larger of the two heaps
        for l in lst:
            self.add(l)
 def shortest_paths(self, v):
     '''
     Computes the shortest path distances from a source vertex to all other
     vertices using Dijkstra's algorithm.
     '''
     processed = {}  # mapping of processed vertices to geodesic distance
     candidates = {} # mapping of candidate vertices to their Dijkstra scores; exists for convenience of O(1) lookups
     trace = []      # stores edges in order of processing; used to extract shortest paths
     def dijkstra_score(src, dest):
         return processed[src] + self.getWeight(src, dest)
     # Initialize Dijkstra scores
     for n in self.nodes:
         if n == v:
             processed[n] = 0
             for dest in self.edges[n]:
                 score = dijkstra_score(n, dest)
                 if dest not in candidates or score < candidates[dest]:
                     candidates[dest] = score
         else:
             if n not in candidates:
                 candidates[n] = float('inf')
     # heapify node/score tuples, provide comparison key
     unprocessed = MinHeap(list(candidates.items()), lambda x:x[1])
     # compute shortest paths
     while not unprocessed.is_empty():
         n,s = unprocessed.extract_min()
         processed[n] = s
         candidates.pop(n)
         if len(trace) == 0:
             trace.append(Edge(v, n)) # Investigate KeyError when using WeightedEdge
         else:
             src = trace[-1].getDestination()
             trace.append(Edge(src, n)) # Investigate KeyError when using WeightedEdge
         for dest in self.edges[n]:
             if dest in candidates:
                 unprocessed.delete((dest, candidates[dest]))
                 score = dijkstra_score(n, dest)
                 best = min(candidates[dest], score)
                 candidates[dest] = best
                 unprocessed.insert((dest, best))
     return (processed, PathFinder(trace))
def median_maintenance(data):
    yield data[0]
    if data[0] < data[1]:
        h_high, h_low = MinHeap([data[1]]), MaxHeap([data[0]])
    else:
        h_high, h_low = MinHeap([data[0]]), MaxHeap([data[1]])
    median = h_low.extract_max()
    h_low.insert(median)
    yield median
    for k in data[2:]:
        lower, upper = h_low.extract_max(), h_high.extract_min()
        if k <= lower:
            h_low.insert(k)
        else:
            h_high.insert(k)
        h_low.insert(lower)
        h_high.insert(upper)
        if abs(h_high.size() - h_low.size()) > 1:
            if h_high.size() > h_low.size():
                h_low.insert(h_high.extract_min())
            else:
                h_high.insert(h_low.extract_max())
        if (h_high.size() + h_low.size()) % 2 == 0 or h_low.size() > h_high.size():
            median = h_low.extract_max()
            h_low.insert(median)
            yield median
        else:
            median = h_high.extract_min()
            h_high.insert(median)
            yield median
 def __init__(self):
     self.hlow_heap = MaxHeap()
     self.hhigh_heap = MinHeap()
Example #41
0
def least_cost_path(graph,start,dest,cost):
    """Find and return the least cost path in graph from start vertex to dest vertex.
    Efficiency: If E is the number of edges, the run-time is
      O( E log(E) ).
    Args:
      graph (Graph): The digraph defining the edges between the
        vertices.
      start: The vertex where the path starts. It is assumed
        that start is a vertex of graph.
      dest:  The vertex where the path ends. It is assumed
        that start is a vertex of graph.
      cost:  A function, taking the two vertices of an edge as
        parameters and returning the cost of the edge. For its
        interface, see the definition of cost_distance.
    Returns:
      list: A potentially empty list (if no path can be found) of
        the vertices in the graph. If there was a path, the first
        vertex is always start, the last is always dest in the list.
        Any two consecutive vertices correspond to some
        edge in graph.
    >>> graph = Graph({1,2,3,4,5,6}, [(1,2), (1,3), (1,6), (2,1),
            (2,3), (2,4), (3,1), (3,2), (3,4), (3,6), (4,2), (4,3),
            (4,5), (5,4), (5,6), (6,1), (6,3), (6,5)])
    >>> weights = {(1,2): 7, (1,3):9, (1,6):14, (2,1):7, (2,3):10,
            (2,4):15, (3,1):9, (3,2):10, (3,4):11, (3,6):2,
            (4,2):15, (4,3):11, (4,5):6, (5,4):6, (5,6):9, (6,1):14,
            (6,3):2, (6,5):9}
    >>> cost = lambda u, v: weights.get((u, v), float("inf"))
    >>> least_cost_path(graph, 1,5, cost)
    [1, 3, 6, 5]
    """
    reached = {}
    runners = MinHeap()
    distances = {}
    # add the starting vertices to the runners
    runners.add( 0,(start,start))

    while runners and dest not in reached:
        (val,(prev, goal)) = runners.pop_min()
        #print('[',prev,goal,val,']')
        if goal in reached:
            continue

        if goal not in reached:
            reached[goal] = prev
            distances[goal] = val
            # check the neighbours and add to the runners
            for succ in graph.neighbours(goal):
                runners.add( val + cost(goal,succ),(goal, succ))

            if goal == dest:
                break

    # return empty list if dest cannot be reached
    if dest not in reached:
        return []

    path = []
    vertice = dest
    while True:
        path.append(vertice)
        #print(path)
        if path[-1] == start:
            break
        vertice = reached[vertice]

    # reverse list and output it
    path.reverse()
    return path
 def setUp(self):
     self.heap = MinHeap()
Example #43
0
def test_heap():
    """Pytest fixture."""
    heap = MinHeap()
    for _ in range(MAX_ITER):
        heap.insert(randint(0, 100))
    return heap
class TestMinHeap(unittest.TestCase):

    def setUp(self):
        self.heap = MinHeap()

    def test_basic_initialization_and_repr(self):
        self.assertEqual(repr(self.heap), '[]')

    def test_insert(self):
        self.heap.insert(4)
        self.assertEqual(repr(self.heap), '[4]')
        self.assertEqual(self.heap.size, 1)
        self.heap.insert(4)
        self.assertEqual(repr(self.heap), '[4, 4]')
        self.assertEqual(self.heap.size, 2)
        self.heap.insert(6)
        self.assertEqual(repr(self.heap), '[4, 4, 6]')
        self.assertEqual(self.heap.size, 3)
        self.heap.insert(1)
        self.assertEqual(repr(self.heap), '[1, 4, 6, 4]')
        self.assertEqual(self.heap.size, 4)
        self.heap.insert(3)
        self.assertEqual(repr(self.heap), '[1, 3, 6, 4, 4]')
        self.assertEqual(self.heap.size, 5)

    def test_get_min(self):
        self.assertEqual(self.heap.get_min(), None)
        self.heap.insert(4)
        self.assertEqual(self.heap.get_min(), 4)
        self.heap.insert(7)
        self.assertEqual(self.heap.get_min(), 4)
        self.heap.insert(2)
        self.assertEqual(self.heap.get_min(), 2)
        self.heap.insert(-1)
        self.assertEqual(self.heap.get_min(), -1)

    def test_extract_min(self):
        self.heap.insert(4)
        self.heap.insert(5)
        self.heap.insert(7)
        self.heap.insert(2)
        self.heap.insert(-1)
        self.assertEqual(self.heap.extract_min(), -1)
        self.assertEqual(self.heap.extract_min(), 2)
        self.assertEqual(self.heap.extract_min(), 4)
        self.assertEqual(self.heap.extract_min(), 5)
        self.assertEqual(self.heap.extract_min(), 7)
        self.assertEqual(self.heap.extract_min(), None)

    def test_build_heap(self):
        self.heap.build_heap([4, 4, 6, 1, 3])
        self.assertEqual(repr(self.heap), '[1, 3, 6, 4, 4]')
Example #45
0
from heap import MinHeap
from random import randint
from time import clock

# TODO use my mergesort for comparison?

fill = []
for i in range(30):
    x = randint(0,10000)
    fill.append((x,x))
test = MinHeap(fill)
print(test.heap)

res = []
for i in range(test.size):
    res.append(test.pop()[1])
print(test.heap)

fill.sort(key=lambda tup : tup[0])
res2 = list(map(lambda x : x[0], fill))
print("Expect:",res2)
print("Get:   ",res)

print("Now for excitement!")
heapElapsed = 0
listElapsed = 0
err = False
for i in range(10000):
    fill = []
    for i in range(100):
        x = randint(0,10000)
Example #46
0
from heap import MinHeap, MaxHeap
from math import floor
import sys
#invariant: maintain min heap size = floor(n/2), median is the the max in max heap
with open('Median.txt') as f:
#with open('median10_test.txt') as f:
	a = [int(l) for l in f]
	minHeap = MinHeap([])
	maxHeap = MaxHeap([])
	medians = []
	for i in range(len(a)):
		if minHeap.size() == 0 and maxHeap.size() == 0:
			maxHeap.insert(a[i])
		else:
			if a[i] < maxHeap.top():
				maxHeap.insert(a[i])
			else:
				minHeap.insert(a[i])
			if minHeap.size() > floor((i+1)/2):
				maxHeap.insert(minHeap.extract())
			elif minHeap.size() < floor((i+1)/2):
				minHeap.insert(maxHeap.extract())
		medians.append(maxHeap.top())
	print(sum(medians)%10000)
Example #47
0
 def __init__(self, percentile):
     self.percentile_tracked = percentile
     self.lheap = MaxHeap()
     self.rheap = MinHeap()
     self.size = 0
     self.percentile = None