Learnerslesson
   JAVA   
  SPRING  
  SPRINGBOOT  
 HIBERNATE 
  HADOOP  
   HIVE   
   ALGORITHMS   
   PYTHON   
   GO   
   KOTLIN   
   C#   
   RUBY   
   C++   




C SHARP - BELLMAN FORD'S ALGORITHM - CODE




Example :



using System.Collections.Generic;
using System;

public class Edge {

    public string startVertex;
    public string endVertex;

    public int value;
}

public class BellmanFordSSSP {

    List<string> vertices;
    List<Edge> edgeList;

    Dictionary<string, int> vertexDistance;
    Dictionary<string, string> vertexParent;


    BellmanFordSSSP(){

        vertices = new List<string>();
        edgeList = new List<Edge>();
    }

    void insertVertex(string vertex) {

        vertices.Add(vertex);
    }

    void insertEdge(string vertex1, string vertex2, int edgeVal) {

        Edge edge = new Edge();

        edge.startVertex = vertex1;
        edge.endVertex = vertex2;
        edge.value = edgeVal;

        edgeList.Add(edge);
    }


    public void getShortestPath(string sourceVertex) {

        vertexDistance = new Dictionary<string, int>();
        vertexParent = new Dictionary<string, string>();

       //HashSet the initial distance of every vertex to infinity
        foreach(string vertex in vertices) {
            vertexDistance[vertex] = Int32.MaxValue;;
            vertexParent[vertex] = null;
        }

        //Initialise the distance of source vertex to be 0
        vertexDistance[sourceVertex] = 0;

        int V = vertices.Count;

        for (int i = 0; i < V - 1 ; i++) {
            foreach (Edge edge in edgeList) {
                string u = edge.startVertex;
                string v = edge.endVertex;
                
                //relax the edge
                if (vertexDistance[u] + edge.value < vertexDistance[v]) {
                    vertexDistance[v] = vertexDistance[u] + edge.value;
                    vertexParent[v] = u;
                }
            }
        }

        //Relax all the edges again. If we are still getting a lesser distance then 
        //there is negative weight cycle in the graph. 
        foreach (Edge edge in edgeList) {
            string u = edge.startVertex;
            string v = edge.endVertex;
            if (vertexDistance[u] + edge.value < vertexDistance[v]) {
                System.Console.WriteLine( "The Graph contains negative weight cycle");
                return;
            }
        }
    }

    public void printShortestPath() {

        foreach (KeyValuePair<string, int> entry in vertexDistance) {

            System.Console.WriteLine( "The shortest distance between a and "+entry.Key+" is "+entry.Value);
        }
    }

    public static void Main(string[] args){

        BellmanFordSSSP bellmanFordSSSP = new BellmanFordSSSP();

        // Adding vertices one by one

        bellmanFordSSSP.insertVertex("a");
        bellmanFordSSSP.insertVertex("b");
        bellmanFordSSSP.insertVertex("c");
        bellmanFordSSSP.insertVertex("d");
        bellmanFordSSSP.insertVertex("e");

        //Adding edges with values.

        bellmanFordSSSP.insertEdge("a", "b", 18);
        bellmanFordSSSP.insertEdge("a", "c", 2);
        bellmanFordSSSP.insertEdge("a", "d", 4);

        bellmanFordSSSP.insertEdge("c", "e", 1);

        bellmanFordSSSP.insertEdge("e", "b", 5);

        bellmanFordSSSP.insertEdge("d", "c", 12);
        bellmanFordSSSP.insertEdge("d", "e", 3);



        bellmanFordSSSP.getShortestPath("a");

        bellmanFordSSSP.printShortestPath();;
    }
}


Output :



  The shortest distance between a and a is 0
  The shortest distance between a and b is 8
  The shortest distance between a and c is 2
  The shortest distance between a and d is 4
  The shortest distance between a and e is 3

Code explanation for Bellman Ford's Algorithm - Single Source Sortest path


For explanation purpose we will be taking the below Graph :

java_Collections

So, the first thing we will do is construct create a List,


	List<string> vertices;

And store all the Vertices there,


	bellmanFordSSSP.insertVertex("a");
	bellmanFordSSSP.insertVertex("b");
	bellmanFordSSSP.insertVertex("c");
	bellmanFordSSSP.insertVertex("d");
	bellmanFordSSSP.insertVertex("e");

The next thing we would do is, list out all the Edges.

java_Collections

So, we would create a List,


	List<Edge> edgeList;

And store all the Edges in the edgeList,


	bellmanFordSSSP.insertEdge("a", "b", 18);
	bellmanFordSSSP.insertEdge("a", "c", 2);
	bellmanFordSSSP.insertEdge("a", "d", 4);

	bellmanFordSSSP.insertEdge("c", "e", 1);

	bellmanFordSSSP.insertEdge("e", "b", 5);

	bellmanFordSSSP.insertEdge("d", "c", 12);
	bellmanFordSSSP.insertEdge("d", "e", 3);

