2020-01-29 00:18:15 +08:00
|
|
|
package DataStructures.Graphs;
|
|
|
|
|
2018-06-04 01:44:13 +08:00
|
|
|
import java.util.*;
|
|
|
|
class BellmanFord
|
|
|
|
/*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs in form of edges which have
|
|
|
|
start vertex, end vertes and weights. Vertices should be labelled with a number between 0 and total number of vertices-1,both inclusive*/
|
|
|
|
{
|
|
|
|
int vertex,edge;
|
|
|
|
private Edge edges[];
|
|
|
|
private int index=0;
|
|
|
|
BellmanFord(int v,int e)
|
|
|
|
{
|
|
|
|
vertex=v;
|
|
|
|
edge=e;
|
|
|
|
edges=new Edge[e];
|
|
|
|
}
|
|
|
|
class Edge
|
|
|
|
{
|
|
|
|
int u,v;
|
|
|
|
int w;
|
|
|
|
/**
|
|
|
|
*@param u Source Vertex
|
|
|
|
* @param v End vertex
|
|
|
|
* @param c Weight
|
|
|
|
*/
|
2020-05-25 05:21:28 +08:00
|
|
|
public Edge(int a,int b,int c)
|
2018-06-04 01:44:13 +08:00
|
|
|
{
|
|
|
|
u=a;
|
|
|
|
v=b;
|
|
|
|
w=c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @param p[] Parent array which shows updates in edges
|
|
|
|
* @param i Current vertex under consideration
|
|
|
|
*/
|
|
|
|
void printPath(int p[],int i)
|
|
|
|
{
|
|
|
|
if(p[i]==-1)//Found the path back to parent
|
|
|
|
return;
|
|
|
|
printPath(p,p[i]);
|
|
|
|
System.out.print(i+" ");
|
|
|
|
}
|
|
|
|
public static void main(String args[])
|
|
|
|
{
|
|
|
|
BellmanFord obj=new BellmanFord(0,0);//Dummy object to call nonstatic variables
|
|
|
|
obj.go();
|
|
|
|
}
|
|
|
|
public void go()//Interactive run for understanding the class first time. Assumes source vertex is 0 and shows distaance to all vertices
|
|
|
|
{
|
|
|
|
Scanner sc=new Scanner(System.in);//Grab scanner object for user input
|
|
|
|
int i,v,e,u,ve,w,j,neg=0;
|
|
|
|
System.out.println("Enter no. of vertices and edges please");
|
|
|
|
v=sc.nextInt();
|
|
|
|
e=sc.nextInt();
|
|
|
|
Edge arr[]=new Edge[e];//Array of edges
|
|
|
|
System.out.println("Input edges");
|
|
|
|
for(i=0;i<e;i++)
|
|
|
|
{
|
|
|
|
u=sc.nextInt();
|
|
|
|
ve=sc.nextInt();
|
|
|
|
w=sc.nextInt();
|
|
|
|
arr[i]=new Edge(u,ve,w);
|
|
|
|
}
|
|
|
|
int dist[]=new int[v];//Distance array for holding the finalized shortest path distance between source and all vertices
|
|
|
|
int p[]=new int[v];//Parent array for holding the paths
|
|
|
|
for(i=0;i<v;i++)
|
|
|
|
dist[i]=Integer.MAX_VALUE;//Initializing distance values
|
|
|
|
dist[0]=0;
|
|
|
|
p[0]=-1;
|
|
|
|
for(i=0;i<v-1;i++)
|
|
|
|
{
|
|
|
|
for(j=0;j<e;j++)
|
|
|
|
{
|
|
|
|
if((int)dist[arr[j].u]!=Integer.MAX_VALUE&&dist[arr[j].v]>dist[arr[j].u]+arr[j].w)
|
|
|
|
{
|
|
|
|
dist[arr[j].v]=dist[arr[j].u]+arr[j].w;//Update
|
|
|
|
p[arr[j].v]=arr[j].u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//Final cycle for negative checking
|
|
|
|
for(j=0;j<e;j++)
|
|
|
|
if((int)dist[arr[j].u]!=Integer.MAX_VALUE&&dist[arr[j].v]>dist[arr[j].u]+arr[j].w)
|
|
|
|
{
|
|
|
|
neg=1;
|
|
|
|
System.out.println("Negative cycle");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(neg==0)//Go ahead and show results of computaion
|
|
|
|
{
|
|
|
|
System.out.println("Distances are: ");
|
|
|
|
for(i=0;i<v;i++)
|
|
|
|
System.out.println(i+" "+dist[i]);
|
|
|
|
System.out.println("Path followed:");
|
|
|
|
for(i=0;i<v;i++)
|
|
|
|
{
|
|
|
|
System.out.print("0 ");
|
|
|
|
printPath(p,i);
|
|
|
|
System.out.println();
|
|
|
|
}
|
|
|
|
}
|
2020-01-29 00:34:52 +08:00
|
|
|
sc.close();
|
2018-06-04 01:44:13 +08:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @param source Starting vertex
|
|
|
|
* @param end Ending vertex
|
|
|
|
* @param Edge Array of edges
|
|
|
|
*/
|
|
|
|
public void show(int source,int end, Edge arr[])//Just shows results of computation, if graph is passed to it. The graph should
|
|
|
|
//be created by using addEdge() method and passed by calling getEdgeArray() method
|
|
|
|
{
|
|
|
|
int i,j,v=vertex,e=edge,neg=0;
|
|
|
|
double dist[]=new double[v];//Distance array for holding the finalized shortest path distance between source and all vertices
|
|
|
|
int p[]=new int[v];//Parent array for holding the paths
|
|
|
|
for(i=0;i<v;i++)
|
|
|
|
dist[i]=Integer.MAX_VALUE;//Initializing distance values
|
|
|
|
dist[source]=0;
|
|
|
|
p[source]=-1;
|
|
|
|
for(i=0;i<v-1;i++)
|
|
|
|
{
|
|
|
|
for(j=0;j<e;j++)
|
|
|
|
{
|
|
|
|
if((int)dist[arr[j].u]!=Integer.MAX_VALUE&&dist[arr[j].v]>dist[arr[j].u]+arr[j].w)
|
|
|
|
{
|
|
|
|
dist[arr[j].v]=dist[arr[j].u]+arr[j].w;//Update
|
|
|
|
p[arr[j].v]=arr[j].u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//Final cycle for negative checking
|
|
|
|
for(j=0;j<e;j++)
|
|
|
|
if((int)dist[arr[j].u]!=Integer.MAX_VALUE&&dist[arr[j].v]>dist[arr[j].u]+arr[j].w)
|
|
|
|
{
|
|
|
|
neg=1;
|
|
|
|
System.out.println("Negative cycle");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(neg==0)//Go ahead and show results of computaion
|
|
|
|
{
|
|
|
|
System.out.println("Distance is: "+dist[end]);
|
|
|
|
System.out.println("Path followed:");
|
|
|
|
System.out.print(source+" ");
|
|
|
|
printPath(p,end);
|
|
|
|
System.out.println();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
*@param x Source Vertex
|
|
|
|
* @param y End vertex
|
|
|
|
* @param z Weight
|
|
|
|
*/
|
|
|
|
public void addEdge(int x,int y,int z)//Adds unidirectionl Edge
|
|
|
|
{
|
|
|
|
edges[index++]=new Edge(x,y,z);
|
|
|
|
}
|
|
|
|
public Edge[] getEdgeArray()
|
|
|
|
{
|
|
|
|
return edges;
|
|
|
|
}
|
|
|
|
}
|