Skip to content

Commit 55f7e2b

Browse files
authored
Implement Bidirectional BFS algorithm
This class implements the Bidirectional Breadth-First Search (BFS) algorithm to determine if a path exists between two nodes in an unweighted graph. It explores the graph from both the start and goal nodes simultaneously, improving efficiency for large graphs.
1 parent a9ba87c commit 55f7e2b

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
BidirectionalBFS.java
3+
4+
This class implements the Bidirectional Breadth-First Search (BFS) algorithm to efficiently
5+
determine whether a path exists between two nodes in an unweighted graph. Instead of
6+
searching from the start node alone, it simultaneously explores the graph from both the
7+
start and goal nodes, meeting in the middle. This approach often reduces the number of
8+
nodes visited compared to traditional BFS, making it faster for large graphs. The main
9+
method provides an example graph and demonstrates usage by printing whether a path
10+
exists between the specified start and goal nodes.
11+
*/
12+
13+
14+
15+
import java.util.*;
16+
17+
public class BidirectionalBFS {
18+
19+
public static boolean bidirectionalBFS(Map<Integer, List<Integer>> graph, int start, int goal) {
20+
if (start == goal) return true;
21+
22+
Set<Integer> visitedStart = new HashSet<>();
23+
Set<Integer> visitedGoal = new HashSet<>();
24+
25+
Queue<Integer> queueStart = new LinkedList<>();
26+
Queue<Integer> queueGoal = new LinkedList<>();
27+
28+
queueStart.add(start);
29+
queueGoal.add(goal);
30+
31+
visitedStart.add(start);
32+
visitedGoal.add(goal);
33+
34+
while (!queueStart.isEmpty() && !queueGoal.isEmpty()) {
35+
// Expand from start side
36+
if (expandFrontier(graph, queueStart, visitedStart, visitedGoal)) return true;
37+
// Expand from goal side
38+
if (expandFrontier(graph, queueGoal, visitedGoal, visitedStart)) return true;
39+
}
40+
41+
return false; // no path found
42+
}
43+
44+
private static boolean expandFrontier(Map<Integer, List<Integer>> graph, Queue<Integer> queue,
45+
Set<Integer> visitedThisSide, Set<Integer> visitedOtherSide) {
46+
int size = queue.size();
47+
for (int i = 0; i < size; i++) {
48+
int current = queue.poll();
49+
for (int neighbor : graph.getOrDefault(current, new ArrayList<>())) {
50+
if (visitedOtherSide.contains(neighbor)) return true;
51+
if (!visitedThisSide.contains(neighbor)) {
52+
visitedThisSide.add(neighbor);
53+
queue.add(neighbor);
54+
}
55+
}
56+
}
57+
return false;
58+
}
59+
60+
public static void main(String[] args) {
61+
Map<Integer, List<Integer>> graph = new HashMap<>();
62+
graph.put(0, Arrays.asList(1, 2));
63+
graph.put(1, Arrays.asList(0, 3));
64+
graph.put(2, Arrays.asList(0, 3, 4));
65+
graph.put(3, Arrays.asList(1, 2, 5));
66+
graph.put(4, Arrays.asList(2, 5));
67+
graph.put(5, Arrays.asList(3, 4));
68+
69+
int start = 0;
70+
int goal = 5;
71+
72+
boolean pathExists = bidirectionalBFS(graph, start, goal);
73+
System.out.println("Path from " + start + " to " + goal + ": " + pathExists);
74+
}
75+
}

0 commit comments

Comments
 (0)