-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPrimList.ts
More file actions
96 lines (87 loc) 路 2.93 KB
/
Copy pathPrimList.ts
File metadata and controls
96 lines (87 loc) 路 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
export default function prims(list: WeightedAdjacencyList): WeightedAdjacencyList | null {
// Prims algorithm :: minimum spanning tree
// What is a minimum spanning tree?
// - Requires no cycles
// - For it to technically be a minimum spanning tree, the graph requires
// to be strongly connected
// 1. Select starting node,
// 2. put edges of current selected node into a list
// 3. select edge that is the lowest value and to a node we haven't seen yet
// 4. we need to insert the edge from current to new into our mst
// 5. the newly selected node becomes the current node,
// 6. repeate to step 2 until unvisited is empty or unreachable
// ...
// 8. $$
const visited: boolean[] = new Array(list.length).fill(false);
const mst: GraphEdge[][] = new Array(list.length).fill(null).map(() => []);
// 1.
visited[0] = true;
let current = 0;
const edges: [number, GraphEdge][] = [];
do {
// 2. put all dem edges in the list
for (const edgemeDaddy of list[current]) {
edges.push([current, edgemeDaddy]);
}
// 3. select edge that is the lowest value and to a node we haven't seen yet
let lowest = Infinity;
let lowestEdge: [number, GraphEdge | null] = [-1, null];
for (const edge of edges) {
if (visited[edge[1].to] === false && edge[1].weight < lowest) {
lowest = edge[1].weight;
lowestEdge = edge;
}
}
// 4. we need to insert the edge from current to new into our mst, set visited, and remove the potential edge
if (lowestEdge[1] !== null) {
mst[lowestEdge[0]].push(lowestEdge[1]);
mst[lowestEdge[1].to].push({ to: lowestEdge[0], weight: lowestEdge[1].weight });
visited[lowestEdge[1].to] = true;
edges.splice(edges.indexOf(lowestEdge as [number, GraphEdge]), 1);
}
// 5. the newly selected node becomes the current node
current = lowestEdge[1]?.to || -1;
} while (visited.includes(false) && current >= 0);
return mst;
}
if (require.main === module) {
prims([
[
// 0
{ to: 2, weight: 1 },
{ to: 1, weight: 3 },
],
[
// 1
{ to: 0, weight: 3 },
{ to: 4, weight: 1 },
{ to: 3, weight: 3 },
],
[
// 2
{ to: 0, weight: 1 },
{ to: 3, weight: 7 },
],
[
// 3
{ to: 6, weight: 1 },
{ to: 1, weight: 3 },
{ to: 2, weight: 7 },
],
[
// 4
{ to: 1, weight: 1 },
{ to: 5, weight: 2 },
],
[
// 5
{ to: 4, weight: 2 },
{ to: 6, weight: 1 },
],
[
// 6
{ to: 5, weight: 1 },
{ to: 3, weight: 1 },
],
]);
}