mirror of
https://github.com/web3privacy/w3ps1.git
synced 2024-10-15 16:26:26 +02:00
107 lines
3 KiB
JavaScript
107 lines
3 KiB
JavaScript
var dijkstraExports = {};
|
|
var dijkstra = {
|
|
get exports() {
|
|
return dijkstraExports;
|
|
},
|
|
set exports(v) {
|
|
dijkstraExports = v;
|
|
}
|
|
};
|
|
(function(module) {
|
|
var dijkstra2 = {
|
|
single_source_shortest_paths: function(graph, s, d) {
|
|
var predecessors = {};
|
|
var costs = {};
|
|
costs[s] = 0;
|
|
var open = dijkstra2.PriorityQueue.make();
|
|
open.push(s, 0);
|
|
var closest, u, v, cost_of_s_to_u, adjacent_nodes, cost_of_e, cost_of_s_to_u_plus_cost_of_e, cost_of_s_to_v, first_visit;
|
|
while (!open.empty()) {
|
|
closest = open.pop();
|
|
u = closest.value;
|
|
cost_of_s_to_u = closest.cost;
|
|
adjacent_nodes = graph[u] || {};
|
|
for (v in adjacent_nodes) {
|
|
if (adjacent_nodes.hasOwnProperty(v)) {
|
|
cost_of_e = adjacent_nodes[v];
|
|
cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;
|
|
cost_of_s_to_v = costs[v];
|
|
first_visit = typeof costs[v] === "undefined";
|
|
if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
|
|
costs[v] = cost_of_s_to_u_plus_cost_of_e;
|
|
open.push(v, cost_of_s_to_u_plus_cost_of_e);
|
|
predecessors[v] = u;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (typeof d !== "undefined" && typeof costs[d] === "undefined") {
|
|
var msg = ["Could not find a path from ", s, " to ", d, "."].join("");
|
|
throw new Error(msg);
|
|
}
|
|
return predecessors;
|
|
},
|
|
extract_shortest_path_from_predecessor_list: function(predecessors, d) {
|
|
var nodes = [];
|
|
var u = d;
|
|
while (u) {
|
|
nodes.push(u);
|
|
predecessors[u];
|
|
u = predecessors[u];
|
|
}
|
|
nodes.reverse();
|
|
return nodes;
|
|
},
|
|
find_path: function(graph, s, d) {
|
|
var predecessors = dijkstra2.single_source_shortest_paths(graph, s, d);
|
|
return dijkstra2.extract_shortest_path_from_predecessor_list(
|
|
predecessors,
|
|
d
|
|
);
|
|
},
|
|
/**
|
|
* A very naive priority queue implementation.
|
|
*/
|
|
PriorityQueue: {
|
|
make: function(opts) {
|
|
var T = dijkstra2.PriorityQueue, t = {}, key;
|
|
opts = opts || {};
|
|
for (key in T) {
|
|
if (T.hasOwnProperty(key)) {
|
|
t[key] = T[key];
|
|
}
|
|
}
|
|
t.queue = [];
|
|
t.sorter = opts.sorter || T.default_sorter;
|
|
return t;
|
|
},
|
|
default_sorter: function(a, b) {
|
|
return a.cost - b.cost;
|
|
},
|
|
/**
|
|
* Add a new item to the queue and ensure the highest priority element
|
|
* is at the front of the queue.
|
|
*/
|
|
push: function(value, cost) {
|
|
var item = { value, cost };
|
|
this.queue.push(item);
|
|
this.queue.sort(this.sorter);
|
|
},
|
|
/**
|
|
* Return the highest priority element in the queue.
|
|
*/
|
|
pop: function() {
|
|
return this.queue.shift();
|
|
},
|
|
empty: function() {
|
|
return this.queue.length === 0;
|
|
}
|
|
}
|
|
};
|
|
{
|
|
module.exports = dijkstra2;
|
|
}
|
|
})(dijkstra);
|
|
export {
|
|
dijkstraExports as d
|
|
};
|