Open In App

Greedy Best-First Search in AI

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Greedy Best-First Search in AI is a graph traversal algorithm designed to find the shortest path or solve problems with multiple possible solutions. It is a heuristic search algorithm, means it uses a heuristic function to guide the search process by estimating how close a path is to the goal.

Unlike search methods that don't have prior knowledge, it uses heuristic rules or estimates that gives direction for search. It is popular because of its simplicity and efficiency in certain situations. This makes it an informed search algorithm because it uses problem-specific knowledge to decide the next step, focusing on the most promising path without revisiting previous choices.

How Does Greedy Best-First Search Work?

Greedy Best-First Search algorithm operates by exploring nodes in a graph by always choosing the one that appears closest to the goal. The algorithm evaluates the nodes based on a heuristic function which estimates the cost from the current node to the goal. It’s called "greedy" because it selects the node that seems to be the best choice at the moment, focusing only on immediate progress.

The algorithm does not backtrack or reconsider nodes that seem less optimal making it fast but potentially incomplete if the path it chooses does not lead to a solution.

Let's see step-by-step how Greedy Best-First Search algorithm works:

  1. Initialization: We start at the initial node and add it to a priority queue.
  2. Expand Nodes: The algorithm evaluates all neighboring nodes, assigning each one a value based on the heuristic function (representing the estimated distance to the goal).
  3. Select the Best Node: From the priority queue, the node with the lowest heuristic value is selected. This node is considered the most promising.
  4. Goal Check: If the selected node is the goal, the search terminates. If not, the algorithm continues exploring.
  5. Repeat: Steps 2-4 are repeated until the goal is found or the search space is exhausted.

Role of Heuristics in Greedy Best-First Search (GBFS)

Greedy Best-First Search is highly depends on the heuristic function used. A heuristic is a function that estimates the cost to reach the goal from the current node. A good heuristic leads to fast and efficient searching while a poor heuristic can cause inefficiency or even failure.

Common heuristics include:

  • Euclidean Distance: Straight-line distance between the current node and the goal, used in pathfinding problems.
  • Manhattan Distance: The sum of absolute differences between the coordinates of two points, often applied in grid-based environments.

The choice of heuristic influences how the algorithm behaves and whether it can find an optimal solution efficiently.

Greedy Best-First Search for Hierarchical Routing

Let’s see an example of how GBFS can be applied in a real-world scenario like hierarchical routing. Here we’ll use a graph where nodes represent locations and edges represent possible paths between them. Each node has a heuristic value showing how close it is to the goal.

Step 1: Importing the Required Libraries

We will be importing Heapq, Networkx and Matplotlib libraries.

Python
import heapq
import networkx as nx
import matplotlib.pyplot as plt

Step 2: Defining the Node Class

We start by defining a Node class to represent each location. Each node stores its name and heuristic value and the __lt__ function allows comparison between nodes based on their heuristic values. This is important for maintaining the priority queue.

Python
class Node:
    def __init__(self, name, heuristic):
        self.name = name
        self.heuristic = heuristic

    def __lt__(self, other):
        return self.heuristic < other.heuristic
      

Step 3: Implementing Greedy Best-First Search Algorithm

The core of the algorithm is the greedy_best_first_search_hierarchical function. This function performs the Greedy Best-First Search (GBFS) by starting at the initial node, pushing it onto a priority queue and exploring the nodes based on their heuristic values. It first prioritizes nodes within the same region and then moves on to other regions if necessary.

Python
def greedy_best_first_search_hierarchical(graph, start, goal, heuristic, region_map):
    priority_queue = []
    heapq.heappush(priority_queue, Node(start, heuristic[start]))
    
    visited = set()
    path = {start: None}
    
    while priority_queue:
        current_node = heapq.heappop(priority_queue).name
        
        if current_node == goal:
            return reconstruct_path(path, start, goal)
        
        visited.add(current_node)
        
        current_region = region_map[current_node]
        for neighbor in graph[current_node]:
            if neighbor not in visited and region_map[neighbor] == current_region:
                heapq.heappush(priority_queue, Node(neighbor, heuristic[neighbor]))
                if neighbor not in path:
                    path[neighbor] = current_node

        for neighbor in graph[current_node]:
            if neighbor not in visited and region_map[neighbor] != current_region:
                heapq.heappush(priority_queue, Node(neighbor, heuristic[neighbor]))
                if neighbor not in path:
                    path[neighbor] = current_node

    return None

Step 4: Reconstructing the Path

Once the goal node is reached, we need to reconstruct the path from the start node to the goal node by backtracking through the path dictionary. This helper function does that by following the parent nodes.

Python
def reconstruct_path(path, start, goal):
    current = goal
    result_path = []
    while current is not None:
        result_path.append(current)
        current = path[current]
    result_path.reverse()
    return result_path

Step 5: Visualizing the Graph and Path

This function uses the networkx and matplotlib libraries to visually display the graph and highlight the path found by the search algorithm. Additionally, it adds region labels to the nodes for better understanding.

