* BFS algorithm for unweighted shortest path. * Time complexity: O(V + E)
(
source: GraphSource<any>,
startVertex: Vertex<any, any>,
targetId: ElementId | undefined,
targetCondition: Condition | undefined,
direction: Direction,
edgeLabels: readonly string[],
maxDepth: number,
)
| 5121 | * Time complexity: O(V + E) |
| 5122 | */ |
| 5123 | private bfs( |
| 5124 | source: GraphSource<any>, |
| 5125 | startVertex: Vertex<any, any>, |
| 5126 | targetId: ElementId | undefined, |
| 5127 | targetCondition: Condition | undefined, |
| 5128 | direction: Direction, |
| 5129 | edgeLabels: readonly string[], |
| 5130 | maxDepth: number, |
| 5131 | ): ShortestPathResult | null { |
| 5132 | // Early termination: check if start is target |
| 5133 | if (this.isTarget(startVertex, targetId, targetCondition)) { |
| 5134 | return { vertices: [startVertex], edges: [], length: 0 }; |
| 5135 | } |
| 5136 | |
| 5137 | // BFS data structures with parent pointers for efficient path reconstruction |
| 5138 | const visited = new Set<ElementId>([startVertex.id]); |
| 5139 | const previous = new Map<ElementId, { vertex: Vertex<any, any>; edge: Edge<any, any> } | null>([ |
| 5140 | [startVertex.id, null], |
| 5141 | ]); |
| 5142 | const queue: Vertex<any, any>[] = [startVertex]; |
| 5143 | |
| 5144 | let depth = 0; |
| 5145 | |
| 5146 | while (queue.length > 0 && depth < maxDepth) { |
| 5147 | const levelSize = queue.length; |
| 5148 | depth++; |
| 5149 | |
| 5150 | for (let i = 0; i < levelSize; i++) { |
| 5151 | const current = queue.shift()!; |
| 5152 | |
| 5153 | // Get adjacent vertices based on direction |
| 5154 | const neighbors = this.getNeighbors(source, current, direction, edgeLabels); |
| 5155 | |
| 5156 | for (const { vertex: neighbor, edge } of neighbors) { |
| 5157 | if (visited.has(neighbor.id)) { |
| 5158 | continue; |
| 5159 | } |
| 5160 | |
| 5161 | visited.add(neighbor.id); |
| 5162 | previous.set(neighbor.id, { vertex: current, edge }); |
| 5163 | |
| 5164 | // Check if this is the target |
| 5165 | if (this.isTarget(neighbor, targetId, targetCondition)) { |
| 5166 | return this.reconstructPath(neighbor, previous, depth); |
| 5167 | } |
| 5168 | |
| 5169 | queue.push(neighbor); |
| 5170 | } |
| 5171 | } |
| 5172 | } |
| 5173 | |
| 5174 | return null; // No path found |
| 5175 | } |
| 5176 | |
| 5177 | /** |
| 5178 | * Dijkstra's algorithm for weighted shortest path. |
no test coverage detected