Skip to content

Commit 1715f89

Browse files
committed
dijkstra
1 parent a7c7234 commit 1715f89

File tree

5 files changed

+262
-0
lines changed

5 files changed

+262
-0
lines changed

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,62 @@ console.log(g.V); // display 13, which is the number of vertices in g
7272
console.log(g.adj(0)); // display the adjacency list which are vertices directed from vertex 0
7373
```
7474

75+
### Create undirected weighted graph
76+
77+
The sample code below shows show to create undirected weighted graph:
78+
79+
```javascript
80+
var jsgraphs = require('js-graph-algorithms');
81+
var g = new jsgraphs.WeightedGraph(8);
82+
g.addEdge(new jsgraphs.Edge(0, 7, 0.16));
83+
g.addEdge(new jsgraphs.Edge(2, 3, 0.17));
84+
g.addEdge(new jsgraphs.Edge(1, 7, 0.19));
85+
g.addEdge(new jsgraphs.Edge(0, 2, 0.26));
86+
g.addEdge(new jsgraphs.Edge(5, 7, 0.28));
87+
g.addEdge(new jsgraphs.Edge(1, 3, 0.29));
88+
g.addEdge(new jsgraphs.Edge(1, 5, 0.32));
89+
g.addEdge(new jsgraphs.Edge(2, 7, 0.34));
90+
g.addEdge(new jsgraphs.Edge(4, 5, 0.35));
91+
g.addEdge(new jsgraphs.Edge(1, 2, 0.36));
92+
g.addEdge(new jsgraphs.Edge(4, 7, 0.37));
93+
g.addEdge(new jsgraphs.Edge(0, 4, 0.38));
94+
g.addEdge(new jsgraphs.Edge(6, 2, 0.4));
95+
g.addEdge(new jsgraphs.Edge(3, 6, 0.52));
96+
g.addEdge(new jsgraphs.Edge(6, 0, 0.58));
97+
g.addEdge(new jsgraphs.Edge(6, 4, 0.93));
98+
99+
console.log(g.V); // display 13, which is the number of vertices in g
100+
console.log(g.adj(0)); // display the adjacency list which are undirected edges connected to vertex 0
101+
```
102+
103+
### Create directed weighted graph
104+
105+
The sample code below shows show to create directed weighted graph:
106+
107+
```javascript
108+
var jsgraphs = require('js-graph-algorithms');
109+
var g = new jsgraphs.WeightedDiGraph(8);
110+
g.addEdge(new jsgraphs.Edge(0, 7, 0.16));
111+
g.addEdge(new jsgraphs.Edge(2, 3, 0.17));
112+
g.addEdge(new jsgraphs.Edge(1, 7, 0.19));
113+
g.addEdge(new jsgraphs.Edge(0, 2, 0.26));
114+
g.addEdge(new jsgraphs.Edge(5, 7, 0.28));
115+
g.addEdge(new jsgraphs.Edge(1, 3, 0.29));
116+
g.addEdge(new jsgraphs.Edge(1, 5, 0.32));
117+
g.addEdge(new jsgraphs.Edge(2, 7, 0.34));
118+
g.addEdge(new jsgraphs.Edge(4, 5, 0.35));
119+
g.addEdge(new jsgraphs.Edge(1, 2, 0.36));
120+
g.addEdge(new jsgraphs.Edge(4, 7, 0.37));
121+
g.addEdge(new jsgraphs.Edge(0, 4, 0.38));
122+
g.addEdge(new jsgraphs.Edge(6, 2, 0.4));
123+
g.addEdge(new jsgraphs.Edge(3, 6, 0.52));
124+
g.addEdge(new jsgraphs.Edge(6, 0, 0.58));
125+
g.addEdge(new jsgraphs.Edge(6, 4, 0.93));
126+
127+
console.log(g.V); // display 13, which is the number of vertices in g
128+
console.log(g.adj(0)); // display the adjacency list which are directed edges from vertex 0
129+
```
130+
75131
### Depth First Search
76132

77133
The sample code below show how to perform depth first search of an undirected graph
@@ -264,4 +320,39 @@ for(var i=0; i < mst.length; ++i) {
264320
var w = e.other(v);
265321
console.log('(' + v + ', ' + w + '): ' + e.weight);
266322
}
323+
```
324+
325+
### Use Eager Prim algorithm to find the minimum spanning tree of a weighted graph
326+
327+
The sample code below show how to obtain the minimum spanning tree from a weighted graph using Eager Prim algorithm:
328+
329+
```javascript
330+
var jsgraphs = require('js-graph-algorithms');
331+
var g = new jsgraphs.WeightedGraph(8);
332+
333+
g.addEdge(new jsgraphs.Edge(0, 7, 0.16));
334+
g.addEdge(new jsgraphs.Edge(2, 3, 0.17));
335+
g.addEdge(new jsgraphs.Edge(1, 7, 0.19));
336+
g.addEdge(new jsgraphs.Edge(0, 2, 0.26));
337+
g.addEdge(new jsgraphs.Edge(5, 7, 0.28));
338+
g.addEdge(new jsgraphs.Edge(1, 3, 0.29));
339+
g.addEdge(new jsgraphs.Edge(1, 5, 0.32));
340+
g.addEdge(new jsgraphs.Edge(2, 7, 0.34));
341+
g.addEdge(new jsgraphs.Edge(4, 5, 0.35));
342+
g.addEdge(new jsgraphs.Edge(1, 2, 0.36));
343+
g.addEdge(new jsgraphs.Edge(4, 7, 0.37));
344+
g.addEdge(new jsgraphs.Edge(0, 4, 0.38));
345+
g.addEdge(new jsgraphs.Edge(6, 2, 0.4));
346+
g.addEdge(new jsgraphs.Edge(3, 6, 0.52));
347+
g.addEdge(new jsgraphs.Edge(6, 0, 0.58));
348+
g.addEdge(new jsgraphs.Edge(6, 4, 0.93));
349+
350+
var prim = new jsgraphs.EagerPrimMST(g);
351+
var mst = prim.mst;
352+
for(var i=0; i < mst.length; ++i) {
353+
var e = mst[i];
354+
var v = e.either();
355+
var w = e.other(v);
356+
console.log('(' + v + ', ' + w + '): ' + e.weight);
357+
}
267358
```

