im working on graph searching with Floyd-Warshalls algorithm and don´t understand how to alter it to prevent negative loops.
When i enter:
From Cost To
0 -1 1
1 -2 0
I get cost matrix:
0 1
0 -3 -4
1 -5 -10
and then it starts looping till it crashes because its still adding negative edges and further decreases the cost.
void FloydWarshall(int ***distanceMatrix, int maxVertices)
{
int from, to, via;
for(from = 0; from < maxVertices; from++)
{
for(to = 0; to < maxVertices; to++)
{
for(via = 0; via < maxVertices; via++)
{
//Fix the negative looping
//EDIT FIX:
if((*distanceMatrix)[via][via]<0)
{fprintf(stderr, "Contains negative cycle!\n"); continue;}
//END EDIT
//Searches for the cheapest way from all-to-all nodes, if new path
// is cheaper than the previous one, its updated in matrix
(*distanceMatrix)[from][to] = min((*distanceMatrix)[from][to],
((*distanceMatrix)[from][via]+(*distanceMatrix)[via][to]));
}
}
}
}
Where min is:
int min(int a,int b)
{return (a<b)? a:b;}
and my distanceMatrix has INF wherever there is no cost.
I came across older topic where the altered algorythm was like this:
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) // Go through all possible sources and targets
for(int k = 0; d[i][j] != -INF && k < n; k++)
if( d[i][k] != INF && // Is there any path from i to k?
d[k][j] != INF && // Is there any path from k to j?
d[k][k] < 0) // Is k part of a negative loop?
d[i][j] = -INF; // If all the above are true
// then the path from i to k is undefined
However, even when i use this fix instead of my function, it still loops and further decreases cost. Is this fix correct? If not, how should i rewrite it? Thanks.
From wikipedia
Hence, to detect negative cycles using the Floyd–Warshall algorithm, one can inspect the diagonal of the path matrix, and the presence of a negative number indicates that the graph contains at least one negative cycle.[2] Obviously, in an undirected graph a negative edge creates a negative cycle (i.e., a closed walk) involving its incident vertices.
So if d[k][k]
is ever less than 0
you should just exit and say there is a negative cycle.