Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 93ce399

Browse files
committed
chapter 13: graphs
1 parent 6d1b9f2 commit 93ce399

16 files changed

+858
-0
lines changed

‎src/13-graph/01-airline-system.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// src/13-graph/01-airline-system.js
2+
3+
// import the Graph class
4+
const Graph = require('./graph');
5+
6+
const airline = new Graph();
7+
8+
const airports = 'MCO TPA JFK LAX SFO'.split(' ');
9+
10+
airports.forEach(airport =>
11+
airline.addVertex(airport)
12+
);
13+
14+
airline.addEdge('MCO', 'JFK');
15+
airline.addEdge('MCO', 'LAX');
16+
airline.addEdge('TPA', 'JFK');
17+
airline.addEdge('TPA', 'LAX');
18+
airline.addEdge('JFK', 'LAX');
19+
airline.addEdge('JFK', 'SFO');
20+
airline.addEdge('LAX', 'SFO');
21+
22+
console.log(airline.toString());
23+
24+
// Output:
25+
// MCO -> JFK LAX
26+
// TPA -> JFK LAX
27+
// JFK -> MCO TPA LAX SFO
28+
// LAX -> MCO TPA JFK SFO
29+
// SFO -> JFK LAX
30+
31+
// to see the output of this file use the command: node src/13-graph/01-airline-system.js

‎src/13-graph/02-using-bfs.js‎

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// src/13-graph/02-using-bfs.js
2+
3+
const Graph = require('./graph');
4+
const { breadthFirstSearch, bfsShortestPath} = require('./bfs');
5+
6+
const airline = new Graph();
7+
8+
const airports = 'SEA SFO LAX LAS DEN DFW STL MDW JFK ATL MCO MIA'.split(' ');
9+
10+
airports.forEach(airport =>
11+
airline.addVertex(airport)
12+
);
13+
14+
airline.addEdge('SEA', 'SFO');
15+
airline.addEdge('SEA', 'DEN');
16+
airline.addEdge('SEA', 'MDW');
17+
airline.addEdge('SFO', 'LAX');
18+
airline.addEdge('LAX', 'LAS');
19+
airline.addEdge('DEN', 'DFW');
20+
airline.addEdge('DEN', 'STL');
21+
airline.addEdge('STL', 'MDW');
22+
airline.addEdge('STL', 'MCO');
23+
airline.addEdge('MDW', 'ATL');
24+
airline.addEdge('MDW', 'JFK');
25+
airline.addEdge('ATL', 'JFK');
26+
airline.addEdge('JFK', 'MCO');
27+
airline.addEdge('JFK', 'MIA');
28+
29+
console.log(airline.toString());
30+
31+
// Output:
32+
// SEA -> SFO DEN MDW
33+
// SFO -> SEA LAX
34+
// LAX -> SFO LAS
35+
// LAS -> LAX
36+
// DEN -> SEA DFW STL
37+
// DFW -> DEN
38+
// STL -> DEN MDW MCO
39+
// MDW -> SEA STL ATL JFK
40+
// JFK -> MDW ATL MCO MIA
41+
// ATL -> MDW JFK
42+
// MCO -> STL JFK
43+
// MIA -> JFK
44+
45+
console.log('--- BFS ---');
46+
47+
const printAirport = (value) => console.log('Visited airport: ' + value);
48+
49+
breadthFirstSearch(airline,'SEA', printAirport);
50+
51+
// Output:
52+
// --- BFS ---
53+
// Visited airport: SEA
54+
// Visited airport: SFO
55+
// Visited airport: DEN
56+
// Visited airport: MDW
57+
// Visited airport: LAX
58+
// Visited airport: DFW
59+
// Visited airport: STL
60+
// Visited airport: ATL
61+
// Visited airport: JFK
62+
// Visited airport: LAS
63+
// Visited airport: MCO
64+
// Visited airport: MIA
65+
66+
console.log('--- BFS Shortest Path ---');
67+
68+
const shortestPath = bfsShortestPath(airline, 'SEA');
69+
console.log(shortestPath);
70+
71+
// { distances: { SEA: 0, SFO: 1, LAX: 2, LAS: 3, DEN: 1, DFW: 2, STL: 2, MDW: 1, JFK: 2, ATL: 2, MCO: 3, MIA: 3 },
72+
// predecessors: { SEA: null, SFO: 'SEA', LAX: 'SFO', LAS: 'LAX', DEN: 'SEA', DFW: 'DEN', STL: 'DEN', MDW: 'SEA', JFK: 'MDW', ATL: 'MDW', MCO: 'STL', MIA: 'JFK'}
73+
// }
74+
75+
// find the shortest path from SEA to JFK
76+
let path = [];
77+
for (let v = 'JFK'; v !== 'SEA'; v = shortestPath.predecessors[v]) {
78+
path.push(v);
79+
}
80+
path.push('SEA');
81+
path.reverse();
82+
83+
console.log('Shortest path from SEA to JFK: ' + path.join(' -> '));
84+
85+
// Shortest path from SEA to JFK: SEA -> MDW -> JFK
86+
87+
// to see the output of this file use the command: node src/13-graph/02-using-bfs.js