And we have the method insertEdge(...) that initialises the Edges,


void insertEdge(string vertex1, string vertex2, int edgeVal) {

		Edge edge = new Edge();

		edge.startVertex = vertex1;
		edge.endVertex = vertex2;
		edge.value = edgeVal;

		edgeList.Add(edge);
	}

The insertEdge(...) method is quite simple to understand. We already have the Edge class :


public class Edge {

	public string startVertex;
	public string endVertex;

	public int value;
}

We have created an Edge object,


	Edge edge = new Edge();

And initialised the values,


	edge.startVertex = vertex1;
	edge.endVertex = vertex2;
	edge.value = edgeVal;

Finally, added the edge object to the List edgeList.


	edgeList.Add(edge);

And one by one, we add all the edges to the List edgeList. And, finally the List edgeList has all the Edges in it.


Now, since we have all the edges in the List edgeList. It is time for us to call the method getShortestPath(...) by passing the start vertex a to it.


	bellmanFordSSSP.getShortestPath("a");

Explanation of void getShortestPath(string sourceVertex) method :


public void getShortestPath(string sourceVertex) {

	vertexDistance = new Dictionary<string, int>();
	vertexParent = new Dictionary<string, string>();

//HashSet the initial distance of every vertex to infinity
	foreach(string vertex in vertices) {
		vertexDistance[vertex] = Int32.MaxValue;;
		vertexParent[vertex] = null;
	}

	//Initialise the distance of source vertex to be 0
	vertexDistance[sourceVertex] = 0;

	int V = vertices.Count;

	for (int i = 0; i < V - 1 ; i++) {
		foreach (Edge edge in edgeList) {
			string u = edge.startVertex;
			string v = edge.endVertex;

			//relax the edge
			if (vertexDistance[u] + edge.value < vertexDistance[v]) {
				vertexDistance[v] = vertexDistance[u] + edge.value;
				vertexParent[v] = u;
			}
		}
	}

	//Relax all the edges again. If we are still getting a lesser distance then
	//there is negative weight cycle in the graph.
	foreach (Edge edge in edgeList) {
		string u = edge.startVertex;
		string v = edge.endVertex;
		if (vertexDistance[u] + edge.value < vertexDistance[v]) {
			System.Console.WriteLine( "The Graph contains negative weight cycle");
			return;
		}
	}
}

So, what we have done is, created two Maps.


The first Dictionary vertexDistance stores vertex as key and the value as the one we were marking each vertex with.


vertexDistance = new Dictionary<string, int>();

In simple words,


If we take the example of the Edge a,b with value 18.

java_Collections

The Vertex a is marked with 0 and Vertex b is marked with 18.


So, the Dictionary vertexDistance stores Vertex a as key and 0 as value.


Similarly, the Dictionary vertexDistance stores Vertex b as key and 18 as value.


Quite clear !


Now, let us see the second Dictionary,


vertexParent = new Dictionary<string, string>();

The second Dictionary vertexParent stores vertex as key and the value as its immediate source vertex.


If we take the same example of the Edge a,b with value 18.

java_Collections

So, the Dictionary vertexParent stores Vertex b as key and vertex a as value.


Similarly, if we take the example of the Edge d,e with length 3.

java_Collections

Then the Dictionary vertexParent stores Vertex e as key and vertex d as value.


Fair enough !


So, the next thing we will do is, mark all the Vertices with except the starting vertex a, which should be marked with 0.

java_Collections

And to do this we will take all the Vertices one by one and put in the Dictionary vertexDistance and initialise the value of each Vertex to or int.Max_value.


And at the same time, take the vertices and put in the Dictionary vertexParent and initialise the value of each Vertex to null.


	foreach(string vertex in vertices) {
		vertexDistance[vertex] = Int32.MaxValue;;
		vertexParent[vertex] = null;
	}

	vertexDistance.Add(sourceVertex, 0);
java_Collections


Then comes the for loop where in each iteration the marking and relaxing process takes place. And we iterate it V-1 times. Where V is the number of Vertices.


	for (int i = 0; i < V - 1 ; i++) {
		foreach (Edge edge in edgeList) {
			string u = edge.startVertex;
			string v = edge.endVertex;

			//relax the edge
			if (vertexDistance[u] + edge.value < vertexDistance[v]) {
				vertexDistance[v] = vertexDistance[u] + edge.value;
				vertexParent[v] = u;
			}
		}
	}

The above for loop is quite simple.


As said we iterate the for loop V-1 times.


