Open In App

Iterative Deepening A* algorithm (IDA*) in Artificial intelligence

Last Updated : 16 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Iterative deepening A (IDA)** is a powerful graph traversal and pathfinding algorithm designed to find the shortest path in a weighted graph. This method combines features of iterative deepening depth-first search (IDDFS) and the A search algorithm* by using a heuristic function to estimate the remaining cost to the goal node. IDA* is often referred to as a memory-efficient version of A*, as it requires significantly less memory while still ensuring optimal pathfinding.

This article aims to explain how the Iterative Deepening A* (IDA*) algorithm efficiently finds the shortest path in a weighted graph while using minimal memory.

What is the Iterative Deepening A* (IDA*) Algorithm?

IDA* is a variant of depth-first search (DFS) that iteratively deepens its search by incrementing the cost threshold, which controls the depth of the exploration. Unlike A*, which explores all possible nodes within a threshold, IDA* uses a heuristic function to evaluate and prioritize the most promising nodes. This allows it to prune less promising paths, reducing memory usage while ensuring that the search focuses on optimal routes.

Key Features of IDA* Algorithm

  1. Graph Traversal Algorithm: IDA* explores a graph by progressively deepening the search depth.
  2. Shortest Pathfinding: It efficiently finds the shortest path in a weighted graph using a combination of DFS and A* techniques.
  3. Admissible Heuristic: The heuristic function in IDA* ensures that the estimated cost never exceeds the actual cost, making it an admissible heuristic.
  4. Memory Efficiency: As a depth-first search algorithm, IDA* uses far less memory compared to the traditional A* algorithm.
  5. Focused Search: The algorithm is designed to explore only the most promising nodes, ensuring it doesn’t go to unnecessary depths.

How the IDA* Algorithm Works?

The IDA* algorithm works by incrementally increasing the threshold based on the f-score of each node, which is calculated using the formula:

[Tex]f(n) = g(n) + h(n)[/Tex]

[Tex]f(n) = \text{Actual\;cost} + \text{Estimated \; cost}[/Tex]

Where h is admissible.

Here,

  • f(n)  = Total cost evaluation function.
  • g(n) = The actual cost from the initial node to the current node.
  • h(n) = Heuristic estimated cost from the current node to the goal state. it is based on the approximation according to the problem characteristics.

What is the F-score?

In the IDA* algorithm, F-score is a heuristic function that is used to estimate the cost of reaching the goal state from a given state. It is a combination of two other heuristic functions, g(n) and h(n).
It is used to determine the order in which the algorithm expands nodes in the search tree and thus, it plays an important role in how quickly the algorithm finds a solution.

A lower F-score indicates that a node is closer to the goal state and will be expanded before a node with a higher F-score. Simply it is nothing but g(n) + h(n).

Step-by-Step Process of the IDA* Algorithm 

  1. Initialization: Set the root node as the current node and compute its f-score.
  2. Set Threshold: Initialize a threshold based on the f-score of the starting node.
  3. Node Expansion: Expand the current node’s children and calculate their f-scores.
  4. Pruning: If the f-score exceeds the threshold, prune the node and store it for future exploration.
  5. Path Return: Once the goal node is found, return the path from the start node to the goal.
  6. Update Threshold: If the goal is not found, increase the threshold based on the minimum pruned value and repeat the process.

Example of IDA* Algorithm

In the below tree, the f score is written inside the nodes means the f score is already computed and the start node is 2 whereas the goal node is 15. the explored node is colored green color.

So now we have to go to a given goal by using IDA* algorithm.

Iteration 1

Iteration 1

  • Root node as current node i.e 2 
  • Threshold = current node value (2=2). So explore its children.
  • 4 > Threshold & 5>Threshold. So, this iteration is over and the pruned values are 4, and 5.

Iteration 2

Iteration 2

  • In pruned values, the least is 4, So threshold = 4
  • current node = 2  and 2< threshold, So explore its children. i.e two children explore one by one
  • So, first children 4, So, set current node = 4 i.e equal to the threshold, so, explored its children also i.e  5, 4 having 5> threshold so, pruned it and explore second child of node 4 i.e 4, so set current node = 4 = threshold, and explore its children i.e 8 & 7 having both 8 & 7 > threshold so, pruned it. At the end of this, our pruned value is 5,8,7
  • Similarly, Explore the second child of root node 2 i.e 5 as the current node, i.e 5>threshold, So pruned it.
  • So, our pruned value is 5,8,7.

Iteration 3

