(function (exports) { 'use strict'; var dijkstra = (function () { var Heap = require('../../data-structures/heap.js').Heap; var current; var visited; var distance; var unvisited; /** * Creates a new node instance. * * @constructor * @private * @param {Number} id Id of the node. * @param {Number} distance Distance from the beginning. */ function Node(id, distance) { this.node = id; this.distance = distance; } /** * Compares the distances between two nodes. * * @private * @param {Node} a 1st node. * @param {Node} b 2nd node. * @returns {number} diff between node distances. */ function compareNodesDistance(a, b) { return b.distance - a.distance; } /** * Initialize all variables used for the algorithm. * * @private * @param {number} src Start node. * @param {Array} graph A distance matrix of the graph. */ function init(src, graph) { var currentTemp; current = {}; visited = []; distance = []; unvisited = new Heap(compareNodesDistance); for (var i = 0; i < graph.length; i += 1) { currentTemp = new Node(); if (src === i) { currentTemp.distance = 0; } else { currentTemp.distance = Infinity; } currentTemp.node = i; visited[i] = false; distance[i] = currentTemp; unvisited.add(currentTemp); } current.node = src; current.distance = 0; } /** * Dijkstra's shortest path algorithm. Finds the minimum * distance between two given nodes using a distance matrix.

* For the implementation is not used the most suitable data structure * (Fibonacci heap) but the Binary heap gives also good results.

* * Time complexity: O(|E|+|V|log(|V|)) where V and E are the number of * vertices and edges respectively. * * @public * @module graphs/shortest-path/dijkstra * @param {Number} src Source node. * @param {Number} dest Destination node. * @param {Array} graph A distance matrix of the graph. * @returns {Number} The shortest distance between two nodes. * * @example * var dijkstra = * require('path-to-algorithms/src/graphs/shortest-path/dijkstra').dijkstra; * var distMatrix = * [[Infinity, 7, 9, Infinity, Infinity, 16], * [7, Infinity, 10, 15, Infinity, Infinity], * [9, 10, Infinity, 11, Infinity, 2], * [Infinity, 15, 11, Infinity, 6, Infinity], * [Infinity, Infinity, Infinity, 6, Infinity, 9], * [16, Infinity, 2, Infinity, 9, Infinity]]; * var shortestDist = dijkstra(0, 2, distMatrix); // 9 */ return function (src, dest, graph) { var tempDistance = 0; init(src, graph); while (current.node !== dest && isFinite(current.distance)) { for (var i = 0; i < graph.length; i += 1) { if (current.node !== i && //if it's not the current node !visited[i] && //and if we haven't visited this node //and this node is sibling of the current... Number.isFinite(graph[i][current.node])) { tempDistance = current.distance + graph[i][current.node]; if (tempDistance < distance[i].distance) { distance[i].distance = tempDistance; current.distance = tempDistance; unvisited.update(current); } } } visited[current.node] = true; current = unvisited.extract(); } if (distance[dest]) { return distance[dest].distance; } return Infinity; }; })(); exports.dijkstra = dijkstra; })(typeof window === 'undefined' ? module.exports : window);