Depth First Search (DFS) for Artificial Intelligence
Last Updated :
16 May, 2024
Depth-first search contributes to its effectiveness and optimization in artificial intelligence. From algorithmic insights to real-world implementations, DFS plays a huge role in optimizing AI systems. Let's dive into the fundamentals of DFS, its significance in artificial intelligence, and its practical applications.
What is a Depth-First Search in AI?
Depth-first search is a traversing algorithm used in tree and graph-like data structures. It generally starts by exploring the deepest node in the frontier. Starting at the root node, the algorithm proceeds to search to the deepest level of the search tree until nodes with no successors are reached. Suppose the node with unexpanded successors is encountered then the search backtracks to the next deepest node to explore alternative paths.
Search operation of the depth-first searchDepth-first search (DFS) explores a graph by selecting a path and traversing it as deeply as possible before backtracking.
- Originally it starts at the root node, then it expands all of its one branch until it reaches a dead end, then backtracks to the most recent unexplored node, repeating until all nodes are visited or a specific condition is met. ( As shown in the above image, starting from node A, DFS explores its successor B, then proceeds to its descendants until reaching a dead end at node D. It then backtracks to node B and explores its remaining successors i.e E. )
- This systematic exploration continues until all nodes are visited or the search terminates. (In our case after exploring all the nodes of B. DFS explores the right side node i.e C then F and and then G. After exploring the node G. All the nodes are visited. It will terminate.
Key characteristics of DFS
In simple terms, the DFS algorithms in AI holds the power of extending the current path as deeply as possible before considering the other options.
- DFS is not cost-optimal since it doesn't guarantee to find the shortest paths.
- DFS uses the simple principle to keep track of visited nodes: It uses a stack to keep track of nodes that have been visited so far which helps in the backtracking of the graph. When the DFS encounters a new node, it adds it to the stack to explore its neighbours. If it reaches a node with no successors (leaf node), it works by backtracking such as popping nodes off the stack to explore the alternative paths.
- Backtracking search: The variant of DFS is called backtracking search which uses less memory than traditional depth-first search. Rather than generating all the successors, the backtracking search enables the DFS to generate only one successor at a time. This approach allows dynamic state modification, such as generating successors by directly modifying the current state description instead of allocating the memory to a brand-new state. Thus reducing the memory requirements to store one state description and path of actions.
Edge classes in a Depth-first search tree based on a spanning tree
The edges of the depth-first search tree can be divided into four classes based on the spanning tree, they are
- Forward edges: The forward edge is responsible for pointing from a node of the tree to one of its successors.
- Back edges: The back edge holds the power of directing its edge from a node of the tree to one of its ancestors.
- Tree edges: When DFS explores the new vertex from the current vertex, the edge connecting them is called a tree edge. It is essential while constructing a DFS spanning tree because it represents the paths to be followed during the traversal.
- Cross edges: Cross edges are the edges that connect two vertices that are neither ancestors nor descendants of each other in the DFS tree.
Edge classes in DFS based on spanning treeDepth First Search(DFS) Algorithm
Take a look at the below Pseudocode which explains the working of DFS
function findPath(robot, start, goal):
stack ← empty stack
visited ← empty set
stack.push(start)
while not stack.isEmpty( ):
current ← stack.pop( )
if current == goal:
return "Path found"
visited.add(current)
neighbors ← robot.getNeighbors(current)
for neighbor in neighbors:
if neighbor not in visted:
stack.push(neighbor)
return "Path not found"
Step wise DFS Pseudocode Explanatioin
- Initialize an empty stack and an empty set for visited vertices.
- Push the start vertex onto the stack.
- While the stack is not empty:
- Pop the current vertex.
- If it's the goal vertex, return "Path found".
- Add the current vertex to the visited set.
- Get the neighbors of the current vertex.
- For each neighbor not visited, push it onto the stack.
- If the loop completes without finding the goal, return "Path not found".
Time complexity of DFS:
- Explicit Time Complexity: This time complexity arises because DFS traverses each vertex and edge exactly once in the worst-case scenario. This complexity is for explicit traversing of DFS without any repetition. The time complexity of DFS is commonly represented as
O(|V| + |E|)
Where,
- V- represents the number of vertices,
- E - represents the number of edges.
- Implicit Time Complexity: This implicit time complexity is appropriate while considering the time complexity in terms of the number of nodes visited in the tree instead of the number of edges and vertices in a graph. For implicit traversing of DFS can be simply depicted as,
O(bd)
where,
- b - represents the branching factor,
- d - represents the depth of the search.
Space complexity of DFS:
- Explicit Space Complexity: The space complexity of DFS is commonly represented as
O(|V|)
Where,
- V - represents the number of vertices.
This is because DFS typically uses additional data structures like stack or recursion stack to keep track of visited vertices.
- Implicit Space Complexity: For an implicit search in a graph, DFS’s space complexity can be represented as follows:
O(bd)
where,
- b - represents the branching factor,
- d - represents the depth of the search.
This space complexity is said to be considered when the space is required to store the nodes on the current path during the search.
DFS Behavior Across Different State Space Structures
- Finite state spaces that are trees: In this scenario, DFS is efficient and complete. It explore all possible states without revisiting any state which ensures that it systematically covers the entire state space.
- Infinite state spaces: Since DFS is not a systematic one in the infinite state space, it can typically get stuck while traversing down an infinite path even if there are no cycles. Thus lack of systematic exploration renders DFS incomplete for infinite state spaces, as it may not cover the entire space or it may never terminate. Such that makes the Depth-first search incomplete.
- Cyclic state spaces: DFS can stuck in an infinite loop when dealing with the cyclic state spaces. To address this issue, some implementations of DFS incorporate a cycle-checking mechanism to prevent revisiting states and entering an infinite loop.
- Acyclic state spaces: Even though it is capable of exploring the entire state spaces, the acyclic state spaces may lead to expanding the same state many times via different paths.
DFS Implementation in Robotics Pathfinding
DFS can be used to find a path from a start node to a goal node in a maze or grid-based environment. The DFS algorithm systematically explores all possible paths from the start node, one branch at a time until it finds a path that leads to the goal. The below figures show the maze which contains the initial state of the robot, the obstacles, and the goal state. Here, the goal node is in the position of (0,5) where the robot needs to traverse through the maze to find the path to reach the goal.
Step 1: Define Maze dimensions and obstacles
We define a maze_size representing the dimension of the maze, in our case, it's a 6x6 grid. A list of coordinates that represents the positions of obstacles within a maze is also specified. The robot is positioned at the initial state (0,0) and aims to reach the goal state (0,5).
Maze environment Maze dimensions and obstacles
Python
# Maze dimensions and obstacles
maze_size = 6
obstacles = [(0,1),(1,1),(3,2),(3,3),(3,4),(3,5),(0,4),(4,1),(4,2),(4,3)]
start = (0,0)
goal = (0,5)
Step 2: Define a is_valid function
The is_valid function checks whether a given position of (x,y) is valid such that it inspects that it's within the bounds of the maze and not obstructed by any obstacles.
Python
def is_valid(x,y):
return 0 <= x < maze_size and 0 <= y < maze_size and (x,y) not in obstacles
Step 3: Define dfs function (Depth-first search):
In the below code, we define the dfs function to implement the DFS algorithm. It uses a stack to keep a record of the nodes it visits, and it iterates through each node that helps in exploring its neighbors recursively until it finds the goal node or it exhausts all possibilities.
- The empty stack stores nodes to be explored, and the empty set is used to keep track of nodes that have been already visited to avoid revisiting them.
- If the current node is found to be the goal node, it reverses the path so that the robot can follow and it finally returns "Path found".
- If no path is found, it returns "No path found". This is an exhaustive search approach, it ensures that all the potential paths are explored and provides a comprehensive solution to the maze-navigating problem.
Python
def dfs (current, visited, path):
x, y = current
if current == goal:
path.append(current)
return True
visited.add(current)
moves = [(x-1,y), (x+1, y), (x, y-1), (x, y+1)]
for move in moves:
if is_valid(*move) and move not in visited:
if dfs(move, visited, path):
path.append(current)
return True
return False
Step 4: Call DFS function to find the path
Python
#Call DFS function to find the path
visited = set()
path = []
if dfs(start, visited, path):
path.reverse()
print("Path found:")
for position in path:
print(position)
else:
print("No path found!")
Complete Code of Robots Pathfinding
Python
# Maze dimensions and obstacles
maze_size = 6
obstacles = [(0,1),(1,1),(3,2),(3,3),(3,4),(3,5),(0,4),(4,1),(4,2),(4,3)]
start = (0,0)
goal = (0,5)
# checks whether a given position of (x,y) is valid to move or not
def is_valid(x,y):
return 0 <= x < maze_size and 0 <= y < maze_size and (x,y) not in obstacles
#Dfs function (Depth-first search)
def dfs (current, visited, path):
x, y = current
if current == goal:
path.append(current)
return True
visited.add(current)
moves = [(x-1,y), (x+1, y), (x, y-1), (x, y+1)]
for move in moves:
if is_valid(*move) and move not in visited:
if dfs(move, visited, path):
path.append(current)
return True
return False
#Call DFS function to find the path
visited = set()
path = []
if dfs(start, visited, path):
path.reverse()
print("Path found:")
for position in path:
print(position)
else:
print("No path found!")
Output:
Path found:
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(2, 1)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(1, 3)
(2, 3)
(2, 4)
(1, 4)
(1, 5)
(0, 5)
Output explanation
Step 1: We first start at the initial position (0,0), it is where the robot begins its exploration.
Step 2: The robot moves right along the top row of the maze such as (1,0), (2,0),(3,0).
Step 3: Now, the robot moves down to the second row to the position of (3,1).
Step 4: The robot follows a path to the left (2,1), then down (2,2), then right (1,2), and then down again (0,2).
Step 5: Now, the robot moves right to reach the third row to the position (0,3).
Step 6: The robot moves right along the third row such as passing the positions of (1,3) and (2,3).
Step 7: The robot moves down to the fourth row (2,4) and then it moves left (1,4).
Step 8: The robot moves right to the last column (1,5).
Step 9: Finally, the robot reaches the goal node at the bottom-left corner(0,5) of the maze.
Output representationApplications of DFS in AI
- Maze generation: The Maze generation is comprised of designing a layout of passages and walls within a maze. This maze generation makes use of a randomized approach of the Depth-first search algorithm because it leverages the recursive method and stack. For instance, assume that the space is a large grid of cells where each cell holds the four walls. The DFS performs by selecting any random neighbor at first that has not been visited. It removes the wall between the two cells that are not connected and then it adds the new cell to the stack. This process continues until there is no more solution can be generated, resulting in a complete maze.
- Puzzle-solving: Puzzle-solving including Japanese nonograms can employ Depth-first search as a method for systematically exploring possible solutions. In Japanese nonograms, DFS is utilized to explore different combinations of filled and empty cells in the grid.
- Pathfinding in robotics: DFS can be employed for pathfinding in robotics, especially in scenarios where simplicity, memory efficiency, and adaptability are important considerations.
Conclusion
The Depth-first search emerges as a crucial algorithm in artificial intelligence that offers both theoretical insights and practical applications. DFS servers as a foundational tool for traversing complex state spaces. As the technology evolves, DFS remains a cornerstone algorithm for driving advancements and pushing the boundaries of AI research and applications.
Similar Reads
Breadth First Search (BFS) for Artificial Intelligence
In artificial intelligence, the Breadth-First Search (BFS) algorithm is an essential tool for exploring and navigating various problem spaces. By systematically traversing graph or tree structures, BFS solves tasks such as pathfinding, network routing, and puzzle solving. This article probes into th
14 min read
8 Best Topics for Research and Thesis in Artificial Intelligence
Imagine a future in which intelligence is not restricted to humans!!! A future where machines can think as well as humans and work with them to create an even more exciting universe. While this future is still far away, Artificial Intelligence has made a lot of advancements in these times. There is
7 min read
Game Playing in Artificial Intelligence
Game playing has always been a fascinating domain for artificial intelligence (AI). From the early days of computer science to the current era of advanced deep learning systems, games have served as benchmarks for AI development. They offer structured environments with clear rules, making them ideal
4 min read
Local Search Algorithm in Artificial Intelligence
Local search algorithms are essential tools in artificial intelligence and optimization, employed to find high-quality solutions in large and complex problem spaces. Key algorithms include Hill-Climbing Search, Simulated Annealing, Local Beam Search, Genetic Algorithms, and Tabu Search. Each of thes
4 min read
Issues in the Design of Search Programs in Artificial Intelligence
Search algorithms are fundamental in Artificial Intelligence (AI), enabling machines to navigate complex decision spaces and solve problems efficiently. From pathfinding in robotics to optimization problems in machine learning, search programs are at the heart of many AI applications. However, desig
6 min read
Artificial Intelligence in NASA and DARPA in 2000s
Artificial Intelligence was developed very rapidly and was being deployed successfully at NASA. In the year 1999, Remote Agent took Deep Space 1 on a galactic ride. In May 1999, an AI program called Remote Agent autonomously ran the spacecraft Deep Space 1 for two days. The remote agent system was s
5 min read
Semantic Networks in Artificial Intelligence
Semantic networks are a powerful tool in the field of artificial intelligence (AI), used to represent knowledge and understand relationships between different concepts. They are graphical representations that connect nodes (representing concepts) with edges (representing relationships). Semantic net
9 min read
Emergence Of Artificial Intelligence
Concept of AI goes back to the classical ages. Under greek mythology, the concept of machines and mechanical men were well thought of. In 1950, âALAS TURINGâ, published landmark paper âComputing Machinery and Intelligenceâ, proposes the âImitation Gameâ, known as the famous âTURING TESTâ He speculat
5 min read
Artificial Intelligence for GATE 2025
Welcome to the complete tutorial on Artificial Intelligence for the GATE DA Exam. This guide will simplify the syllabus topics, making them accessible and straightforward to understand for all aspirants.1. Introduction to AI and Search AlgorithmsUninformed SearchBreadth-First SearchDepth-First Searc
3 min read
Components of Artificial Intelligence (AI)
Artificial Intelligence (AI) helps machines to think, learn and act like humans. Components of AI help systems to mimic human intelligence which allows them to make decisions, solve problems and understand the world around them. In this article, weâll see these components and explain how they help A
5 min read