‎src/13-graph/03-using-dfs.js‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// src/13-graph/03-using-dfs.js
2+
3+
const Graph = require('./graph');
4+
const { depthFirstSearch, enhancedDepthFirstSearch } = require('./dfs');
5+
6+
const caveSystem = new Graph();
7+
8+
const caves = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
9+
10+
caves.forEach(cave => caveSystem.addVertex(cave));
11+
12+
13+
caveSystem.addEdge('A', 'B');
14+
caveSystem.addEdge('A', 'C');
15+
caveSystem.addEdge('A', 'D');
16+
caveSystem.addEdge('C', 'D');
17+
caveSystem.addEdge('C', 'G');
18+
caveSystem.addEdge('D', 'G');
19+
caveSystem.addEdge('D', 'H');
20+
caveSystem.addEdge('B', 'E');
21+
caveSystem.addEdge('B', 'F');
22+
caveSystem.addEdge('E', 'I');
23+
24+
console.log('********* DFS - cave ***********');
25+
depthFirstSearch(caveSystem, (cave) => console.log('Visited cave:',cave));
26+
27+
// ********* DFS - cave ***********
28+
// Visited cave: A
29+
// Visited cave: B
30+
// Visited cave: E
31+
// Visited cave: I
32+
// Visited cave: F
33+
// Visited cave: C
34+
// Visited cave: D
35+
// Visited cave: G
36+
// Visited cave: H
37+
38+
console.log('********* Enhanced DFS - cave ***********');
39+
const result = enhancedDepthFirstSearch(caveSystem);
40+
41+
console.log(result);
42+
43+
console.log('********* Topological sort using DFS ***********');
44+
45+
const tasks = new Graph(true); // this is a directed graph
46+
['A', 'B', 'C', 'D', 'E', 'F'].forEach(task => tasks.addVertex(task));
47+
// add the arrows, task dependencies:
48+
tasks.addEdge('A', 'C');
49+
tasks.addEdge('A', 'D');
50+
tasks.addEdge('B', 'D');
51+
tasks.addEdge('B', 'E');
52+
tasks.addEdge('C', 'F');
53+
tasks.addEdge('F', 'E');
54+
55+
// DFS traversal
56+
const dfsTasks = enhancedDepthFirstSearch(tasks);
57+
console.log(dfsTasks);
58+
// {
59+
// discovery: { A: 1, B: 11, C: 2, D: 8, E: 4, F: 3 },
60+
// finished: { A: 10, B: 12, C: 7, D: 9, E: 5, F: 6 },
61+
// predecessors: { A: null, B: null, C: 'A', D: 'A', E: 'F', F: 'C' }
62+
// }
63+
64+
// sort tasks in decreasing order of finish time
65+
// dfsTasks.finished = { A: 10, B: 12, C: 7, D: 9, E: 5, F: 6 }
66+
const sortedTasks = Object.keys(dfsTasks.finished).sort((a, b) => dfsTasks.finished[b] - dfsTasks.finished[a]);
67+
console.log(sortedTasks);
68+
// [ 'B', 'A', 'D', 'C', 'F', 'E' ]
69+
70+
// to see the output of this file use the command: node src/13-graph/03-using-dfs.js

