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",
|
"@doodle3d/doodle3d-core": "github:doodle3d/doodle3d-core",
|
||||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||||
"file-saver": "^1.3.3",
|
"file-saver": "^1.3.3",
|
||||||
|
"heap": "^0.2.6",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"material-ui": "^0.19.4",
|
"material-ui": "^0.19.4",
|
||||||
"material-ui-icons": "^1.0.0-beta.17",
|
"material-ui-icons": "^1.0.0-beta.17",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Heap from 'heap';
|
||||||
import { angle, subtract, distanceTo } from './vector2.js';
|
import { angle, subtract, distanceTo } from './vector2.js';
|
||||||
|
|
||||||
const graphs = new WeakMap();
|
const graphs = new WeakMap();
|
||||||
@ -147,40 +148,36 @@ function betweenAngles(n, a, b) {
|
|||||||
|
|
||||||
// dijkstra's algorithm
|
// dijkstra's algorithm
|
||||||
function shortestPath(graph, start, end) {
|
function shortestPath(graph, start, end) {
|
||||||
|
const traverse = graph.map(() => -1);
|
||||||
|
traverse[start] = start;
|
||||||
|
const visited = graph.map(() => false);
|
||||||
const distances = graph.map(() => Infinity);
|
const distances = graph.map(() => Infinity);
|
||||||
distances[start] = 0;
|
distances[start] = 0;
|
||||||
const traverse = [];
|
|
||||||
const queue = [];
|
|
||||||
for (let i = 0; i < distances.length; i ++) {
|
|
||||||
queue.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (queue.length > 0) {
|
const heap = new Heap((a, b) => a.distance - b.distance);
|
||||||
let queueIndex;
|
heap.push({ nodeIndex: start, distance: 0 });
|
||||||
let minDistance = Infinity;
|
|
||||||
for (let index = 0; index < queue.length; index ++) {
|
for (let i = 0; i < graph.length; i ++) {
|
||||||
const nodeIndex = queue[index];
|
let nodeIndex;
|
||||||
const distance = distances[nodeIndex];
|
do { nodeIndex = heap.pop().nodeIndex } while (visited[nodeIndex]);
|
||||||
if (distances[nodeIndex] < minDistance) {
|
|
||||||
queueIndex = index;
|
if (nodeIndex === end) break;
|
||||||
minDistance = distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const [nodeIndex] = queue.splice(queueIndex, 1);
|
|
||||||
const node = graph[nodeIndex];
|
const node = graph[nodeIndex];
|
||||||
|
visited[nodeIndex] = true;
|
||||||
|
|
||||||
for (let i = 0; i < node.length; i ++) {
|
for (let i = 0; i < node.length; i ++) {
|
||||||
const child = node[i];
|
const child = node[i];
|
||||||
const distance = distances[nodeIndex] + child.distance;
|
const distance = distances[nodeIndex] + child.distance;
|
||||||
if (distance < distances[child.to]) {
|
if (distance < distances[child.to]) {
|
||||||
|
heap.push({ nodeIndex: child.to, distance });
|
||||||
distances[child.to] = distance;
|
distances[child.to] = distance;
|
||||||
traverse[child.to] = nodeIndex;
|
traverse[child.to] = nodeIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!traverse.hasOwnProperty(end)) return null;
|
if (traverse[end] === -1) return null;
|
||||||
|
|
||||||
const path = [end];
|
const path = [end];
|
||||||
let nodeIndex = end;
|
let nodeIndex = end;
|
||||||
|
Loading…
Reference in New Issue
Block a user