Merge pull request #1832 from mokeyish/patch-2

Fix the logic error of `getStartingNodes`
This commit is contained in:
Henry Heng 2024-03-12 16:49:08 +08:00 committed by GitHub
commit 474681e113
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 27 deletions

View File

@ -162,39 +162,22 @@ export const constructGraphs = (
* @param {string} endNodeId * @param {string} endNodeId
*/ */
export const getStartingNodes = (graph: INodeDirectedGraph, endNodeId: string) => { export const getStartingNodes = (graph: INodeDirectedGraph, endNodeId: string) => {
const visited = new Set<string>()
const queue: Array<[string, number]> = [[endNodeId, 0]]
const depthQueue: IDepthQueue = { const depthQueue: IDepthQueue = {
[endNodeId]: 0 [endNodeId]: 0
} }
let maxDepth = 0 // Assuming that this is a directed acyclic graph, there will be no infinite loop problem.
let startingNodeIds: string[] = [] const walkGraph = (nodeId: string) => {
const depth = depthQueue[nodeId]
while (queue.length > 0) { graph[nodeId].flatMap((id) => {
const [currentNode, depth] = queue.shift()! depthQueue[id] = Math.max(depthQueue[id] ?? 0, depth + 1)
walkGraph(id)
if (visited.has(currentNode)) { })
continue
}
visited.add(currentNode)
if (depth > maxDepth) {
maxDepth = depth
startingNodeIds = [currentNode]
} else if (depth === maxDepth) {
startingNodeIds.push(currentNode)
}
for (const neighbor of graph[currentNode]) {
if (!visited.has(neighbor)) {
queue.push([neighbor, depth + 1])
depthQueue[neighbor] = depth + 1
}
}
} }
walkGraph(endNodeId)
const maxDepth = Math.max(...Object.values(depthQueue))
const depthQueueReversed: IDepthQueue = {} const depthQueueReversed: IDepthQueue = {}
for (const nodeId in depthQueue) { for (const nodeId in depthQueue) {
if (Object.prototype.hasOwnProperty.call(depthQueue, nodeId)) { if (Object.prototype.hasOwnProperty.call(depthQueue, nodeId)) {
@ -202,6 +185,10 @@ export const getStartingNodes = (graph: INodeDirectedGraph, endNodeId: string) =
} }
} }
const startingNodeIds = Object.entries(depthQueueReversed)
.filter(([_, depth]) => depth === 0)
.map(([id, _]) => id)
return { startingNodeIds, depthQueue: depthQueueReversed } return { startingNodeIds, depthQueue: depthQueueReversed }
} }