Beispiel #1
0
    def __init__(self, board):
        self.board = board
        self.twin_board = self.board.twin()

        self.data_structure = DataStructure()
        self.twin_data_structure = DataStructure()

        self.states_explored = -1

        current_state = self.board
        current_twin_state = self.twin_board
        while True:
            self.states_explored += 1
            # print(current_state.moves_to_reach)
            # print(current_state)
            if current_state.is_solved():
                self.solution = self._form_solution(current_state)
                break
            elif current_twin_state.is_solved():
                self.moves = -1
                self.solution = []
                break

            for neighbor in current_state.neighbors():
                if current_state.previous is None or not neighbor.has_same_data(current_state.previous):
                    self.data_structure.add(neighbor)

            for neighbor in current_twin_state.neighbors():
                if current_twin_state.previous is None or not neighbor.has_same_data(current_twin_state.previous):
                    self.twin_data_structure.add(neighbor)

            current_state = self.data_structure.get_min()
            current_twin_state = self.twin_data_structure.get_min()
Beispiel #2
0
def heapsort(arr):
    """ Implements heapsort
    
        O(n*log(n))
    """
    heap = Heap(arr)
    for i in range(heap.size - 1, 0, -1):
        heap.heap[0], heap.heap[heap.size - 1] = heap.heap[heap.size -
                                                           1], heap.heap[0]
        heap.size -= 1
        heap.max_heapify(0)
    return heap.heap  # Ordered array
Beispiel #3
0
def heap_sort(num_arr):
    """
    Returns num_arr sorted in ascending fashion. The original array is not modified.
    Sorting is implemented using heap sort algorithm.
    The algorithm has O(n * log(n)) complexity.
    How it works: The array is put into max heap. The root of max heap is always the largest number. The sorting is done
        by repeated popping of the root.
    This implementation does not conserve the order of equal elements ("unstable sort").
    """
    hp = Heap(num_arr)
    result = []
    while not hp.is_empty():
        result.insert(0, hp.pop_max())
    return result
    def test_find_open_with_empty_aunt(self):
        node17 = HeapNode(17)
        node15 = HeapNode(15)
        node11 = HeapNode(11)
        node6 = HeapNode(6)
        node10 = HeapNode(10)
        node17.left = node15
        node17.right = node11
        node15.left = node6
        node15.right = HeapNode(10)

        heap = Heap(node17)
        self.assertEqual(heap[-1].value, 10)
        self.assertEqual(heap.find_open(), (node11, 'left'))
Beispiel #5
0
    def test_create_many(self):
        def is_invariant_node(i, my_heap):
            if i < 0 or i >= my_heap.size:
                raise IndexError(f"Index i should be between [0 and {my_heap.size})")
            if i != 0:
                pt = (i - 1) // 2
                if my_heap.arr[pt] < my_heap.arr[i]:
                    return False
            lf, rt = 2*i + 1, 2*i + 2
            if lf >= my_heap.size:
                return True
            elif rt == my_heap.size:
                if my_heap.arr[lf] > my_heap.arr[i]:
                    return False
            else:
                if my_heap.arr[i] < max(my_heap.arr[lf], my_heap.arr[rt]):
                    return False
            return True

        def check_heap_inv(my_heap):
            is_invariant = True
            for i in range(my_heap.size):
                is_invariant = is_invariant and is_invariant_node(i, my_heap)
            return is_invariant

        n_cases = 100
        n_nums = 50
        for _ in range(n_cases):
            num_list = list(np.random.rand(n_nums))
            h = Heap(num_list)
            self.assertTrue(check_heap_inv(h), "Heap invariant check failed")
    def test_find_open_with_single_child_aunt(self):
        node17 = HeapNode(17)
        node15 = HeapNode(15)
        node11 = HeapNode(11)
        node6 = HeapNode(6)
        node10 = HeapNode(10)
        node7 = HeapNode(7)
        node17.left = node15
        node17.right = node11
        node15.left = node6
        node15.right = HeapNode(10)
        node11.left = node7

        heap = Heap(node17)
        self.assertEqual(heap[-1].value, 7)
        self.assertEqual(heap.find_open(), (node11, 'right'))