Python
def visualize_graph(graph, path, pos, region_map):
    G = nx.Graph()
    for node, neighbors in graph.items():
        for neighbor in neighbors:
            G.add_edge(node, neighbor)

    plt.figure(figsize=(10, 8))
    nx.draw(G, pos, with_labels=True, node_size=4000, node_color='skyblue', 
            font_size=15, font_weight='bold', edge_color='gray')

    if path:
        path_edges = list(zip(path, path[1:]))
        nx.draw_networkx_edges(G, pos, edgelist=path_edges, edge_color='green', width=3)
        nx.draw_networkx_nodes(G, pos, nodelist=path, node_color='lightgreen')

    for node, region in region_map.items():
        plt.text(pos[node][0], pos[node][1] - 0.2, f"Region {region}", fontsize=12, color='black')

    plt.title("Greedy Best-First Search for Hierarchical Routing", size=20)
    plt.show()

Step 6: Defining the Graph and Heuristic Values

Here we define the graph's structure where nodes are connected to their neighbors. We also set heuristic values for each node to guide the search process and assign regions to the nodes for hierarchical routing.

Python
graph = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F', 'G'],
    'D': ['H'],
    'E': ['I', 'J'],
    'F': ['K' , 'M' , 'E'],
    'G': ['L', 'M'],
    'H': [],
    'I': [],
    'J': [],
    'K': [],
    'L': [],
    'M': []
}

heuristic = {
    'A': 8,
    'B': 6,
    'C': 7,
    'D': 5,
    'E': 4,
    'F': 5,
    'G': 4,
    'H': 3,
    'I': 2,
    'J': 1,
    'K': 3,
    'L': 2,
    'M': 1
}

region_map = {
    'A': 1, 'B': 1, 'C': 1,
    'D': 2, 'E': 2,
    'F': 3, 'G': 3,
    'H': 2, 'I': 2, 'J': 2,
    'K': 3, 'L': 3, 'M': 3
}

Step 7: Execute the Search and Visualize the Result

Once all the components are in place, we execute the Greedy Best-First Search from the starting node 'A' to the goal node 'M' and then visualize the resulting path to see how the algorithm performs in practice.

Python
pos = {
    'A': (0, 0),
    'B': (-1, 1),
    'C': (1, 1),
    'D': (-1.5, 2),
    'E': (-0.5, 2),
    'F': (0.5, 2),
    'G': (1.5, 2),
    'H': (-2, 3),
    'I': (-1, 3),
    'J': (0, 3),
    'K': (1, 3),
    'L': (2, 3),
    'M': (3, 3)
}

start_node = 'A'
goal_node = 'M'
result_path = greedy_best_first_search_hierarchical(graph, start_node, goal_node, heuristic, region_map)

print("Path from {} to {}: {}".format(start_node, goal_node, result_path))

visualize_graph(graph, result_path, pos, region_map)

Output:

Path from A to M: ['A', 'C', 'G', 'M']

Greedy-best-First-Search-in-AI
Result

Greedy Best-First Search offers various advantages that make it a popular choice in various AI applications:

  1. Speed: It is generally faster than uninformed search algorithms like Breadth-First Search because it uses heuristic information.
  2. Simplicity: The algorithm is simple to implement and understand, making it a preferred choice in cases where speed is more important than optimality.
  3. Resource-Efficient: Since it focuses on the path that seems most promising, it may require less memory compared to algorithms like A*.

Despite its advantages, Greedy Best-First Search has several limitations that can impact its effectiveness.

  1. Incomplete: It is not guaranteed to find a solution especially if it gets stuck in a local optimum or reaches a dead-end. Since there is no backtracking, it may overlook valid paths that require revisiting nodes to get a better result.
  2. Non-Optimal: Unlike A*, it does not guarantee an optimal solution. Its greedy nature makes it focus on the nearest node which may not always lead to the best path. This can result in suboptimal solutions especially in complex problem spaces.
  3. Heuristic Dependency: The efficiency and success of GBFS depends on the quality of the heuristic. A bad heuristic could mislead the search, leading to inefficient exploration or even failure to find a path.

Applications of Greedy Best-First Search in AI

It has various practical applications across various AI and computer science fields:

  1. Pathfinding: It is used in map navigation systems and video game AI for efficient pathfinding from one point to another.
  2. Puzzle Solving: In puzzles such as the 8-puzzle or 15-puzzle, it is often used to find the quickest way to reach a goal state, i.e arranging tiles in the correct order.
  3. Robot Navigation: Autonomous robots use GBFS for navigation in unknown or dynamic environments as the heuristic helps the robot choose paths that appear to bring it closest to the goal efficiently.
  4. Artificial Intelligence Planning: It is used in various AI planning tasks such as automated problem-solving where there are multiple potential solutions and a fast solution is more important than the most optimal one.

By mastering Greedy Best-First Search, we can tackle its efficiency and simplicity making it a useful for solving a wide range of AI challenges.


Similar Reads