68 lines
1.2 KiB
JavaScript
68 lines
1.2 KiB
JavaScript
"use strict";
|
|
|
|
var _ = require("./lodash");
|
|
var greedyFAS = require("./greedy-fas");
|
|
|
|
module.exports = {
|
|
run: run,
|
|
undo: undo
|
|
};
|
|
|
|
function run(g) {
|
|
var fas = (g.graph().acyclicer === "greedy"
|
|
? greedyFAS(g, weightFn(g))
|
|
: dfsFAS(g));
|
|
_.forEach(fas, function(e) {
|
|
var label = g.edge(e);
|
|
g.removeEdge(e);
|
|
label.forwardName = e.name;
|
|
label.reversed = true;
|
|
g.setEdge(e.w, e.v, label, _.uniqueId("rev"));
|
|
});
|
|
|
|
function weightFn(g) {
|
|
return function(e) {
|
|
return g.edge(e).weight;
|
|
};
|
|
}
|
|
}
|
|
|
|
function dfsFAS(g) {
|
|
var fas = [];
|
|
var stack = {};
|
|
var visited = {};
|
|
|
|
function dfs(v) {
|
|
if (_.has(visited, v)) {
|
|
return;
|
|
}
|
|
visited[v] = true;
|
|
stack[v] = true;
|
|
_.forEach(g.outEdges(v), function(e) {
|
|
if (_.has(stack, e.w)) {
|
|
fas.push(e);
|
|
} else {
|
|
dfs(e.w);
|
|
}
|
|
});
|
|
delete stack[v];
|
|
}
|
|
|
|
_.forEach(g.nodes(), dfs);
|
|
return fas;
|
|
}
|
|
|
|
function undo(g) {
|
|
_.forEach(g.edges(), function(e) {
|
|
var label = g.edge(e);
|
|
if (label.reversed) {
|
|
g.removeEdge(e);
|
|
|
|
var forwardName = label.forwardName;
|
|
delete label.reversed;
|
|
delete label.forwardName;
|
|
g.setEdge(e.w, e.v, label, forwardName);
|
|
}
|
|
});
|
|
}
|