src/jsgraphs.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,19 @@ var jsgraphs = jsgraphs || {};
437437

438438
jss.WeightedGraph = WeightedGraph;
439439

440+
var WeightedDiGraph = function(V) {
441+
WeightedGraph.call(this, V);
442+
};
443+
444+
WeightedDiGraph.prototype = Object.create(jss.WeightedGraph.prototype);
445+
446+
WeightedDiGraph.prototype.addEdge = function(e) {
447+
var v = e.from();
448+
this.adjList[v].push(e);
449+
};
450+
451+
jss.WeightedDiGraph = WeightedDiGraph;
452+
440453
var DepthFirstSearch = function(G, s) {
441454
this.s = s;
442455
var V = G.V;
@@ -758,6 +771,79 @@ var jsgraphs = jsgraphs || {};
758771
};
759772

760773
jss.EagerPrimMST = EagerPrimMST;
774+
775+
var Dijkstra = function(G, s) {
776+
var V = G.V;
777+
this.s = s;
778+
this.marked = [];
779+
this.edgeTo = [];
780+
this.cost = [];
781+
this.pq = new jss.IndexMinPQ(V, function(cost1, cost2){
782+
return cost1, cost2;
783+
});
784+
785+
for(var v =0; v < V; ++v){
786+
this.marked.push(false);
787+
this.edgeTo.push(null);
788+
this.cost.push(Number.MAX_VALUE);
789+
}
790+
791+
this.cost[s] = 0;
792+
793+
this.pq.insert(s, this.cost[s]);
794+
795+
while(!this.pq.isEmpty()) {
796+
var v = this.pq.delMin();
797+
this.marked[v] = true;
798+
var adj_v = G.adj(v);
799+
for(var i = 0; i < adj_v.length; ++i) {
800+
var e = adj_v[i];
801+
this.relax(e);
802+
}
803+
}
804+
805+
};
806+
807+
808+
809+
810+
Dijkstra.prototype.relax = function(e) {
811+
812+
var v = e.from();
813+
var w = e.to();
814+
815+
if(this.cost[w] > this.cost[v] + e.weight) {
816+
this.cost[w] = this.cost[v] + e.weight;
817+
this.edgeTo[w] = e;
818+
if(this.pq.containsIndex(w)){
819+
this.pq.decreaseKey(w, this.cost[w]);
820+
} else {
821+
this.pq.insert(w, this.cost[w]);
822+
}
823+
}
824+
};
825+
826+
827+
828+
Dijkstra.prototype.hasPathTo = function(v) {
829+
return this.marked[v];
830+
};
831+
832+
833+
Dijkstra.prototype.pathTo = function(v) {
834+
var path = new jss.Stack();
835+
for(var x = v; x != this.s; x = this.edgeTo[x].from()) {
836+
path.push(this.edgeTo[x]);
837+
}
838+
return path.toArray();
839+
};
840+
841+
Dijkstra.prototype.distanceTo = function(v) {
842+
return this.cost[v];
843+
};
844+
845+
846+
jss.Dijkstra = Dijkstra;
761847

762848
})(jsgraphs);
763849

