simscript
Version:
A Discrete Event Simulation Library in TypeScript
109 lines (108 loc) • 3.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Network = void 0;
const util_1 = require("./util");
;
class Network {
constructor(options) {
util_1.setOptions(this, options);
}
set nodes(value) {
this._nodes = value;
}
get nodes() {
return this._nodes;
}
set links(value) {
this._links = value;
}
get links() {
return this._links;
}
getNode(id) {
id = id.toString();
return this._nodes.find(nd => nd.id == id);
}
shortestPath(start, finish) {
const unvisited = [], visited = [];
this._nodes.forEach(node => {
unvisited.push({
id: node.id,
node: node,
distance: node == start ? 0 : Infinity,
link: null
});
});
while (unvisited.length) {
let current = null;
unvisited.forEach(pp => {
if (current == null || pp.distance < current.distance) {
current = pp;
}
});
unvisited.splice(unvisited.indexOf(current), 1);
visited.push(current);
if (unvisited.length) {
this._links.forEach(link => {
if (link.from == current.node && !link.disabled) {
unvisited.forEach(pp => {
if (pp.node == link.to) {
const distance = current.distance + this.getLinkDistance(link, current.link);
if (distance < pp.distance) {
pp.distance = distance;
pp.link = link;
}
}
});
}
});
}
}
const linkPath = [];
for (let node = finish; node != null;) {
const part = this._getPathPart(visited, node), link = part.link;
if (!link) {
break;
}
node = link.from;
linkPath.unshift(link);
}
return linkPath;
}
getLinkDistance(link, prevLink) {
let distance = null;
if (link.distance != null) {
distance = link.distance;
}
else {
util_1.assert(link.from.position != null && link.to.position != null, 'link must have a distance or connect points with positions');
distance = util_1.Point.distance(link.from.position, link.to.position);
}
return distance;
}
mergePath(path) {
const queues = [];
let dist = 0;
path.forEach((link, i) => {
dist += this.getLinkDistance(link, i > 0 ? path[i - 1] : null);
if (i == 0) {
queues.push(link.from.queue);
}
queues.push(link.to.queue);
});
return [queues, dist];
}
_getLinkAngle(link) {
return util_1.Point.angle(link.from.position, link.to.position, true);
}
_getPathPart(visited, node) {
for (let i = 0; i < visited.length; i++) {
let pp = visited[i];
if (pp.node == node) {
return pp;
}
}
return null;
}
}
exports.Network = Network;