mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-22 13:37:58 +01:00
Shortest path now uses a heap
Use a heap in dijkstra's algoritm to keep track of the shortest path. Change time from O(v^2) to O(u + v log(v)). @companje tijdens een college kwam een algoritme aan bod wat ik gebruikt heb in de slicer. Ik kwam er achter dat ik een fout had gemaakt waardoor het algoritme een stuk trager was als zou moeten. Door een binary heap te gebruiken is het algoritme een stuk sneller. Dit algoritme rekent een kortste pad uit en wordt gebruikt in de `comb` functie.
This commit is contained in:
parent
3b440b346a
commit
13ffea4115
5961
package-lock.json
generated
5961
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,7 @@
|
||||
"@doodle3d/doodle3d-core": "github:doodle3d/doodle3d-core",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"file-saver": "^1.3.3",
|
||||
"heap": "^0.2.6",
|
||||
"lodash": "^4.17.4",
|
||||
"material-ui": "^0.19.4",
|
||||
"material-ui-icons": "^1.0.0-beta.17",
|
||||
|
@ -1,3 +1,4 @@
|
||||
import Heap from 'heap';
|
||||
import { angle, subtract, distanceTo } from './vector2.js';
|
||||
|
||||
const graphs = new WeakMap();
|
||||
@ -147,40 +148,36 @@ function betweenAngles(n, a, b) {
|
||||
|
||||
// dijkstra's algorithm
|
||||
function shortestPath(graph, start, end) {
|
||||
const traverse = graph.map(() => -1);
|
||||
traverse[start] = start;
|
||||
const visited = graph.map(() => false);
|
||||
const distances = graph.map(() => Infinity);
|
||||
distances[start] = 0;
|
||||
const traverse = [];
|
||||
const queue = [];
|
||||
for (let i = 0; i < distances.length; i ++) {
|
||||
queue.push(i);
|
||||
}
|
||||
|
||||
while (queue.length > 0) {
|
||||
let queueIndex;
|
||||
let minDistance = Infinity;
|
||||
for (let index = 0; index < queue.length; index ++) {
|
||||
const nodeIndex = queue[index];
|
||||
const distance = distances[nodeIndex];
|
||||
if (distances[nodeIndex] < minDistance) {
|
||||
queueIndex = index;
|
||||
minDistance = distance;
|
||||
}
|
||||
}
|
||||
const heap = new Heap((a, b) => a.distance - b.distance);
|
||||
heap.push({ nodeIndex: start, distance: 0 });
|
||||
|
||||
for (let i = 0; i < graph.length; i ++) {
|
||||
let nodeIndex;
|
||||
do { nodeIndex = heap.pop().nodeIndex } while (visited[nodeIndex]);
|
||||
|
||||
if (nodeIndex === end) break;
|
||||
|
||||
const [nodeIndex] = queue.splice(queueIndex, 1);
|
||||
const node = graph[nodeIndex];
|
||||
visited[nodeIndex] = true;
|
||||
|
||||
for (let i = 0; i < node.length; i ++) {
|
||||
const child = node[i];
|
||||
const distance = distances[nodeIndex] + child.distance;
|
||||
if (distance < distances[child.to]) {
|
||||
heap.push({ nodeIndex: child.to, distance });
|
||||
distances[child.to] = distance;
|
||||
traverse[child.to] = nodeIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!traverse.hasOwnProperty(end)) return null;
|
||||
if (traverse[end] === -1) return null;
|
||||
|
||||
const path = [end];
|
||||
let nodeIndex = end;
|
||||
|
Loading…
Reference in New Issue
Block a user