import { GraphExpander } from '../../interfaces/graph-expander'; /** * Configuration options for bidirectional BFS. */ export interface BidirectionalBFSOptions { /** Target number of paths to find */ targetPaths: number; /** Maximum BFS iterations before stopping */ maxIterations: number; /** Minimum iterations to continue after finding target paths (for path diversity) */ minIterations?: number; } /** * Result from bidirectional BFS search. */ export interface BidirectionalBFSResult { /** Array of paths (each path is array of node IDs from seedA to seedB) */ paths: string[][]; /** Nodes visited from seedA */ visitedA: Set; /** Nodes visited from seedB */ visitedB: Set; /** Number of iterations performed */ iterations: number; } /** * Generic bidirectional breadth-first search with degree-based node prioritization. * * **NOTE: This is an earlier design with parameterised termination.** * For the parameter-free version that aligns with the thesis theoretical framework, * see DegreePrioritisedExpansion (N≥1 seeds, frontier exhaustion only). * * **Design Relationship**: * - BidirectionalBFS: Earlier design, N=2 only, has termination parameters (targetPaths, maxIterations) * - DegreePrioritisedExpansion: Refined design, N≥1 with identical code path, parameter-free * * This implementation is suitable for production use cases where: * - Predictable resource consumption is required * - Finding *a* path quickly is more important than exhaustive sampling * - Service-level objectives constrain iteration count * * Searches for paths between two seed nodes by expanding frontiers from both directions. * Uses priority queue to process low-degree nodes first, naturally prioritizing specific * connections over generic ones. * * **Algorithm**: Degree-based best-first search * - Maintains two frontiers (from seedA and seedB) * - Processes nodes in order of degree (low degree = high priority) * - Detects when frontiers meet to find paths * - Continues for minimum iterations after finding target paths (for diversity) * * **Time Complexity**: O(E log V) where E = edges explored, V = vertices * **Space Complexity**: O(V) for visited sets and frontiers * * @template T - Type of node data returned by expander * @example * ```typescript * const bfs = new BidirectionalBFS( * expander, * 'nodeA', * 'nodeB', * { targetPaths: 5, maxIterations: 10, minIterations: 2 } * ); * * const result = await bfs.search(); * console.log(`Found ${result.paths.length} paths in ${result.iterations} iterations`); * ``` * * @see DegreePrioritisedExpansion - Parameter-free version for N≥1 seeds */ export declare class BidirectionalBFS { private readonly expander; private readonly seedA; private readonly seedB; private readonly options; private foundPaths; private stateA; private stateB; constructor(expander: GraphExpander, seedA: string, seedB: string, options: BidirectionalBFSOptions); /** * Execute the bidirectional BFS search. * * @returns Search results including found paths and visited nodes */ search(): Promise; /** * Expand frontier by getting neighbors from expander and adding to priority queue. * @param state - BFS state to expand * @param _label - Direction label (unused, for debugging) * @internal */ private expandFrontier; /** * Check if frontiers have met (bidirectional search intersection). * @internal */ private checkForConnections; /** * Reconstruct path from meeting point. * @param meetingNode - Node where the two searches met * @param _fromA - Whether path started from A (unused, for symmetry) * @internal */ private reconstructPath; /** * Check if path already exists in foundPaths. * @param path * @internal */ private pathExists; /** * Add nodes from newly discovered paths to frontiers for focused exploration. * @param pathCountBefore * @internal */ private addPathNodesToFrontiers; } //# sourceMappingURL=bidirectional-bfs.d.ts.map