Iteration 3

  • In pruned values, the least is 5, So threshold = 5
  • current node = root node = 2  and 2< threshold, So explore its children. i.e two children explore one by one
  • So, first children 4, So, set current node = 4 < threshold, so, explored its children also i.e  5, 4 having 5= threshold so explore its child also 7&8 > threshold. So, pruned it and explore the second child of node 4 i.e 4, so set current node = 4 < threshold, and explore its children i.e 8 & 7 here, both 8 & 7 > threshold so, pruned it. At the end of this, our pruned value is 7 & 8
  • Similarly, Explore the second child of root node 2 i.e 5 as the current node, i.e 5 = threshold, so, explored its children also i.e  6 & 6, i.e both 6 & 6 > threshold. So pruned it
  • So, our pruned value is 7,8 & 6

Iteration 4

  • In pruned values, the least value is 6, So threshold = 6
  • current node = root node = 2  and 2< threshold, So explore its children. i.e two children explore one by one
  • So, the first child is 4, So, set current node = 4 < threshold, so, explored its children also i.e  5, 4 having 5< threshold so explore its child also 7&8 > threshold. So, pruned it and explore the second child of node 4 i.e 4, so set current node = 4 < threshold, and explore its children i.e 8 & 7 here, both 8 & 7 > threshold so, pruned it. At the end of this, our pruned value is 7 & 8
  • Similarly, Explore the second child of root node 2 i.e 5 as the current node, i.e 5 = threshold, so, explored its children also i.e  6 & 6, i.e both 6 & 6 = threshold, So, explore one by one,
  •  The first 6 has two children i.e 6 & 8, having 6 = threshold. So, explore its child also i.e 13 & 7. here both 13 & 7 > Threshold. So, pruned it. next is 8 > Threshold. pruned it, So, pruned value at this stage is 13,7 & 8.
  • Explore the second child of 5 i.e 6 = Threshold. So, explore its child i.e 7 & 9. Both are greater than Threshold. So, pruned it
  • So, our pruned values are 13,7,8 & 9. 

Iteration 5

  • In pruned values, the least value is 7, So threshold = 7
  • current node = root node = 2  and 2< threshold, So explore its children. i.e two children explore one by one
  • So, the first child is 4, So, set current node = 4 < threshold, so, explored its children also i.e  5, 4 
  • The first child of 4 is 5 i.e 5< threshold so explore its child also 7&8, Here 7 = threshold. So, explore its children i.e 12 & 14, both > Threshold. So, pruned it. And the second child of 5 is 8 > Threshold, So, pruned it. At this stage, our pruned value is 12, 14  & 7.
  • Now explore the second child of node 4 i.e 4, so set current node = 4 < threshold, and explore its children i.e 8 & 7 here, 8 > threshold so, pruned it. then go to the second child i.e 7 = Threshold, So explore its children i.e 13 & 8. having both > Threshold. So pruned it. At the end of this, our pruned value is 12,14,8 & 13
  • Similarly, Explore the second child of root node 2 i.e 5 as the current node, i.e 5 < threshold, so, explored its children also i.e  6 & 6, i.e both 6 & 6 < threshold, So, explore one by one,
  •  The first 6 has two children i.e 6 & 8, having 6 < threshold. So, explore its child also i.e 13 & 7. here 13 > Threshold. So, pruned it. And 7= Threshold. And it hasn’t any child. So, the shift to the next sub-child of 6 i.e 8 > threshold, So, pruned it. The pruned value at this stage is  12,14,8 &13
  • Explore the second child of 5 i.e 6 < Threshold. So, explore its child i.e 7 & 9. Here 7 = Threshold, So, explore its children i.e  8 & 14, Both are greater than Threshold. So, pruned it, Now the sub child of 6 is 9 > Threshold, So, pruned it.  
  • So, our pruned values are 12,14,8,13 & 9.

Iteration 6

Iteration 6

  • In pruned values, the least value is 8, So threshold = 8
  • current node = root node = 2  and 2< threshold, So explore its children. i.e two children explore one by one
  • So, the first child is 4, So, set current node = 4 < threshold, so, explored its children also i.e  5, 4 
  • The first child of 4 is 5 i.e 5< threshold so explore its child also 7&8, Here 7 < threshold. So, explore its children i.e 12 & 14, both > Threshold. So, pruned it. And the second child of 5 is 8 = Threshold, So,  So, explore its children i.e 16 & 15, both > Threshold. So, pruned it. At this stage, our pruned value is 12, 14, 16 & 15.
  • Now explore the second child of node 4 i.e 4, so set current node = 4 < threshold, and explore its children i.e 8 & 7 here, 8 = Threshold, So,  So, explore its children i.e 12 & 9, both > Threshold. So, pruned it. then go to the second child i.e 7 < Threshold, So explore its children i.e 13 & 8. having 13 > Threshold. So pruned it.  and 8 = Threshold and it hasn’t any child. At the end of this, our pruned values are 12, 14, 16, 15, and 13.
  • Similarly, Explore the second child of root node 2 i.e 5 as the current node, i.e 5 < threshold, so, explored its children also i.e  6 & 6, i.e both 6 & 6 < threshold, So, explore one by one,
  •  The first 6 has two children i.e 6 & 8, having 6 < threshold. So, explore its child also i.e 13 & 7. here 13 > Threshold. So, pruned it. And 7<Threshold. And it hasn’t any child. So, the shift to the next sub-child of 6 i.e 8 = threshold. So,  explored its children also i.e  15 & 16, Here 15 = Goal Node. So, stop this iteration. Now no need to explore more.
  • The goal path is 2–>5–>6–>8–>15

