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
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 test2(): minhp = MinHeap() print minhp.isEmpty() minhp.add(1) minhp.add(1) minhp.add(1) minhp.printer() print minhp.extractMin() print minhp.extractMin()
def encode(self, symbols=None): """ Huffman-encoding symbols symbols: [(w1, s1), (w2, s2), ..., (wn, sn)] where wi, si are ith symbol's weight/freq """ pq = MinHeap() symbols = copy.deepcopy(symbols) symbols = [(s[0], HuffmanNode(value=s[1], left=None, right=None)) for s in symbols] # initialize symbols to nodes pq.heapify(symbols) while len(symbols) > 1: l, r = pq.pop(symbols), pq.pop(symbols) lw, ls, rw, rs = l[0], l[1], r[0], r[1] # left weight, left symbol, right wreight, right symbol parent = HuffmanNode(value=None, left=ls, right=rs) pq.add(heap=symbols, item=(lw+rw, parent)) self._root = pq.pop(symbols)[1] # tree is complete, pop root node self._symbol2codes() # create symbol: code dictionary self._maxDepth = len(max(self._codes.values(), key=len)) # max depth self._minDepth = len(min(self._codes.values(), key=len)) # min depth self._avgDepth = sum([len(d) for d in self._codes.values()]) / len(self._codes) # mean depth
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
def C2W3(): """Median Maintain""" from heap import MinHeap, MaxHeap MinHeap = MinHeap() MaxHeap = MaxHeap() medians = [] heaplow, heaphigh = [], [] lowmax, highmin = float('-inf'), float('inf') with open('Median.txt') as file: for line in file: item = int(line) lenlow, lenhigh = len(heaplow), len(heaphigh) while True: if lenlow > lenhigh: if item >= lowmax: MinHeap.add(heaphigh, item) highmin = heaphigh[0] break if item < lowmax: returnitem = MaxHeap.popadd(heaplow, item) MinHeap.add(heaphigh, returnitem) lowmax = heaplow[0] highmin = heaphigh[0] break if lenlow <= lenhigh: if item <= highmin: MaxHeap.add(heaplow, item) lowmax = heaplow[0] break if item > highmin: returnitem = MinHeap.popadd(heaphigh, item) MaxHeap.add(heaplow, returnitem) lowmax = heaplow[0] highmin = heaphigh[0] break medians.append(lowmax) print('item', item, 'lowmax', lowmax, 'highmin', highmin) return sum(medians), len(medians)
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 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