‎src/13-graph/04-using-dijkstra.js‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// src/13-graph/04-using-dijkstra.js
2+
3+
const Graph = require('./graph');
4+
const dijkstra = require('./dijkstra');
5+
6+
const flightCosts = [
7+
// SEA, MDW, DEN, MCO, STL, JFK, ATL
8+
[0, 300, 220, 1000, 0, 0, 0], // SEA
9+
[300, 0, 0, 0, 50, 210, 190], // MDW
10+
[220, 0, 0, 0, 350, 0, 0], // DEN
11+
[1000, 0, 0, 0, 150, 250, 0], // MCO
12+
[0, 50, 350, 150, 0, 0, 0], // STL
13+
[0, 210, 0, 250, 0, 0, 200], // JFK
14+
[0, 190, 0, 0, 0, 200, 0], // ATL
15+
];
16+
17+
console.log('********* Dijkstra\'s Algorithm - Shortest Path ***********');
18+
19+
const prices = dijkstra(flightCosts, 0); // SEA
20+
// prices output:
21+
// {
22+
// distances: [
23+
// 0, 300, 220,
24+
// 500, 350, 510,
25+
// 490
26+
// ],
27+
// predecessors: {
28+
// '0': [ 0 ],
29+
// '1': [ 0, 1 ],
30+
// '2': [ 0, 2 ],
31+
// '3': [ 0, 1, 4, 3 ],
32+
// '4': [ 0, 1, 4 ],
33+
// '5': [ 0, 1, 5 ],
34+
// '6': [ 0, 1, 6 ]
35+
// }
36+
// }
37+
console.log('Prices from SEA to all airports:');
38+
const airports = ['SEA', 'MDW', 'DEN', 'MCO', 'STL', 'JFK', 'ATL'];
39+
for (let i = 1; i < airports.length; i++) {
40+
const flights = prices.predecessors[i].map(airport => airports[airport]).join(' -> ');
41+
console.log(`SEA -> ${airports[i]}: $${prices.distances[i]} via ${flights}`);
42+
}
43+
// Prices from SEA to all airports:
44+
// SEA -> MDW: 300ドル via SEA -> MDW
45+
// SEA -> DEN: 220ドル via SEA -> DEN
46+
// SEA -> MCO: 500ドル via SEA -> MDW -> STL -> MCO
47+
// SEA -> STL: 350ドル via SEA -> MDW -> STL
48+
// SEA -> JFK: 510ドル via SEA -> MDW -> JFK
49+
// SEA -> ATL: 490ドル via SEA -> MDW -> ATL
50+
51+
// to see the output of this file use the command: node src/13-graph/04-using-dijkstra.js
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// src/13-graph/05-using-floyd-warshall.js
2+
3+
const floydWarshall = require('./floyd-warshall');
4+
5+
const INF = Infinity;
6+
const flightCosts = [
7+
// SEA, MDW, DEN, MCO, STL, JFK, ATL
8+
[INF, 300, 220, 1000, INF, INF, INF], // SEA
9+
[300, INF, INF, INF, 50, 210, 190], // MDW
10+
[220, INF, INF, INF, 350, INF, INF], // DEN
11+
[1000, INF, INF, INF, 150, 250, INF], // MCO
12+
[INF, 50, 350, 150, INF, INF, INF], // STL
13+
[INF, 210, INF, 250, INF, INF, 200], // JFK
14+
[INF, 190, INF, INF, INF, 200, INF], // ATL
15+
];
16+
17+
console.log('********* Floyd-Warshall Algorithm - Shortest Path ***********');
18+
19+
const distances = floydWarshall(flightCosts);
20+
console.log('Distances between all airports:');
21+
22+
const airports = ['SEA', 'MDW', 'DEN', 'MCO', 'STL', 'JFK', 'ATL'];
23+
console.table(airports.map((airport, i) => {
24+
return airports.reduce((acc, dest, j) => {
25+
acc[dest] = distances[i][j];
26+
return acc;
27+
}, {});
28+
}));
29+
30+
// ┌─────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
31+
// │ Airport │ SEA │ MDW │ DEN │ MCO │ STL │ JFK │ ATL │
32+
// ├─────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
33+
// │ SEA │ 0 │ 300 │ 220 │ 500 │ 350 │ 510 │ 490 │
34+
// │ MDW │ 300 │ 0 │ 400 │ 200 │ 50 │ 210 │ 190 │
35+
// │ DEN │ 220 │ 400 │ 0 │ 500 │ 350 │ 610 │ 590 │
36+
// │ MCO │ 500 │ 200 │ 500 │ 0 │ 150 │ 250 │ 390 │
37+
// │ STL │ 350 │ 50 │ 350 │ 150 │ 0 │ 260 │ 240 │
38+
// │ JFK │ 510 │ 210 │ 610 │ 250 │ 260 │ 0 │ 200 │
39+
// │ ATL │ 490 │ 190 │ 590 │ 390 │ 240 │ 200 │ 0 │
40+
// └─────────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
41+
42+
// to see the output of this file use the command: node src/13-graph/05-using-floyd-warshall.js