Real-World Applications of IDA*

1. The 15-Puzzle Problem

The 15-puzzle problem is a classic example of a sliding puzzle game. It consists of a 4×4 grid of numbered tiles with one tile missing. The aim is to rearrange the tiles to form a specific goal configuration. The state space of the puzzle can be represented as a tree where each node represents a configuration of the puzzle and each edge represents a legal move. IDA* can be used to find the shortest sequence of moves to reach the goal state from the initial state.

2. The 8-Queens Problem

The 8-Queens problem is a classic example of the n-Queens problem where n queens have been placed on an n x n chessboard such that no two queens attack each other. The state space of the problem can be represented as a tree where each node represents a configuration of the chessboard and each edge represents the placement of a queen. IDA* can be used to find the minimum number of queens that need to be moved to reach the goal state.

In both of these examples, IDA* is used to find the optimal solution by using a combination of depth-first search and a heuristic function to limit the search space. The algorithm incrementally increases the depth bound, allowing it to find the solution without exploring the entire state space, which would be infeasible for larger problems.

Advantages and Disadvantages of Iterative Deepening A* algorithm (IDA*)

Advantages

  1. Optimal Pathfinding: IDA* guarantees finding the optimal path, as it never overestimates the cost to the goal.
  2. Memory Efficient: It uses limited memory compared to A* by applying depth-first search techniques.
  3. Admissible Heuristic: The heuristic function ensures that the algorithm remains admissible, thus optimizing performance.
  4. Efficient with Large State Spaces: IDA* handles large graphs efficiently by pruning unnecessary nodes.

Disadvantages

  1. Repeated Node Exploration: The algorithm does not store visited nodes, leading to repeated exploration.
  2. Slower than A*: IDA* can be slower than algorithms like A* due to the repeated exploration of nodes.
  3. Higher Computational Cost: It may take longer and consume more processing power compared to other algorithms like A* or breadth-first search.

It’s important to note that IDA* is not suitable for all types of problems, and the choice of algorithm will depend on the specific characteristics of the problem you’re trying to solve.

IDA* vs Iterative Deepening Depth-First Search (IDDFS)

The table given below highlights the differences between IDA* and Iterative Deepening Depth-First Search (IDDFS):

CriteriaIterative Deepening Depth-First Search (IDDFS)Iterative Deepening A (IDA)**
SystematicSystematic exploration of the search space.Not systematic; may revisit nodes due to threshold updates.
OptimalityGuarantees optimal solution in unweighted graphs.Optimal, but only expands nodes where f-score ≤ threshold.
Node ExpansionNever expands the same node twice.May expand the same node multiple times if f-score < threshold.
Handling Infinite Search TraversalNot suited for infinite search traversal.Better suited for infinite search traversal compared to IDDFS.

Applications of IDA* in Artificial intelligence

IDA* is particularly suited for solving complex AI problems where memory is limited. Here are a few areas where it is commonly applied:

  1. Pathfinding in Games: IDA* is frequently used in video games where memory is a constraint, and optimal paths need to be found efficiently, such as in real-time strategy games.
  2. Robot Navigation: In robotics, IDA* is applied to efficiently navigate through complex environments without requiring excessive memory.
  3. Puzzle Solving: Classic AI problems like the 8-puzzle or 15-puzzle can be solved using IDA*, where the search space is large and memory constraints are significant.
  4. Artificial General Intelligence (AGI): In research areas exploring AGI, where problem-solving often involves navigating vast search spaces, IDA* can be used to manage memory while finding optimal solutions.

Conclusion

The Iterative Deepening A (IDA*) algorithm* strikes a balance between memory efficiency and optimal pathfinding by combining the strengths of depth-first search and heuristic functions. It prunes unpromising paths, allowing it to handle larger state spaces than traditional algorithms. While IDA* might not be the fastest option, its ability to find the optimal solution while using less memory makes it an excellent choice for solving problems like the 15-puzzle and n-Queens problems. It’s a robust solution for graph traversal and pathfinding when memory efficiency is a concern.



Next Article

Similar Reads