diff --git a/Graphs/BellmanFord.js b/Graphs/BellmanFord.js new file mode 100644 index 0000000000..cf9d168460 --- /dev/null +++ b/Graphs/BellmanFord.js @@ -0,0 +1,56 @@ +/* +The Bellman–Ford algorithm is an algorithm that computes shortest paths +from a single source vertex to all of the other vertices in a weighted digraph. +It also detects negative weight cycle. + +Complexity: + Worst-case performance O(VE) + Best-case performance O(E) + Worst-case space complexity O(V) + +Reference: + https://en.wikipedia.org/wiki/Bellman–Ford_algorithm + https://cp-algorithms.com/graph/bellman_ford.html + +*/ + +/** + * + * @param graph Graph in the format (u, v, w) where + * the edge is from vertex u to v. And weight + * of the edge is w. + * @param V Number of vertices in graph + * @param E Number of edges in graph + * @param src Starting node + * @param dest Destination node + * @returns Shortest distance from source to destination + */ +function BellmanFord (graph, V, E, src, dest) { + // Initialize distance of all vertices as infinite. + const dis = Array(V).fill(Infinity) + // initialize distance of source as 0 + dis[src] = 0 + + // Relax all edges |V| - 1 times. A simple + // shortest path from src to any other + // vertex can have at-most |V| - 1 edges + for (let i = 0; i < V - 1; i++) { + for (let j = 0; j < E; j++) { + if ((dis[graph[j][0]] + graph[j][2]) < dis[graph[j][1]]) { dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2] } + } + } + // check for negative-weight cycles. + for (let i = 0; i < E; i++) { + const x = graph[i][0] + const y = graph[i][1] + const weight = graph[i][2] + if ((dis[x] !== Infinity) && (dis[x] + weight < dis[y])) { + return null + } + } + for (let i = 0; i < V; i++) { + if (i === dest) return dis[i] + } +} + +export { BellmanFord } diff --git a/Graphs/test/BellmanFord.test.js b/Graphs/test/BellmanFord.test.js new file mode 100644 index 0000000000..a5d8e2a856 --- /dev/null +++ b/Graphs/test/BellmanFord.test.js @@ -0,0 +1,34 @@ +import { BellmanFord } from '../BellmanFord.js' + +test('Test Case 1', () => { + const V = 5 + const E = 8 + const destination = 3 + const graph = [[0, 1, -1], [0, 2, 4], + [1, 2, 3], [1, 3, 2], + [1, 4, 2], [3, 2, 5], + [3, 1, 1], [4, 3, -3]] + const dist = BellmanFord(graph, V, E, 0, destination) + expect(dist).toBe(-2) +}) +test('Test Case 2', () => { + const V = 6 + const E = 9 + const destination = 4 + const graph = [[0, 1, 3], [0, 3, 6], + [0, 5, -1], [1, 2, -3], + [1, 4, -2], [5, 2, 5], + [2, 3, 1], [4, 3, 5], [5, 4, 2]] + const dist = BellmanFord(graph, V, E, 0, destination) + expect(dist).toBe(1) +}) +test('Test Case 3', () => { + const V = 4 + const E = 5 + const destination = 1 + const graph = [[0, 3, -1], [0, 2, 4], + [3, 2, 2], [3, 1, 5], + [2, 1, -1]] + const dist = BellmanFord(graph, V, E, 0, destination) + expect(dist).toBe(0) +})