67 lines
1.2 KiB
JavaScript
67 lines
1.2 KiB
JavaScript
import _ from 'lodash'
|
|
|
|
import greedyFAS from './greedy-fas'
|
|
|
|
function run (g) {
|
|
const fas = (g.graph().acyclicer === 'greedy'
|
|
? greedyFAS(g, weightFn(g))
|
|
: dfsFAS(g))
|
|
_.forEach(fas, function (e) {
|
|
const 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) {
|
|
const fas = []
|
|
const stack = {}
|
|
const 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) {
|
|
const label = g.edge(e)
|
|
if (label.reversed) {
|
|
g.removeEdge(e)
|
|
|
|
const forwardName = label.forwardName
|
|
delete label.reversed
|
|
delete label.forwardName
|
|
g.setEdge(e.w, e.v, label, forwardName)
|
|
}
|
|
})
|
|
}
|
|
|
|
export default {
|
|
run,
|
|
undo
|
|
}
|