Uninformed search (also called blind search) refers to a family of search algorithms that explore a problem's state space using only the structural information encoded in the problem definition — namely the initial state, the successor function, the cost function, and the goal test. They have no domain-specific knowledge (no heuristic) about which states are 'closer' to the goal. Key strategies include Breadth-First Search (BFS), Depth-First Search (DFS), Uniform-Cost Search (UCS), Depth-Limited Search (DLS), Iterative-Deepening DFS (IDDFS), and Bidirectional Search. Every GATE DA paper tests properties — completeness, optimality, time complexity, and space complexity — of these strategies.
Problem formulation and search fundamentals
A search problem is formally defined by five components: (1) the initial state s₀, (2) a set of actions A(s) available in each state s, (3) a transition model Result(s, a) returning the state reached by taking action a in state s, (4) an action cost function c(s, a, s'), and (5) a goal test Goal(s). Solving the problem means finding a sequence of actions (a path) from s₀ to some goal state that satisfies any additional optimality criteria.
A node in a search tree encodes: (state, parent, action, path-cost g, depth). The frontier (open list) holds nodes generated but not yet expanded. The explored set (closed list) holds already-expanded states (used in graph search to avoid revisiting). Tree search never revisits states explicitly; graph search does.
Tree search vs. Graph search
Tree search can revisit states (potentially infinite loops on cyclic graphs); graph search maintains an explored set. GATE questions frequently test which strategy is complete only with graph search (DFS) vs. those complete even in tree search (BFS, UCS with non-negative costs).
Breadth-First Search (BFS)
BFS expands nodes level by level: the frontier is a FIFO queue. All nodes at depth d are expanded before any node at depth d+1. The shallowest solution is always found first.
| Property | BFS Result | Condition |
|---|---|---|
| Complete? | Yes | Provided b (branching factor) is finite |
| Optimal? | Yes — finds shallowest goal | Only if all step costs are equal (unit cost). Use UCS for non-uniform costs. |
| Time complexity | O(b^d) | b = branching factor, d = depth of shallowest solution |
| Space complexity | O(b^d) | All nodes at depth d are kept in memory — this is BFS's critical weakness |
Space explosion
At b=10 and d=10, BFS stores 10^10 ≈ 10 billion nodes in memory. This is why BFS is rarely used in practice for large state spaces despite its theoretical guarantees.
Graph BFS — finds shallowest solution
from collections import deque
def bfs(problem):
node = Node(problem.initial)
if problem.goal_test(node.state): return node
frontier = deque([node]) # FIFO queue
explored = set()
while frontier:
node = frontier.popleft() # expand shallowest
explored.add(node.state)
for action in problem.actions(node.state):
child = node.expand(problem, action)
if child.state not in explored and child not in frontier:
if problem.goal_test(child.state):
return child # early goal test
frontier.append(child)
return None # failureDepth-First Search (DFS)
DFS always expands the deepest node in the frontier. The frontier is a LIFO stack (or equivalently, DFS is implemented recursively). It commits to a path early and backtracks when hitting a dead end or depth limit.
| Property | DFS Result | Condition |
|---|---|---|
| Complete? | No (tree search) | Fails in infinite or cyclic state spaces without explored set |
| Complete? | Yes (graph search, finite space) | With explored set, avoids revisiting states |
| Optimal? | No | May find a deep non-optimal solution before a shallower optimal one |
| Time complexity | O(b^m) | m = maximum depth of search tree; can be >> d |
| Space complexity | O(b·m) | Linear space — stores only current path + unexpanded siblings. Key advantage over BFS. |
DFS's key advantage
Space complexity O(bm) is DFS's crucial advantage. When solutions are deep and branching is large, DFS's linear space requirement makes it the only feasible option. This is exactly why it forms the backbone of IDDFS.
Uniform-Cost Search (UCS)
UCS (Dijkstra's algorithm applied to search) expands the node with the lowest cumulative path cost g(n). The frontier is a priority queue ordered by g. UCS is the optimal uninformed search strategy for problems with non-negative, varying step costs.
Path cost g(n) — the sum of action costs along the path from start to node n.
| Property | UCS Result | Condition |
|---|---|---|
| Complete? | Yes | All step costs ≥ ε > 0 (strictly positive) |
| Optimal? | Yes | Finds least-cost solution; same guarantee as Dijkstra's |
| Time complexity | O(b^(1 + ⌊C*/ε⌋)) | C* = optimal solution cost, ε = minimum step cost |
| Space complexity | O(b^(1 + ⌊C*/ε⌋)) | Same as time; stores all generated nodes |
BFS as a special case of UCS
BFS is UCS with all step costs equal to 1. When costs are uniform, g(n) = depth(n), so the priority queue degenerates into a FIFO queue and UCS becomes BFS.
Iterative Deepening DFS (IDDFS)
IDDFS combines BFS's completeness and optimality (for unit costs) with DFS's linear space. It runs DFS with a depth limit l = 0, 1, 2, … until a solution is found. Nodes near the root are regenerated multiple times, but this overhead is small — the last level dominates.
Total nodes generated by IDDFS to reach depth d. For b=10, d=5: IDDFS generates only ~11% more nodes than BFS — a negligible overhead for the massive space savings.
| Property | BFS | DFS | IDDFS |
|---|---|---|---|
| Complete? | Yes | No (tree) | Yes |
| Optimal? | Yes (unit cost) | No | Yes (unit cost) |
| Time | O(b^d) | O(b^m) | O(b^d) |
| Space | O(b^d) | O(bm) | O(bd) ← Best of both worlds |
GATE key insight
IDDFS is the preferred uninformed search in practice because it is complete, optimal (for unit costs), uses linear space, and has the same asymptotic time complexity as BFS. GATE frequently asks to compare IDDFS to BFS and DFS.
Bidirectional Search
Bidirectional search runs two simultaneous searches — one forward from the start and one backward from the goal — and terminates when the two frontiers meet. If both frontiers have depth d/2, the time and space complexity drop from O(b^d) to O(b^(d/2)).
Bidirectional complexity advantage. For b=10, d=10: BFS explores 10^10 nodes; bidirectional explores 2×10^5 — a 50,000× reduction.
Implementation challenge
Bidirectional search requires a known goal state (to generate predecessors), an invertible successor function, and careful handling of the meeting condition. It's most beneficial when the state space is large and the branching factor is similar in both directions.
Complete comparison table
| Strategy | Data Structure | Complete? | Optimal? | Time | Space |
|---|---|---|---|---|---|
| BFS | FIFO Queue | Yes (finite b) | Yes (unit cost) | O(b^d) | O(b^d) |
| DFS | LIFO Stack | No (tree) / Yes (graph, finite) | No | O(b^m) | O(bm) |
| DLS (depth=l) | LIFO Stack | Yes if d ≤ l | No | O(b^l) | O(bl) |
| UCS | Priority Queue (by g) | Yes (ε > 0) | Yes | O(b^(C*/ε)) | O(b^(C*/ε)) |
| IDDFS | LIFO Stack (iterative) | Yes | Yes (unit cost) | O(b^d) | O(bd) |
| Bidirectional BFS | Two FIFO Queues | Yes | Yes (unit cost) | O(b^(d/2)) | O(b^(d/2)) |
GATE PYQ Spotlight
GATE DA — BFS vs DFS on State Space (2-mark)
Consider a state space where the start state is 1. The successor function for state n returns states n+1 and n+2. States in the unexpanded list are expanded in ascending order. Previously expanded states are not re-added. Which ONE statement about BFS and DFS is true when reaching goal state 6? Answer: BFS expands states in the order 1→2→3→4→5→6 (level by level); DFS may follow a single path aggressively. With ascending-order expansion and no revisits, BFS visits 5 states before reaching 6 while DFS visits fewer states in this specific tree (not cyclic). Key takeaway: BFS guarantees shortest path (fewest hops); DFS may be faster in lucky branching structures but is not guaranteed optimal.
GATE DA — Bidirectional complexity (1-mark)
If a state space has branching factor b = 10 and the goal is at depth d = 6, how many nodes does bidirectional BFS examine compared to standard BFS? BFS: O(10^6) = 1,000,000 nodes. Bidirectional: O(2 × 10^3) = 2,000 nodes — roughly 500× fewer. Answer choice: O(b^(d/2)) for bidirectional vs. O(b^d) for BFS.
Practice questions
- What is the time and space complexity of BFS and when does space become the limiting factor? (Answer: BFS: time O(b^d), space O(b^d) where b = branching factor, d = depth of solution. Space stores all frontier nodes. Example: b=10, d=10: 10^10 = 10 billion nodes in memory — ~80GB. Space is almost always the limiting factor before time. Solution: IDDFS (Iterative Deepening DFS) achieves BFS optimality with DFS's O(bd) space — uses O(d) memory instead of O(b^d).)
- What is the difference between BFS and uniform cost search? (Answer: BFS: expands nodes in order of path length (number of steps). Optimal only when all edges have equal cost. Uniform Cost Search (Dijkstra's): expands nodes in order of path COST (not steps). Optimal for any non-negative edge costs. BFS is a special case of UCS where all edges have cost 1. When edge costs vary (different route distances, different action costs), UCS finds the optimal cost solution; BFS finds the minimum-step solution (which may be expensive).)
- What is the completeness property of DFS and under what conditions does DFS fail? (Answer: DFS is NOT complete in general: can enter infinite loops in graphs with cycles or infinite depth. DFS is complete for: finite graphs with cycle detection (visited set). DFS is complete for: finite trees. DFS is NOT complete for: infinite depth spaces (e.g., successor of state n is n+1 — DFS goes to infinity). Complete alternatives: BFS (always complete if solution exists), IDDFS (complete, memory-efficient).)
- What is the difference between graph search and tree search in uninformed search algorithms? (Answer: Tree search: does not track visited nodes — may revisit states, potentially infinite loops in cyclic graphs. Space: O(bd). Suitable only for tree-structured problems or when revisiting is rare. Graph search: maintains a 'closed' set of visited nodes — never revisits. Guaranteed to terminate on finite graphs. Space: O(b^d) for BFS (frontier + closed set). Required for problems with cycles (route planning, grid worlds).)
- What is bidirectional search and when does it provide a significant speedup? (Answer: Bidirectional search: run two simultaneous searches — one forward from start, one backward from goal. Stop when frontiers meet. Complexity: O(b^{d/2}) instead of O(b^d) — square root of unidirectional cost. For b=10, d=10: unidirectional needs 10^10 nodes; bidirectional needs 2×10^5 ≈ 200,000. Enormous speedup. Limitation: requires knowing the goal state and being able to compute predecessor states (backward operators). Works well for: route planning, word ladders, bidirectional A*.)
On LumiChats
When LumiChats plans multi-step tasks, it uses graph-search-like mechanisms under the hood — expanding possible action sequences and pruning those that are clearly suboptimal, analogous to UCS or IDDFS in classical AI.
Try it free