graflow cleanup
This commit is contained in:
77
bzGraflow.js
77
bzGraflow.js
@@ -407,83 +407,6 @@ class BZgraflow extends Buildoz{
|
||||
}
|
||||
return(this.flow.nodes.map(n => n.id).some(dfs))
|
||||
}
|
||||
|
||||
|
||||
getLoopingLinks(nodes, links) {
|
||||
const loops = []
|
||||
|
||||
// Handle self-loops (links where from[0] === to[0])
|
||||
for(let [idx, link] of this.flow.links.entries()){
|
||||
if(link.from[0] === link.to[0]) {
|
||||
loops.push([idx])
|
||||
}
|
||||
}
|
||||
|
||||
// Build adjacency list with link indexes
|
||||
const adj = {};
|
||||
this.flow.nodes.forEach(node => adj[node.id] = [])
|
||||
for(let [idx, link] of this.flow.links.entries()){
|
||||
if(link.from[0] !== link.to[0]) { // Skip self-loops, already handled
|
||||
adj[link.from[0]].push({ to: link.to[0], linkIdx: idx })
|
||||
}
|
||||
}
|
||||
|
||||
// Track visited nodes globally to avoid revisiting completed subtrees
|
||||
const visited = new Set()
|
||||
|
||||
// DFS to find cycles
|
||||
const dfs = (nid, path, pathLinkIndexes) => {
|
||||
// If already fully visited, skip
|
||||
if(visited.has(nid)) return
|
||||
|
||||
// Add current node to path
|
||||
path.push(nid)
|
||||
|
||||
// Explore neighbors
|
||||
for(const neighbor of adj[nid]) {
|
||||
// Check if this neighbor creates a cycle
|
||||
const cycleStartIdx = path.indexOf(neighbor.to)
|
||||
if(cycleStartIdx !== -1) {
|
||||
// Found a cycle: from path[cycleStartIdx] to path[path.length-1] and back via this link
|
||||
// The cycle links are: pathLinkIndexes[cycleStartIdx] to pathLinkIndexes[pathLinkIndexes.length-1], plus the current link
|
||||
const cycleLinkIndexes = [...pathLinkIndexes.slice(cycleStartIdx), neighbor.linkIdx]
|
||||
// Normalize: represent cycle as sorted array of link indexes for uniqueness
|
||||
const normalized = [...cycleLinkIndexes].sort((a, b) => a - b)
|
||||
// Check if we already have this cycle (avoid duplicates)
|
||||
const alreadyFound = loops.some(loop => {
|
||||
const loopNormalized = [...loop].sort((a, b) => a - b)
|
||||
if(loopNormalized.length !== normalized.length) return false
|
||||
return loopNormalized.every((idx, i) => idx === normalized[i])
|
||||
})
|
||||
if(!alreadyFound && cycleLinkIndexes.length > 0) {
|
||||
loops.push(cycleLinkIndexes)
|
||||
}
|
||||
continue // Don't recurse into this neighbor
|
||||
}
|
||||
|
||||
pathLinkIndexes.push(neighbor.linkIdx)
|
||||
dfs(neighbor.to, path, pathLinkIndexes)
|
||||
pathLinkIndexes.pop()
|
||||
}
|
||||
|
||||
// Remove current node from path
|
||||
path.pop()
|
||||
|
||||
// Mark as fully visited
|
||||
visited.add(nid)
|
||||
}
|
||||
|
||||
// Start DFS from each unvisited node
|
||||
for(const node of this.flow.nodes) {
|
||||
if(!visited.has(node.id)) {
|
||||
dfs(node.id, [], [])
|
||||
}
|
||||
}
|
||||
|
||||
return loops
|
||||
}
|
||||
|
||||
|
||||
|
||||
findBackEdges(nodes, links) {
|
||||
// Build adjacency list with link indexes
|
||||
|
||||
Reference in New Issue
Block a user