test/dijkstra-spec.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
var expect = require('chai').expect;
2+
var jsgraphs = require('../src/jsgraphs');
3+
4+
describe('Dijkstra', function(){
5+
it('should get shortest path from Weigthed Directed Graph', function(){
6+
var g = new jsgraphs.WeightedDiGraph(8);
7+
g.addEdge(new jsgraphs.Edge(0, 1, 5.0));
8+
g.addEdge(new jsgraphs.Edge(0, 4, 9.0));
9+
g.addEdge(new jsgraphs.Edge(0, 7, 8.0));
10+
g.addEdge(new jsgraphs.Edge(1, 2, 12.0));
11+
g.addEdge(new jsgraphs.Edge(1, 3, 15.0));
12+
g.addEdge(new jsgraphs.Edge(1, 7, 4.0));
13+
g.addEdge(new jsgraphs.Edge(2, 3, 3.0));
14+
g.addEdge(new jsgraphs.Edge(2, 6, 11.0));
15+
g.addEdge(new jsgraphs.Edge(3, 6, 9.0));
16+
g.addEdge(new jsgraphs.Edge(4, 5, 5.0));
17+
g.addEdge(new jsgraphs.Edge(4, 6, 20.0));
18+
g.addEdge(new jsgraphs.Edge(4, 7, 5.0));
19+
g.addEdge(new jsgraphs.Edge(5, 2, 1.0));
20+
g.addEdge(new jsgraphs.Edge(5, 6, 13.0));
21+
g.addEdge(new jsgraphs.Edge(7, 5, 6.0));
22+
g.addEdge(new jsgraphs.Edge(7, 2, 7.0));
23+
24+
expect(g.V).to.equal(8);
25+
var edgeCount = 0;
26+
for(var v = 0; v < g.V; ++v){
27+
var adj_v = g.adj(v);
28+
edgeCount += adj_v.length;
29+
}
30+
expect(edgeCount).to.equal(16);
31+
32+
var dijkstra = new jsgraphs.Dijkstra(g, 0);
33+
34+
for(var v = 1; v < g.V; ++v){
35+
if(dijkstra.hasPathTo(v)){
36+
var path = dijkstra.pathTo(v);
37+
console.log('=====path from 0 to ' + v + ' start==========');
38+
for(var i = 0; i < path.length; ++i) {
39+
var e = path[i];
40+
console.log(e.from() + ' => ' + e.to() + ': ' + e.weight);
41+
}
42+
console.log('=====path from 0 to ' + v + ' end==========');
43+
console.log('=====distance: ' + dijkstra.distanceTo(v) + '=========');
44+
}
45+
}
46+
});
47+
});

test/weighted-digraph-spec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var expect = require('chai').expect;
2+
var jsgraphs = require('../src/jsgraphs');
3+
4+
describe('Weigthed Directed Graph', function(){
5+
it('should be weighted and directed', function(){
6+
var g = new jsgraphs.WeightedDiGraph(8);
7+
g.addEdge(new jsgraphs.Edge(0, 1, 5.0));
8+
g.addEdge(new jsgraphs.Edge(0, 4, 9.0));
9+
g.addEdge(new jsgraphs.Edge(0, 7, 8.0));
10+
g.addEdge(new jsgraphs.Edge(1, 2, 12.0));
11+
g.addEdge(new jsgraphs.Edge(1, 3, 15.0));
12+
g.addEdge(new jsgraphs.Edge(1, 7, 4.0));
13+
g.addEdge(new jsgraphs.Edge(2, 3, 3.0));
14+
g.addEdge(new jsgraphs.Edge(2, 6, 11.0));
15+
g.addEdge(new jsgraphs.Edge(3, 6, 9.0));
16+
g.addEdge(new jsgraphs.Edge(4, 5, 5.0));
17+
g.addEdge(new jsgraphs.Edge(4, 6, 20.0));
18+
g.addEdge(new jsgraphs.Edge(4, 7, 5.0));
19+
g.addEdge(new jsgraphs.Edge(5, 2, 1.0));
20+
g.addEdge(new jsgraphs.Edge(5, 6, 13.0));
21+
g.addEdge(new jsgraphs.Edge(7, 5, 6.0));
22+
g.addEdge(new jsgraphs.Edge(7, 2, 7.0));
23+
24+
expect(g.V).to.equal(8);
25+
var edgeCount = 0;
26+
for(var v = 0; v < g.V; ++v){
27+
var adj_v = g.adj(v);
28+
edgeCount += adj_v.length;
29+
}
30+
expect(edgeCount).to.equal(16);
31+
});
32+
});

test/weighted-graph-spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ describe("Create various types of Weighted Graphs", function() {
4040

4141
expect(found).to.equal(true);
4242
}
43+
44+
var edgeCount = 0;
45+
for (var v = 0; v < g.V; ++v) {
46+
edgeCount+=g.adj(v).length;
47+
}
48+
expect(edgeCount).to.equal(32);
4349
});
4450
});
4551

0 commit comments

Comments
 (0)