Exemple #1
0
def dijkstra(graph, s, e):
    """Simple dijkstra algo to work out shortest path to an end node"""
   
    pq = MinHeap()
    # Set the distance for the start node to zero then build heap
    s.set_distance(0)
    pq.build_heap([(v.get_distance(),v) for v in graph])

    while not pq.is_empty():
        cv = pq.del_min()
        current_v = cv[1]
        current_v.set_as_visited()
        if current_v.get_key() == e.get_key():
        	break
        else:
	        for v in current_v.adj:
	            new_dist = current_v.get_distance() + current_v.get_weight(v)
	            if new_dist < v.get_distance():
	                v.set_distance(new_dist)
	                v.set_pred(current_v)
	                pq.decrease_val(v, new_dist)
    

	# if queue empties before end is found it means there are no paths from source to end
    if pq.is_empty() == True:
    	print 'No path to exists'
    else:
    	shortest(e)
Exemple #2
0
def dsp(graph: list, s, t) -> int:
    """
        Find shortest path from two vertices via Dijkstra's shortest-path algorithm.

        Args:
            s: source vertex
            t: the target vertex

        Returns:
            Shortest path from `s` to `t` vertices
    """
    if s == t:
        return 0

    # Vertices seen so far
    visited = []
    heap = MinHeap([(10000000, v) for v in range(1, len(graph))])
    heap.update_min(0, s)

    while not heap.is_empty():
        dist, u = heap.pop()
        visited.append(u)
        if u == t:
            return dist
        for v, d in graph[u]:
            if v not in visited:
                heap.update_min(dist + d, v)
class TestMinHeap(unittest.TestCase):
    def setUp(self):
        self.heap = MinHeap()

    def test_clear(self):
        """Calling clear for a heap sets its array to an empty list and size to zero. (0p)"""
        self.heap.array = [(1, 1)]
        self.heap.size = 1

        self.heap.clear()

        self.assertListEqual(
            [], self.heap.array,
            "heap.clear() should set heap.array to an empty list.")
        self.assertEqual(0, self.heap.size,
                         "heap.clear() should set heap.size to 0.")

    def test_empty_heap_size(self):
        """The size of an empty heap is zero. (0p)"""
        self.assertEqual(0, self.heap.size,
                         "The size of an empty heap should be zero.")

    def test_empty_heap_is__empty(self):
        """is_empty returns True for an empty heap. (0p)"""
        self.assertTrue(
            self.heap.is_empty(),
            "Calling is_empty should return True for an empty heap instance.")

    def test_higher_priority_high_low(self):
        """_higher_priority returns True when comparing an element with a higher priority to an element with a lower priority. (1p)"""
        self.heap.array = [(1, 'important'), (2, 'not important')]
        self.assertTrue(
            self.heap._higher_priority(0, 1),
            "_higher_priority priority should return True when comparing {0} to {1}"
            .format(self.heap.array[0], self.heap.array[1]))

    def test_higher_priority_low_high(self):
        """_higher_priority returns False when comparing an element with a lower priority to an element with a higher priority. (1p)"""
        self.heap.array = [(1, 'important'), (2, 'not important')]
        self.assertFalse(
            self.heap._higher_priority(1, 0),
            "_higher_priority priority should return False when comparing {0} to {1}"
            .format(self.heap.array[1], self.heap.array[0]))

    def test_size_after_insert(self):
        """Inserting values into the heap increments the size counter. (1p)"""
        inserted_tasks = generate_tasks_with_priorities()
        for pair in inserted_tasks:
            self.heap.insert(pair)

        inserted_count = len(inserted_tasks)
        current_size = self.heap.size
        self.assertEqual(
            inserted_count, current_size,
            "After inserting {0} pairs, the size of the heap should be {0}, not {1}"
            .format(inserted_count, current_size) + '\n' +
            heap_array_to_string(self.heap.array))

    def test_empty_heap_top(self):
        """Calling top on an empty heap returns None. (1p)"""
        self.assertIsNone(
            self.heap.top(),
            "Calling heap.top() should return None for an empty heap instance."
        )

    def test_empty_heap_pop(self):
        """Calling pop on an empty heap raises an exception. (1p)"""
        msg = "Calling heap.pop() should raise a RuntimeError for an empty heap instance."
        with self.assertRaises(RuntimeError, msg=msg):
            self.heap.pop()

    def test_top_after_insert(self):
        """Calling top always returns the object with the smallest priority value. (1p)"""

        inserted_tasks = generate_tasks_with_priorities()

        shuffled = list(inserted_tasks)
        random.shuffle(shuffled)

        for pair in shuffled:
            self.heap.insert(pair)

        expected_value = inserted_tasks[0][1]
        returned_value = self.heap.top()
        self.assertIs(
            returned_value, expected_value,
            "Calling top should have returned {0}, not {1}.".format(
                expected_value, returned_value) + '\n' +
            heap_array_to_string(self.heap.array))

    def test_pop_after_insert(self):
        """Calling pop always returns the object with the smallest priority value and removes it from the heap. (1p)"""

        inserted_tasks = generate_tasks_with_priorities()

        shuffled = list(inserted_tasks)
        random.shuffle(shuffled)

        for pair in shuffled:
            self.heap.insert(pair)

        for i, pair in enumerate(inserted_tasks):
            assertmsg = "Before calling pop, the heap array in your solution looked like this:"
            heap_array_before_pop = self.heap.array[:]

            popped_value = self.heap.pop()
            expected_value = pair[1]
            self.assertIs(
                popped_value, expected_value,
                "Calling pop should have returned {0}, not {1}.".format(
                    expected_value, popped_value) + '\n' +
                heap_array_to_string(heap_array_before_pop, assertmsg))

            removed_count = i + 1
            self.assertEqual(
                len(self.heap.array),
                len(inserted_tasks) - removed_count,
                "Calling pop should remove the object with the smallest priority value from the heap array."
                + '\n' +
                heap_array_to_string(heap_array_before_pop, assertmsg))
