JavaAlgorithms/DataStructures/Graphs/BellmanFord.java

161 lines
5.1 KiB
Java

package DataStructures.Graphs;
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
*/
public Edge(int a,int b,int c)
{
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();
}
}
sc.close();
}
/**
* @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;
}
}