该算法可用于关键路径的查找
算法介绍
参考 这里
代码
/**
* 只针对一个开始节点,一个结束节点的情况
*/
export class Aoe {
constructor(
public startNode: string, // 确定开始节点, 如果不想传入,可以通过edges查找
public edges: Edge[] = [],
) { }
getCriticalPath(): string[] {
const ee: Event[] = [];
const processNodes = [];
processNodes.push(this.startNode);
while(true) {
const node = processNodes.pop();
if(!node) {
break;
}
const edges = this.edges.filter(u => u.target === node);
if(edges.length == 0) {
ee.push(new Event(node, 0));
this.edges.filter(u => u.source === node).forEach(u => processNodes.push(u.target));
} else if (edges.filter(u => ee.findIndex(v => v.node === u.source) < 0).length === 0) {
const eeValue = edges.map(u => u.weight + ee.find(v=>v.node === u.source).weight).sort((a, b) => b - a)[0];
ee.push(new Event(node, eeValue));
this.edges.filter(u => u.source === node).forEach(u => processNodes.push(u.target));
}
}
const lastEvent = ee[ee.length - 1];
const le: Event[] = [];
processNodes.push(lastEvent.node);
while(true) {
const node = processNodes.pop();
if(!node) {
break;
}
const edges = this.edges.filter(u => u.source === node);
if(edges.length == 0) {
le.push(new Event(node, lastEvent.weight));
this.edges.filter(u => u.target === node).forEach(u => processNodes.push(u.source));
} else if (edges.filter(u => le.findIndex(v => v.node === u.target) < 0).length === 0) {
const leValue = edges.map(u => le.find(v => v.node === u.target).weight - u.weight).sort((a, b) => a - b)[0];
le.push(new Event(node, leValue));
this.edges.filter(u => u.target === node).forEach(u => processNodes.push(u.source));
}
}
console.log('ee', ee);
console.log('le', le);
const path = ee.filter(u => le.find(v => v.node === u.node).weight === u.weight).map(u => u.node);
console.log('critical path', path);
return path;
}
}
class Event {
constructor(public node: string, public weight: number) {}
}
export class Edge {
constructor(public source: string,
public target: string,
public weight: number) { }
}
网友评论