91 lines
2.6 KiB
JavaScript
91 lines
2.6 KiB
JavaScript
/**
|
||
* Bellman–Ford algorithm computes shortest paths from a single source
|
||
* vertex to all of the other vertices in a weighted digraph
|
||
* (negative weights allowed).<br><br>
|
||
* Time complexity: O(|V||E|) where V and E are the number of
|
||
* vertices and edges respectively.
|
||
*
|
||
* @example
|
||
*
|
||
* var BellmanFord =
|
||
* require('path-to-algorithms/src/graphs/shortest-path/bellman-ford');
|
||
* var Edge = BellmanFord.Edge;
|
||
* var bellmanFord = BellmanFord.bellmanFord;
|
||
* var edges = [];
|
||
* var vertexes = [
|
||
* new Vertex(0),
|
||
* new Vertex(1),
|
||
* new Vertex(2),
|
||
* new Vertex(3),
|
||
* new Vertex(4)
|
||
* ];
|
||
*
|
||
* edges.push(new Edge(0, 1, -1));
|
||
* edges.push(new Edge(0, 2, 4));
|
||
* edges.push(new Edge(1, 2, 3));
|
||
* edges.push(new Edge(1, 3, 2));
|
||
* edges.push(new Edge(3, 1, 1));
|
||
* edges.push(new Edge(4, 3, -3));
|
||
* edges.push(new Edge(1, 4, 2));
|
||
* edges.push(new Edge(3, 2, 5));
|
||
*
|
||
* // {
|
||
* // parents: { '0': null, '1': 0, '2': 1, '3': 4, '4': 1 },
|
||
* // distances: { '0': 0, '1': -1, '2': 2, '3': -2, '4': 1 }
|
||
* // }
|
||
* var pathInfo = bellmanFord(vertexes, edges, 0);
|
||
*
|
||
* @module graphs/shortest-path/bellman-ford
|
||
*/
|
||
(function (exports) {
|
||
|
||
'use strict';
|
||
|
||
exports.Vertex = require('../../data-structures/vertex').Vertex;
|
||
exports.Edge = require('../../data-structures/edge').Edge;
|
||
|
||
/**
|
||
* Computes shortest paths from a single source
|
||
* vertex to all of the other vertices.
|
||
*
|
||
* @public
|
||
* @param {Array} vertexes Vertices of the graph.
|
||
* @param {Array} edges Edges of the graph.
|
||
* @param {Number} source Start vertex.
|
||
* @returns {Object} Object with two arrays (parents and distances)
|
||
* with shortest-path information or undefined if the graph
|
||
* has a negative cycle.
|
||
*/
|
||
exports.bellmanFord = function (vertexes, edges, source) {
|
||
var distances = {};
|
||
var parents = {};
|
||
var c;
|
||
if (source) {
|
||
for (var i = 0; i < vertexes.length; i += 1) {
|
||
distances[vertexes[i].id] = Infinity;
|
||
parents[vertexes[i].id] = null;
|
||
}
|
||
distances[source.id] = 0;
|
||
for (i = 0; i < vertexes.length - 1; i += 1) {
|
||
for (var j = 0; j < edges.length; j += 1) {
|
||
c = edges[j];
|
||
if (distances[c.from.id] + c.distance < distances[c.to.id]) {
|
||
distances[c.to.id] = distances[c.from.id] + c.distance;
|
||
parents[c.to.id] = c.from.id;
|
||
}
|
||
}
|
||
}
|
||
|
||
for (i = 0; i < edges.length; i += 1) {
|
||
c = edges[i];
|
||
if (distances[c.from.id] + c.distance < distances[c.to.id]) {
|
||
return undefined;
|
||
}
|
||
}
|
||
}
|
||
|
||
return { parents: parents, distances: distances };
|
||
};
|
||
|
||
})(typeof window === 'undefined' ? module.exports : window);
|