Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
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()
Ejemplo n.º 3
0
 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
Ejemplo n.º 5
0
    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()
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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(' 请说明如何用二项堆来实现此算法,以便管理点集合边集。需要对二项堆的表示做改变嘛')