Exemple #4
0
class TestMinHeap(unittest.TestCase):
    def setUp(self):
        self.h = MinHeap(elements=[2, 4, 5, 12, 13, 6, 10])

    def test_parent_index(self):
        self.assertLess(self.h._parent_index(0), 0)
        self.assertEqual(self.h._parent_index(1), 0)
        self.assertEqual(self.h._parent_index(2), 0)
        self.assertEqual(self.h._parent_index(4), 1)
        self.assertEqual(self.h._parent_index(6), 2)

    def test_left_child_index(self):
        self.assertGreaterEqual(self.h._left_child_index(3), len(self.h))
        self.assertGreaterEqual(self.h._left_child_index(5), len(self.h))
        self.assertEqual(self.h._left_child_index(0), 1)
        self.assertEqual(self.h._left_child_index(1), 3)
        self.assertEqual(self.h._left_child_index(2), 5)

    def test_right_child_index(self):
        self.assertGreaterEqual(self.h._right_child_index(3), len(self.h))
        self.assertGreaterEqual(self.h._right_child_index(6), len(self.h))
        self.assertEqual(self.h._right_child_index(0), 2)
        self.assertEqual(self.h._right_child_index(1), 4)
        self.assertEqual(self.h._right_child_index(2), 6)

    def test_is_empty(self):
        self.assertFalse(self.h.is_empty())
        self.assertTrue(MinHeap().is_empty())

    def test_peek(self):
        self.assertEqual(self.h.peek(), self.h.h[0])
        self.assertIsNone(MinHeap().peek())

    def test_heapify_init(self):
        elements = [2, 4, 5, 6, 10, 12, 13]
        h = MinHeap(elements)
        self.assertEqual(h.h, [2, 4, 5, 6, 10, 12, 13])

    def test_heapify_after_init(self):
        elements = [2, 4, 5, 6, 10, 12, 13]
        h = MinHeap()
        self.assertEqual(h.h, [])
        h._heapify(elements)
        self.assertEqual(h.h, [2, 4, 5, 6, 10, 12, 13])

    def test_insert_1(self):
        self.assertEqual(self.h.insert(1), 0)
        self.assertEqual(self.h.h, [1, 2, 5, 4, 13, 6, 10, 12])

    def test_insert_3(self):
        self.assertEqual(self.h.insert(3), 1)
        self.assertEqual(self.h.h, [2, 3, 5, 4, 13, 6, 10, 12])

    def test_insert_10(self):
        self.assertEqual(self.h.insert(9), 3)
        self.assertEqual(self.h.h, [2, 4, 5, 9, 13, 6, 10, 12])

    def test_insert_15(self):
        self.assertEqual(self.h.insert(15), 7)
        self.assertEqual(self.h.h, [2, 4, 5, 12, 13, 6, 10, 15])

    def test_update_min(self):
        self.assertTrue(9 not in self.h)
        self.assertTrue(10 in self.h)
        self.h.update_min(9, 10)
        self.assertTrue(9 in self.h)
        self.assertTrue(10 not in self.h)
        self.assertEqual(self.h.h, [2, 4, 5, 12, 13, 6, 9])

    def test_pop_empty(self):
        h = MinHeap()
        self.assertIsNone(h.pop())
        self.assertEqual(h.h, [])