‎src/13-graph/06-using-prim.js‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// src/13-graph/06-using-prim.js
2+
3+
const prim = require('./prim');
4+
5+
const cityNames = ['Erebor', 'Rivendell', 'Hobbiton', 'Isengard', 'Rohan', 'Lothlorien'];
6+
7+
const cities = [
8+
[0, 2, 4, 0, 0, 0],
9+
[2, 0, 2, 4, 2, 0],
10+
[4, 2, 0, 0, 3, 0],
11+
[0, 4, 0, 0, 3, 2],
12+
[0, 2, 3, 3, 0, 2],
13+
[0, 0, 0, 2, 2, 0]
14+
];
15+
16+
const mst = prim(cities);
17+
console.log('Minimum Spanning Tree:', mst);
18+
19+
// [ -1, 0, 1, 5, 1, 4 ]
20+
21+
// to see the output of this file use the command: node src/13-graph/06-using-prim.js

‎src/13-graph/07-using-kruskal.js‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// src/13-graph/07-using-kruskal.js
2+
3+
const kruskal = require('./kruskal');
4+
5+
const cityNames = ['Erebor', 'Rivendell', 'Hobbiton', 'Isengard', 'Rohan', 'Lothlorien'];
6+
7+
const cities = [
8+
[0, 2, 4, 0, 0, 0],
9+
[2, 0, 2, 4, 2, 0],
10+
[4, 2, 0, 0, 3, 0],
11+
[0, 4, 0, 0, 3, 2],
12+
[0, 2, 3, 3, 0, 2],
13+
[0, 0, 0, 2, 2, 0]
14+
];
15+
16+
const mst = kruskal(cities);
17+
18+
console.log('Minimum Spanning Tree with Kruskal:', mst);
19+
20+
// [ [ 0, 1 ], [ 1, 2 ], [ 1, 4 ], [ 3, 5 ], [ 4, 5 ] ]
21+
22+
// to see the output of this file use the command: node src/13-graph/07-using-kruskal.js

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /