Skip to content

Commit 4350b94

Browse files
committed
Merge pull request #34 from quietshu/master
SPFA algorithm added
2 parents 5c6a696 + 4b3b8f7 commit 4350b94

File tree

3 files changed

+127
-1
lines changed

3 files changed

+127
-1
lines changed

algorithms/graph/SPFA.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* Copyright (C) 2014 Shu Ding
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to
6+
* deal in the Software without restriction, including without limitation the
7+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8+
* sell copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
* IN THE SOFTWARE.
21+
*/
22+
'use strict';
23+
24+
/**
25+
* Calculates the shortest paths in a graph to every node from the node s
26+
* with SPFA(Shortest Path Faster Algorithm) algorithm
27+
*
28+
* @param {Object} graph An adjacency list representing the graph
29+
* @param {string} start the starting node
30+
*
31+
*/
32+
function SPFA(graph, s) {
33+
var distance = {};
34+
var previous = {};
35+
var queue = {};
36+
var isInQue = {};
37+
var head = 0;
38+
var tail = 1;
39+
// initialize
40+
distance[s] = 0;
41+
queue[0] = s;
42+
isInQue[s] = true;
43+
graph.vertices.forEach(function (v) {
44+
if (v !== s) {
45+
distance[v] = Infinity;
46+
isInQue[v] = false;
47+
}
48+
});
49+
50+
var currNode;
51+
while (head != tail) {
52+
currNode = queue[head++];
53+
isInQue[currNode] = false;
54+
var neighbors = graph.neighbors(currNode);
55+
for (var i = 0; i < neighbors.length; i++) {
56+
var v = neighbors[i];
57+
// relaxation
58+
var newDistance = distance[currNode] + graph.edge(currNode, v);
59+
if (newDistance < distance[v]) {
60+
distance[v] = newDistance;
61+
previous[v] = currNode;
62+
if (!isInQue[v]){
63+
queue[tail++] = v;
64+
isInQue[v] = true;
65+
}
66+
}
67+
}
68+
}
69+
70+
return {
71+
distance: distance,
72+
previous: previous
73+
};
74+
}
75+
76+
module.exports = SPFA;

main.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
var lib = {
2525
Graph: {
2626
topologicalSort: require('./algorithms/graph/topological_sort'),
27-
dijkstra: require('./algorithms/graph/dijkstra')
27+
dijkstra: require('./algorithms/graph/dijkstra'),
28+
SPFA: require('./algorithms/graph/SPFA')
2829
},
2930
Math: {
3031
fibonacci: require('./algorithms/math/fibonacci'),

test/algorithms/graph/SPFA.js

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright (C) 2014 Felipe Ribeiro
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"], to
6+
* deal in the Software without restriction, including without limitation the
7+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8+
* sell copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
* IN THE SOFTWARE.
21+
*/
22+
'use strict';
23+
24+
var SPFA = require('../../../algorithms/graph/SPFA'),
25+
Graph = require('../../../data_structures/graph'),
26+
assert = require('assert');
27+
28+
describe('SPFA Algorithm', function () {
29+
it('should return the shortest paths to all nodes from a given origin',
30+
function () {
31+
var g = new Graph();
32+
g.addEdge('a', 'b', 5);
33+
g.addEdge('a', 'c', 10);
34+
g.addEdge('b', 'c', 2);
35+
g.addEdge('b', 'd', 20);
36+
g.addEdge('c', 'd', 1);
37+
g.addEdge('d', 'a', 10);
38+
39+
var shortestPath = SPFA(g, 'a');
40+
assert.equal(shortestPath.distance.b, 5);
41+
assert.equal(shortestPath.previous.b, 'a');
42+
43+
assert.equal(shortestPath.distance.c, 7);
44+
assert.equal(shortestPath.previous.c, 'b');
45+
46+
assert.equal(shortestPath.distance.d, 8);
47+
assert.equal(shortestPath.previous.d, 'c');
48+
});
49+
});

0 commit comments

Comments
 (0)