def test_against_python_priority_queue_randomly(self): TRIALS = 10000 ITER_OPS = 100 RANGE = 10000 que = queue.PriorityQueue() heap = binomialheap.BinomialHeap() size = 0 for i in range(TRIALS): if i % 300 == 0: print("Progress: {:.0%}".format(float(i) / TRIALS)) op = random.randrange(100) if op < 1: # Clear heap.check_structure() for _ in range(size): self.assertEqual(heap.dequeue(), que.get(False)) size = 0 elif op < 2: # Peek heap.check_structure() if size > 0: val = que.get(False) self.assertEqual(heap.peek(), val) que.put(val) elif op < 70: # Enqueue/merge merge = not (op < 60) sink = binomialheap.BinomialHeap() if merge else heap n = random.randint(1, ITER_OPS) for _ in range(n): val = random.randrange(RANGE) que.put(val) sink.enqueue(val) if merge: heap.merge(sink) self.assertEqual(len(sink), 0) size += n elif op < 100: # Dequeue n = min(random.randint(1, ITER_OPS), size) for _ in range(n): self.assertEqual(heap.dequeue(), que.get(False)) size -= n else: raise AssertionError() self.assertEqual(que.qsize(), size) self.assertEqual(len(heap), size) self.assertEqual(que.empty(), size == 0) self.assertEqual(heap.empty(), size == 0)
def test_size_7(self): h = binomialheap.BinomialHeap() h.enqueue(2) h.enqueue(7) h.enqueue(1) h.enqueue(8) h.enqueue(3) h.check_structure() h.enqueue(1) h.enqueue(4) h.check_structure() self.assertEqual(7, len(h)) self.assertEqual(1, h.dequeue()) self.assertEqual(6, len(h)) self.assertEqual(1, h.dequeue()) self.assertEqual(5, len(h)) self.assertEqual(2, h.dequeue()) self.assertEqual(4, len(h)) self.assertEqual(3, h.dequeue()) self.assertEqual(3, len(h)) h.check_structure() self.assertEqual(4, h.dequeue()) self.assertEqual(2, len(h)) self.assertEqual(7, h.dequeue()) self.assertEqual(1, len(h)) self.assertEqual(8, h.dequeue()) self.assertEqual(0, len(h)) h.check_structure()
def test_size_1(self): h = binomialheap.BinomialHeap() h.enqueue(3) h.check_structure() self.assertEqual(1, len(h)) self.assertEqual(3, h.peek()) self.assertEqual(3, h.dequeue()) h.check_structure() self.assertEqual(0, len(h))
def buildheap(self): ''' 构造19.2-2的形式二项堆 ''' heap = bh.BinomialHeap() root1 = bh.BinomialHeapNode(25, 0) # 根结点 heap.head = root1 root2 = bh.BinomialHeapNode(12, 2) root3 = bh.BinomialHeapNode(6, 4) heap.head.sibling = root2 root2.sibling = root3 root2.child = bh.BinomialHeapNode(37, 1, root2) root2.child.sibling = bh.BinomialHeapNode(18, 0, root2) root2.child.child = bh.BinomialHeapNode(41, 0, root2.child) root3.child = bh.BinomialHeapNode(10, 3, root3) root3.child.sibling = bh.BinomialHeapNode(8, 2, root3) root3.child.sibling.sibling = bh.BinomialHeapNode(14, 1, root3) root3.child.sibling.sibling.sibling = bh.BinomialHeapNode(29, 0, root3) node = root3.child node.child = bh.BinomialHeapNode(16, 2, node) node.child.sibling = bh.BinomialHeapNode(28, 1, node) node.child.sibling.sibling = bh.BinomialHeapNode(13, 0, node) node = root3.child.sibling node.child = bh.BinomialHeapNode(11, 1, node) node.child.sibling = bh.BinomialHeapNode(17, 0, node) node.child.child = bh.BinomialHeapNode(27, 0, node.child) node = root3.child.sibling.sibling node.child = bh.BinomialHeapNode(38, 0, node) node = root3.child.child node.child = bh.BinomialHeapNode(26, 1, node) node.child.sibling = bh.BinomialHeapNode(23, 0, node) node.child.child = bh.BinomialHeapNode(42, 0, node.child) node = root3.child.child.sibling node.child = bh.BinomialHeapNode(77, 0, node) return heap
def test_against_list_randomly(self): TRIALS = 1000 MAX_SIZE = 300 RANGE = 1000 heap = binomialheap.BinomialHeap() for _ in range(TRIALS): size = random.randrange(MAX_SIZE) values = [random.randrange(RANGE) for _ in range(size)] for val in values: heap.enqueue(val) values.sort() for val in values: self.assertEqual(val, heap.dequeue()) self.assertTrue(heap.empty()) heap.clear()
import binomialheap import binary_heap import random import time if __name__ == '__main__': L = list(range(1, int(1E+8))) N = list(range(1, 20)) K = list(range(1, 11)) bryheap = binary_heap.MinHeap() binheap = binomialheap.BinomialHeap() for k in K: for n in N: b = 2**n A = random.sample(L, b) start_time = time.process_time() bryheap.add_element(A) print('%d, %s, %d, %d, %2.8f' % (k, 'binary', b, n, time.process_time() - start_time)) start_time = time.process_time() for q in A: binheap.insert(q)
def main(): ITERATIONS = 10000 que = queue.PriorityQueue() heap = binomialheap.BinomialHeap() length = 0 for i in range(ITERATIONS): if i % 300 == 0: print("Progress: {:.0%}".format(float(i) / ITERATIONS)) op = random.randint(0, 99) if op < 1: # Clear heap.check_structure() for j in range(length): if heap.dequeue() != que.get(False): raise AssertionError() if not que.empty(): raise AssertionError() length = 0 elif op < 2: # Peek heap.check_structure() if length > 0: val = que.get(False) if heap.peek() != val: raise AssertionError() que.put(val) elif op < 60: # Add n = random.randint(1, 100) for j in range(n): val = random.randint(0, 9999) que.put(val) heap.enqueue(val) length += n elif op < 70: # Merge n = random.randint(1, 100) temp = binomialheap.BinomialHeap() for j in range(n): val = random.randint(0, 9999) que.put(val) temp.enqueue(val) heap.merge(temp) if len(temp) != 0: raise AssertionError() length += n elif op < 100: # Remove n = min(random.randint(1, 100), length) for j in range(n): if heap.dequeue() != que.get(False): raise AssertionError() length -= n else: raise AssertionError() if len(heap) != length: raise AssertionError() print("Test passed")
def note(self): ''' Summary ==== Print chapter19.2 note Example ==== ```python Chapter19_2().note() ``` ''' print('chapter19.2 note as follow') print('19.2 对二项堆的操作') print('创建一个新二项堆') print(' 为了构造一个空的二项堆') print('寻找最小关键字') print(' 过程BINOMIAL-HEAP-MINIMUM返回一个指针,', '指向包含n个结点的二项堆H中具有最小关键字的结点', '这个实现假设没有一个关键字为无穷') print(' 因为一个二项堆是最小堆有序的,故最小关键字必在根结点中') print(' 过程BINOMIAL-HEAP-MINIMUM检查所有的根(至多[lgn]+1),将当前最小者存于min中') print(' 而将指向当前最小者的指针存于y之中。BINOMIAL-HEAP-MINIMUM返回一个指向具有关键字1的结点的指针') print(' 因为至多要检查[lgn]+1个根,所以BINOMIAL-HEAP-MINIMUM的运行时间为O(lgn)') print('合并两个二项堆') print(' 合并两个二项堆的操作可用作后面大部分操作的一个子程序。') print(' 过程BINOMIAL-HEAP-UNION反复连接根结点的度数相同的各二项树') print(' LINK操作将以结点y为根的Bk-1树与以结点z为根的Bk-1树连接起来') print(' BINOMIAL-HEAP-UNION搓成合并H1和H2并返回结果堆,在合并过程中,同时也破坏了H1和H2的表示') print(' 还使用了辅助过程BINOMIAL-HEAP-MERGE,来讲H1和H2的根表合并成一个按度数的单调递增次序排列的链表') print('练习19.2-1 写出BINOMIAL-HEAP-MERGE的伪代码 代码已经给出') heap = bh.BinomialHeap() heap = heap.insertkey(1) heap = heap.insertkey(2) heap = heap.insertkey(3) print(heap.head) print('练习19.2-2 将关键字24的结点插入如图19-7d的二项树当中') heap = self.buildheap() print(heap.head) heap = heap.insertkey(24) print(heap.head) print(' 所得结果二项堆就是24变成了头结点,25变成24的子结点') heap = heap.deletekey(28) print('练习19.2-3 删除28关键字整个二项堆结构与原来很不相同') print('练习19.2-4 讨论使用如下循环不变式BINOMIAL-HEAP-UNION的正确性') print(' x指向下列之一的根') print(' 1.该度数下唯一的根') print(' 2.该度数下仅有两根中的第一个') print(' 3.该度数下仅有三个根中的第一或第二个') print('练习19.2-5 如果关键字的值可以是无穷,为什么过程BINOMIAL-HEAP-MINIMUM可能无法工作') print('练习19.2-6 假设无法表示出关键字负无穷') print(' 重写BINOMIAL-HEAP-DELETE过程,使之在这种情况下能正确地工作,运行时间仍然为O(lgn)') print('练习19.2-7 类似的') print(' 讨论二项堆上的插入与一个二进制数增值的关系') print(' 合并两个二项堆与将两个二进制数相加之间的关系') print('练习19.2-8 略') print('练习19.2-9 证明:如果将根表按度数排成严格递减序(而不是严格递增序)保存') print(' 仍可以在不改变渐进运行时间的前提下实现每一种二项堆操作') print('练习19.2-10 略') print('思考题19-1 2-3-4堆') print(' 2-3-4树,其中每个内结点(非根可能)有两个、三个或四个子女,且所有的叶结点的深度相同') print(' 2-3-4堆与2-3-4树有些不同之处。在2-3-4堆中,关键字仅存在于叶结点中,', '且每个叶结点x仅包含一个关键字于其x.key域中') print(' 另外,叶结点中的关键字之间没有什么特别的次序;亦即,从左至右看,各关键字可以排成任何次序') print(' 每个内结点x包含一个值x.small,它等于以x为根的子树的各叶结点中所存储的最小关键字') print(' 根r包含了一个r.height域,即树的高度。最后,2-3-4堆主要是在主存中的,故无需任何磁盘读写') print(' 2-3-4堆应该包含如下操作,其中每个操作的运行时间都为O(lgn)') print(' (a) MINIMUM,返回一个指向最小关键字的叶结点的指针') print(' (b) DECREASE-KEY,将某一给定叶结点x的关键字减小为一个给定的值k<=x.key') print(' (c) INSERT,插入具有关键字k的叶结点x') print(' (d) DELETE,删除一给定叶结点x') print(' (e) EXTRACT-MIN,抽取具有最小关键字的叶结点') print(' (f) UNION,合并两个2-3-4堆,返回一个2-3-4堆并破坏输入堆') print('思考题19-2 采用二项堆的最小生成树算法') print(' 第23章要介绍两个在无向图中寻找最小生成树的算法') print(' 可以利用二项堆来设计一个不同的最小生成树算法') print(' 请说明如何用二项堆来实现此算法,以便管理点集合边集。需要对二项堆的表示做改变嘛')