feat: prims basic implementation without PQ
This commit is contained in:
parent
c0ce0f15d9
commit
d9d8d06b8a
5 changed files with 4195 additions and 335 deletions
3687
package-lock.json
generated
Normal file
3687
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -14,10 +14,13 @@
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.7.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest DFSOnBST LRU LinearSearchList BinarySearchList TwoCrystalBalls BubbleSort DoublyLinkedList Queue Stack ArrayList MazeSolver QuickSort BTPreOrder BTInOrder BTPostOrder BTBFS CompareBinaryTrees DFSOnBST DFSGraphList Trie BFSGraphMatrix Map MinHeap",
|
"test": "jest PrimsList",
|
||||||
"clear": "node ./scripts/clear.js",
|
"clear": "node ./scripts/clear.js",
|
||||||
"prettier": "prettier --write ./src",
|
"prettier": "prettier --write ./src",
|
||||||
"generate": "node ./scripts/generate.js",
|
"generate": "node ./scripts/generate.js",
|
||||||
"day": "echo src\\day2"
|
"day": "echo src/day4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@swc-node/register": "^1.6.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
92
src/golden/PrimList.ts
Normal file
92
src/golden/PrimList.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
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 },
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"target": "es6",
|
"target": "esnext",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"baseUrl": "src",
|
"baseUrl": "src",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@code/*": [
|
"@code/*": [
|
||||||
"day2/*"
|
"day4/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue