 Hello and welcome to this next session on data structures and algorithms. We will continue our discussion on shortest path algorithms. Today we will introduce you to an algorithm that finds shortest path between all pairs of vertices in a graph. So far the Bellman Fort and the Dystra algorithms that we discussed are based upon a single source vertex. What if you want to find the shortest path between every pair of points? So given a directed graph for each edge v1, v2 and e you have an associated weight. The problem is to find a shortest path from v1 to v2. We make an interesting observation here before we discuss the exact solution. The observation is that if d v1 vk is shortest path from v1 to vk and d vk v2 is a shortest path from vk to v2 then we expect the following. We expect that v1 to v2 are directly connected in a graph then the associated weight w v1 v2 could be the shortest path or the sum of these two could be the shortest path. So we would expect that d the shortest path from v1 to v2 is the min of t of v1 to vk if from and then from vk to v2 and if there is an edge v1 to v2 you might also want to look at weight of v1 to v2. However, who will give you this shortest path from v1 to vk at the outset? We would not have these. What we of course know are these weights to begin with and instead of looking at the minimum weight from v1 to vk and then vk to v2 what we will do is iteratively construct the weights from v1 to vk and vk to v2 restricted to the first k minus 1 nodes and that we will denote with a superscript k minus 1. So what we are going to exploit is that the shortest path from v1 to vk using the first k minus 1 nodes using the nodes 1 or more precisely the set of nodes 1 to k minus 1. Similarly, if vk minus 1 vk to v2 is the shortest path from v1 to vk using nodes 1 to k minus 1 then we will estimate the shortest path from v1 to v2 using the first k nodes dk v1 v2 as the min of the sum of the distances using k minus 1 nodes from v2 v1 to vk and vk to v2 respectively or it could be the direct weight on the edge v1 to v2. This is the basic idea behind the all pair shortest path algorithm. This has a very specific name this is called the Floyd-Warshall algorithm. In fact, this is the first instance of a algorithmic paradigm called dynamic programming. So this is instance of an algorithmic paradigm. What is dynamic programming here? Well, we are actually solving larger problems in terms of smaller problems. We keep track of distances using up to k minus 1 nodes and use that to keep track of distances up to k nodes. This goes on. A substructure gives you solution to the superstructure. So let us set up the notation before we give you the complete algorithm. So given this weighted graph, we are going to represent the weight of each edge in an adjacency matrix representation. So w is the adjacency matrix representation. So w between i and j is the weight of nodes of the edge v i to vj. It is set to 0 if i equal to j. If ij is an edge, then w, vi, vj is nothing but the actual edge weight and it is set to infinity if there is no direct edge between i and j. Now the distance matrix that we talked about is initialized to w. And what is d0? d0 is nothing but the shortest path matrix for all pairs with path, sorry called we talked about nodes 1, 2 to k minus 1, but here we have k less than 1. So this is basically path through the empty set. We will also do bookkeeping using a predecessor matrix. So this is bookkeeping for shortest path. What this does is if ij is indeed an edge, then the predecessor or j is i. However, if there is no such edge ij, then the predecessor is set to null. This is the initial configuration. Then after, we are going to invoke the dynamic programming update step that we have already motivated. So here is the algorithm with the initialization that we already discussed. We are going to iterate through every node. We are assuming that the nodes are numbered 1 to n. So for this, the k value will be 1, 2 until n. So dk is a new n by n matrix that we want to learn. And this corresponds to the desired shortest path matrix which passes through nodes 1 to k. And how do you find that? Well for every node i and every node j, we will let ourselves explore the shortest path from i to j that passes through 1 of the k minus 1 nodes, 1 or more of the k minus 1 nodes. So this is the shortest path from vi to vj through 1 or more of 1 to k minus 1 nodes with these indices. So you might want to specifically write them down as v, the nodes numbered v1 to vk minus 1. The other possibility however is that there is a shortest path which includes k. And therefore, we compare this shortest path through v1 to vk minus 1 with the new shortest path. And this is the shortest path from vi to vk through v1 to vk minus 1 plus the shortest path from vk to vj. This is again passing through 1 of these nodes, 1 or more of these nodes. What are we saying? We are saying that the shortest path from vi to vj either passes through vk or does not pass through vk but the nodes v1 to vk minus 1. There is no point in repeating vk more than once because if that happens you would have a cycle. And in fact we will see that a cycle with negative weights is undesirable, will lead to infinite shortest path costs or weights. And that is something we will actually discover at the end of the algorithm. So for the time being we are talking about the desirable case where vk does not repeat. What is the complexity of this algorithm? Where you want to iterate over k which varies from 1 to n which is nothing but more than once because if that happens you would have a cycle. And in fact we will see that a cycle with negative weights is undesirable, will lead to infinite shortest path costs or weights. And that is something we will actually discover at the end of the algorithm. So for the time being we are talking about the desirable case where vk does not repeat. What is the complexity of this algorithm? Where you want to iterate over k which varies from 1 to n which is nothing but the number of vertices. And you are going to do that thrice. So it is basically v into v into v into v so each of this is order v. So this is basically an order v cube algorithm. Let us see this algorithm in action. So this is the graph with k equals 0 where d 0 is just set to w. And what is w? If there is a direct edge you have the corresponding weight else you set the weight to infinity. The weight or the shortest path from a node to itself is 0 as weight 0. What next? So we could assume that a corresponds to k equals 1, b corresponds to k equals 2, c is k equals 3 and e is k equals 4. So we start with k equals 1. And to remind you k equals 1 corresponds to the node or vertex a. And we will start with v i equals b. We are certainly not interested in the row corresponding to a because we are looking at paths going through a. So we look at b. Now we scan the row corresponding to a that is this row. This is the column under consideration. And we scan the row corresponding to v i. And we will basically vary j. So j will be scanned for in this row. And what are we going to see? We are going to basically check for different values of j whether v i k plus v k j is less or v i j is less. So we start with v i j. Start with v i j where j equals a, v j equals a. And we find that well 6 plus 0 is certainly equal to 6 itself. So we persist with the 6. Again we are not interested from b to b. b to c, well we are going to look at the shortest path from b to a and from then a to c. b to a is 6, a to c is 4 and this gives you the value of 10. This is actually less than b to c, the earlier value of b to c which was basically infinity. You can do the same thing for b to d but there is no path through a. So this is the only update for v i equals v and k equals 1. Then look at k equals 2. So basically for k equals 1 there is nothing else that is possible. The c i is infinity and d i is also infinity. For k equals 2 we start with v i equals a. So recall we are going to decide on the column based on k and that happens to be this one because this corresponds to b and rho will correspond to v i equals a. This is the rho and we are going to now scan for j in this rho. So we certainly will start with c v j equals c and that will mean comparing a b that is 12 with b c that is 10. So 12 plus 10 is 22 which is actually greater than existing weight 4 on a j the d i j. So we leave this unaltered but then we look at the next one 12 plus 8 and we compare that again a d which was actually infinity. So this leads to an update. So we continue with k equals 2 which corresponds to b and we will change our choice of i to the third rho. This will correspond to v i equals c and as before we are going to scan this from left to right for different values of j. Our comparisons again reveal the following so we look at c b plus b a. So c b is 3 and p a is 6. So this leads to an update of 9 for c a. We also look at c b which is 3 plus b d which is 8 and that is 11 and that is actually less than the earlier value of c d which was infinity. So this gives you two updates for v i equals c. Continuing with k equals 2 we now turn our attention to the last rho. We again perform a scan for different values of j and we compare d b with b a and then d b is 10, d a is 6 and compare with the earlier value of d a. The earlier value of d a was infinity and the 16 is certainly less than infinity. There is an update. There is actually nothing to do for the last two because the weights are always anyways going to be smaller than what we would get using any possible update relaxation. So this was for k equals 2, for k equals 3 which is the choice of c. Now I have shown one example. Now we have started looking at longer, we will start looking at longer hauls. v i equals a, v j equals b. We are going to quickly jump to our results. So we look at the existing shortest path between a and b which was 12 and then we look at the shortest path from a to b. To c which is 4, the shortest path from c to b which is 3 and find that well, 7, 4 plus 3 is certainly less than 12. So we will update. So we go on to the end. We have just changed the value of j, v j equals d and you compare a, c, 4 plus a to b. c d which is 11 and contrast as with the earlier value of a d, a d was 20. So 4 plus 11 is less than 20 and thus you update to 15. So this is as far as the illustration goes, how do you show the correctness of this algorithm? So one can show the correctness of this algorithm using the following loop invariant. We can show that the following loop invariant is initialized, maintained and holds a termination which is what we started off with that d k minus 1 v i comma v j is shortest path from v i to v j using exactly one or more of 1 to 2. K minus 1. Thank you.