for (int i = 0; i < V - 1 ; i++) {

There is a nested for loop inside it. Which collects all the edges from the List edgeList,

java_Collections

And iterates through all the edges from the List edgeList, one by one.


foreach (Edge edge in edgeList) {
	string u = edge.startVertex;
	string v = edge.endVertex;

	//relax the edge
	if (vertexDistance[u] + edge.value < vertexDistance[v]) {
		vertexDistance[v] = vertexDistance[u] + edge.value;
		vertexParent[v] = u;
	}
}

So, in the above nested for loop, it takes the the first edge,

java_Collections

And the startVertex i.e. a is put in a string u,


string u = edge.startVertex;

and the endVertex i.e. b is put in a string v.


string v = edge.endVertex;

So, u would contain vertex a and v would contain the vertex b.


Next, we come across the line that has the if statement. Where the actual relaxation process takes place.


if (vertexDistance[u] + edge.value < vertexDistance[v]) {
	vertexDistance[v] = vertexDistance[u] + edge.value;
	vertexParent[v] = u;
}

So, if we have a closer look at the if statement,


if (vertexDistance[u] + edge.value < vertexDistance[v])

The if statement has,

  1. vertexDistance[u]

  2. edge.value

  3. vertexDistance[v]

The vertexDistance is a Dictionary that has the Key as Vertex name and value as the value marked with the current vertex.

java_Collections
java_Collections

Currently all the vertices are marked with . Except the starting vertex a which is marked with 0.


Now, let us relook the condition inside if statement.


if (vertexDistance[u] + edge.value < vertexDistance[v])

The variable u has the value a inside it.


So, vertexDistance[u] gives us 0(As the value associated with the key a is 0 in vertexDistance Dictionary).


Similarly, vertexDistance[v] gives us (As the value associated with the key b is in vertexDistance Dictionary).


And edge.value gives us 18 (Because the current edge we are dealing with is a,b with value 18).


Now, if we see the add operation,


vertexDistance[u] + edge.value

It would be 0 + 18, i.e. 18


and check if the added value 18 is less than vertexDistance[v] (i.e. ∞).


if (vertexDistance[u] + edge.value < vertexDistance[v])

And obviously, 18 is less than .


So, we get into the if block and relax/replace the new added value vertexDistance.get(u) + edge.value i.e. 18 to the value of vertex b


vertexDistance[v] = vertexDistance[u] + edge.value;

At the same time change the parent of b to a in vertexParent.

java_Collections
java_Collections

Note : In the Dictionary vertexDistance, we are storing the vertex and its marked distance (i.e. Vertex b and 18). And to track the immediate parent of vertex b we are using the Dictionary vertexParent. Where we are storing the immediate parent of b in parallel.

Same way we have to take the next edge and continue with the for loop.


foreach (Edge edge in edgeList) {
	string u = edge.startVertex;
	string v = edge.endVertex;
	if (vertexDistance[u] + edge.value < vertexDistance[v]) {
		System.Console.WriteLine( "The Graph contains negative weight cycle");
		return;
	}
}

So, the next edge in the List edgeList is,

java_Collections

Similarly we take the startVertex and endVertex of edge object in u and v.


So, right now u has a and v has c.


Next, we add the current value of vertex a in vertexDistance (i.e. 0) and the current value of the edge (i.e. 2)


vertexDistance[u] + edge.value

and check if the added value(i.e. 2) is less than the value of vertex d in vertexDistance (i.e. ∞).


if (vertexDistance[u] + edge.value < vertexDistance[v])

And obviously, 2 is less than ∞.


So, we get into the if block and relax/replace the new added value vertexDistance.get(u) + edge.value i.e. 2 to the value of vertex c


vertexDistance[v] = vertexDistance[u] + edge.value;

At the same time change the parent of c to a in vertexParent.

java_Collections
java_Collections

And if we continue the same process, we get the Stortest Path from source vertex a to all the other Vertices.


Well ! We are not done yet.


What if there is a negative weight cycle?


And we have the code to deal with negative weight cycle.


//Relax all the edges again. If we are still getting a lesser distance then
//there is negative weight cycle in the graph.
foreach (Edge edge in edgeList) {
	string u = edge.startVertex;
	string v = edge.endVertex;
	if (vertexDistance[u] + edge.value < vertexDistance[v]) {
		System.Console.WriteLine( "The Graph contains negative weight cycle");
		return;
	}
}

The above code is quite simple to understand.


We usually continue iterating (V-1) times. Where V is the number of vertices. In this case we iterate V times. And if the weight reduces then there is a negative weight cycle.


Running time of Bellman Ford Algorithm


Since we are running a nested for loop.


So, the running time is : O(VE)


Where V is the number of Vertices


And E is the number of Edges.


method indicates if the stack is empty or not.