def singleSourceShortest(G, src): """ Given graph G return dictionary of shortest paths to other vertices from vertex src. All vertices in G must be drawn from the range 0..n-1 and src must also be from same range. """ # Initialize dist[] matrix to be Infinity for all but src infinity = sys.maxsize n = 0 dist = {} for v in range(len(G)): n += 1 dist[v] = infinity dist[src] = 0 # optimized construction for BinaryHeap pq = BinaryHeap(n, src, infinity) while not pq.isEmpty(): u = pq.pop() for v, weight in G.neighbors(u): newLen = dist[u] + weight if newLen < dist[v]: pq.decreaseKey(v, newLen) dist[v] = newLen return dist
def singleSourceShortest(G, src): """ Given graph G return dictionary of shortest paths to other vertices from vertex src. All vertices in G must be drawn from the range 0..n-1 and src must also be from same range. """ # Initialize dist[] matrix to be Infinity for all but src infinity = sys.maxsize n = 0 dist = {} for v in range(len(G)): n += 1 dist[v] = infinity dist[src] = 0 # optimized construction for BinaryHeap pq = BinaryHeap(n, src, infinity) while not pq.isEmpty(): u = pq.pop() for v,weight in G.neighbors(u): newLen = dist[u] + weight if newLen < dist[v]: pq.decreaseKey(v, newLen) dist[v] = newLen return dist
class TestBinaryHeap(unittest.TestCase): def setUp(self): # create BinaryHeap with initial 4 elements, and src is 2. Use # 999 for infinity self.bh = BinaryHeap(15,2,999) def tearDown(self): self.bh = None def test_basic(self): self.assertEqual(2, self.bh.pop()) def test_decreaseKey(self): self.bh.decreaseKey(0, 19) self.bh.decreaseKey(1, 7) self.bh.decreaseKey(3,22) self.assertEqual(2, self.bh.pop()) self.assertEqual(1, self.bh.pop()) self.assertEqual(0, self.bh.pop()) self.assertEqual(3, self.bh.pop()) def test_decreaseKeyMany(self): self.bh = BinaryHeap(1000,0,999) for _ in range(999, 0, -1): self.bh.decreaseKey(_, _) for _ in range(1000): self.assertEqual(_, self.bh.pop()) def test_multipleDecreaseKey(self): self.bh = BinaryHeap(50,0,999) for n in range(1, 50): for p in range(1, n): self.bh.decreaseKey(n, p) result = [] for _ in range(50): result.append(self.bh.pop()) self.assertEqual(list(range(50)), sorted(result)) def test_decreaseKeyRandom(self): self.bh = BinaryHeap(1000,0,999) for _ in range(999, 0, -1): self.bh.decreaseKey(_, random.randint(1,999)) result = [] for _ in range(1000): result.append(self.bh.pop()) self.assertEqual(list(range(1000)), sorted(result))