Reputation: 5784
Is there a simple explanation for why this snippet finds the shortest distance between two vertices
for (k = 0; k < n; ++k)
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
if (d[i][k] + d[k][j] < d[i][j])
d[i][j] = d[i][k] + d[k][j]
and this doesn't
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
for (k = 0; k < n; ++k)
if (d[i][k] + d[k][j] < d[i][j])
d[i][j] = d[i][k] + d[k][j]
( for k is the innermost one in the second snippet)
Upvotes: 1
Views: 2012
Reputation: 620
Basically when you have K
value in loop k
that means You are about to add another edge and all possible way to go from (i->j)
is updated using edges(1->K-1)
.
Then you insert another edge K
and you again check if there is any way to go from (i->j)
in cheaper way using this edge . so you write d[i][j]=min(d[i][j],d[i][k]+d[k][j])
.
So if you want to write
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
Your update should be d[j][k] = min(d[j][k],d[j][i]+d[i][k])
Upvotes: 0
Reputation: 2434
In
for (k = 0; k < n; ++k)
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
if (d[i][k] + d[k][j] < d[i][j])
d[i][j] = d[i][k] + d[k][j]
The outermost loop k
is referring to vertices that may be on the path between Vi
and Vj
. So when k=1
, for example, you are considering all paths between vertices Vi
and Vj
that include vertex V1
as in
Vi .... V1 .... Vj
More importantly, from among those paths you are choosing the best with the relaxation
if (d[i][k] + d[k][j] < d[i][j])
d[i][j] = d[i][k] + d[k][j]
Again, each iteration is focussed on two vertices Vi
and Vj
and in chooses the best path between them.
In your other instance, the one that fails, you are not choosing the best among paths between two fixed vertices Vi
and Vj
, instead you are relaxing all over the place, never waiting long enough to find out which path between two set vertices is the best.
On Geekviewpoint, a site which I rely on a lot, they distinctively use x
and v
as vertices and t
for the outermost loop, which makes it easy to remember that t
is temporary and so not one of the endpoints. (I wish they had actually explained it, since it's not obvious to everyone.)
//dynamically find the shortest distance between each pair.
for (int t = 0; t < n; t++) {
for (int v = 0; v < n; v++) {
for (int u = 0; u < n; u++) {
if (dist[v][u] > (long) dist[v][t] + dist[t][u]) {
dist[v][u] = dist[v][t] + dist[t][u];
pred[v][u] = pred[t][u];
}
}
}
}
Upvotes: 2
Reputation: 5784
I found a counterexample for the second flawed algorithm.
When i=0, j=1 it will try to find an intermediary, but there isn't any.
Then when an intermediary would be available for i=0, j=1 it is no longer checked again.
Upvotes: 0
Reputation: 43477
Because the idea is to try to make paths better by trying to go through node k
at each step in order to improve every i - j
path.
The notations do not matter, you can use i, j, k
as the loop variables instead of k, i, j
if you want, but you must keep the logic above in mind. In that case, you will want to try to improve the j - k
paths by going through i
at each step:
for i = 0, n
for j = 0, n
for k = 0, n
if d[j, i] + d[i, k] < d[j, k]
d[j, k] = d[j, i] + d[i, k]
You cannot just reorder the for loops without also changing the condition because you get a different algorithm that way - who knows what it does.
Upvotes: 4