Beispiel #7
0
 def test_create(self):
     num_list = [1, 4, 7, 5, -3, 2, 8, 9]
     h = Heap(num_list)
     result = [9, 5, 8, 4, -3, 2, 7, 1]
     self.assertTrue(h.arr == result, f"Heap construction failed {h.arr}")
    def test_delete(self):

        #          17                  7                  15                  15          
        #        /    \              /    \              /    \              /    \    
        #     15        11  -->   15        11  -->   7        11   -->   10        11
        #    /  \      /         /  \                /  \                /  \        
        #  6     10   7        6     10            6     10            6     7       
        heap = Heap(max_heap())
        heap[2].value = 11
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 15, 10, 11, None))
        self.assertTrue(test_binary_node(heap.root.left, 10, 6, 7, 15)) 
        self.assertTrue(test_binary_node(heap.root.right, 11, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10))
        self.assertTrue(test_binary_node(heap.root.left.right, 7, None, None, 10))
        #         15                  7                  11    
        #       /    \              /    \             /    \  
        #     10      11  -->    10       11  -->   10       7
        #    /  \               /                  /           
        #  6     7            6                  6             
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 11, 10, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 10, 6, None, 11)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 11))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10))
        #          11               6                 10           
        #        /    \           /    \            /    \        
        #     10       7  -->   10      7   -->   6       7
        #    /                                                      
        #  6                                                       
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 10, 6, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 10))
        #      10             7        
        #    /    \  -->    /       
        #  6       7      6     
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 7, 6, None, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 7)) 
        #      7                
        #    /   -->   6
        #  6             
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 6, None, None, None))
        #   6   -->  None
        heap.delete_root()
        self.assertFalse(heap.root)
    def test_insertion_with_percolation(self):
        #               17
        #             /    \
        #          15        10
        #         /  \      /
        #       6     10   7

        #     6
        six = HeapNode(6)
        heap = Heap(six)
        self.assertTrue(test_binary_node(heap.root, 6, None, None, None))

        #     6             10
        #    /    -->     /
        #  10           6
        heap.insert(10)
        self.assertTrue(test_binary_node(heap.root, 10, 6, None, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10))          
        #     10             10
        #    /  \  -->     /   \
        #  6     7       6      7
        heap.insert(7)
        self.assertTrue(test_binary_node(heap.root, 10, 6, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 10))
        #      10            15
        #     /  \  -->     /   \
        #   6     7       10      7
        #  /              / 
        # 15             6
        heap.insert(15)
        self.assertTrue(test_binary_node(heap.root, 15, 10, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 10, 6, None, 15)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10))
        #      15            17
        #     /  \  -->     /   \
        #   10    7       15      7
        #  /  \          /  \
        # 6    17       6    10
        heap.insert(17)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        #       17             17    
        #      /   \  -->     /   \   
        #    15     7       15     11
        #   /  \   /       /  \   /  
        #  6   10 11      6   10 7  
        heap.insert(11)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) 
        self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11))
    def test_bubble(self):

        #               17                      17                  100
        #             /    \                  /    \               /    \
        #          15        10    -->     15       100    -->   15       17
        #         /  \      /  \          /  \      /  \        /  \     /  \
        #       6     10   7   100      6     10   7   10     6     10  7   10

        heap = Heap(max_heap())
        parent = heap.root.right
        last = HeapNode(100)
        parent.right = last
        last.parent = parent
        heap.bubble(last)

        self.assertTrue(test_binary_node(heap.root, 100, 15, 17, None))
        self.assertTrue(test_binary_node(heap.root.right, 17, 7, 10, 100))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 17))
        self.assertTrue(test_binary_node(heap.root.right.right, 10, None, None, 17))

        #             100                  100                  100
        #            /    \               /    \               /    \
        #          15       17   -->    15       17    -->  99       17
        #         /  \     /  \        /  \     /  \        /  \     /  \
        #       6     10  7   10     99   10  7   10     15     10  7   10
        #      /                     /                   /
        #     99                   6                   6

        parent = heap.root.left.left
        last = HeapNode(99)
        last.parent = parent
        parent.left = last
        heap.bubble(last)
        self.assertTrue(test_binary_node(heap.root, 100, 99, 17, None))
        self.assertTrue(test_binary_node(heap.root.left, 99, 15, 10, 100))
        self.assertTrue(test_binary_node(heap.root.left.left, 15, 6, None, 99))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 99))
        self.assertTrue(test_binary_node(heap.root.left.left.left, 6, None, None, 15))

        #             100                  100                  100
        #            /    \               /    \               /    \
        #          99       17   -->    99       17    -->  100       17
        #         /  \     /  \        /  \     /  \        /  \      /  \
        #       15    10  7   10     15  100  7   10     15    99   7   10
        #      /  \   /             / \   /              /  \   /
        #     6   12 100          6  12 10             6   12 10

        fifteen = heap.root.left.left
        twelve = HeapNode(12)
        twelve.parent = fifteen
        fifteen.right = twelve

        ten = heap.root.left.right
        last = HeapNode(100)
        ten.left = last
        last.parent = ten
        heap.bubble(last)
        self.assertTrue(test_binary_node(heap.root, 100, 100, 17, None))
        self.assertTrue(test_binary_node(heap.root.left, 100, 15, 99, 100))
        self.assertTrue(test_binary_node(heap.root.left.left, 15, 6, 12, 100))
        self.assertTrue(test_binary_node(heap.root.left.right, 99, 10, None, 100))
 def test_insert(self):
     node17 = HeapNode(17)
     heap = Heap(node17)
     heap.insert(15)
     self.assertTrue(test_binary_node(heap.root, 17, 15, None, None))
     self.assertTrue(test_binary_node(heap.root.left, 15, None, None, 17))
     heap.insert(10)
     self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
     self.assertTrue(test_binary_node(heap.root.left, 15, None, None, 17))        
     self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17))
     heap.insert(6)
     self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
     self.assertTrue(test_binary_node(heap.root.left, 15, 6, None, 17))        
     self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17))
     self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
     heap.insert(10)
     self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
     self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17))        
     self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17))
     self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
     self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
     heap.insert(7)
     self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
     self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17))        
     self.assertTrue(test_binary_node(heap.root.right, 10, 7, None, 17))
     self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
     self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
     self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 10))
 def test_heap_iteration(self):
     heap = Heap(max_heap())
     self.assertEqual([int(str(n)) for n in heap.breadth()], [17, 15, 10, 6, 10, 7])
     self.assertEqual([int(str(n)) for n in heap], [17, 15, 10, 6, 10, 7])
     self.assertEqual(heap.flatten(), [17, 15, 10, 6, 10, 7])