How to get the shortest path? A clever problem-solver, however, if you use the Greedy Best-First Search (GBFS) algorithm, you are willing to help. Think of it as that one friend who always puts the best foot forward. In this series of articles, I will explain Greedy Best-First Search and show examples using Python code. In this blog post, Let us see the wonders of Greedy Best-First Search while it makes smart choices and when it is apt for the job.
Here’s a simple way to understand the GBFS algorithm:
Sounds simple, right? But there’s a catch! The GBFS algorithm doesn’t always find the shortest path because it only looks at what seems best right now, not considering the whole journey.
Let’s see an example using a simple grid. Imagine we have a 4×4 grid, and we want to go from the top-left corner (0, 0) to the bottom-right corner (3, 3). Here’s the grid with some obstacles:
[ [0, 1, 1, 1]
[1, 0, 1, 1]
[1, 0, 0, 1]
[1, 1, 0, 0] ]
In this grid, 1 means you can’t go through that cell, and 0 means you can. We’ll use the Euclidean distance as our heuristic, which is just a fancy way of saying the straight-line distance to the goal.
Here’s how we can write the Greedy Best-First Search algorithm in Python.
Python Code:
import heapq
import math
class Node:
def __init__(self, x, y, cost):
self.x = x
self.y = y
self.cost = cost
def __lt__(self, other):
return self.cost < other.cost
def euclidean_distance(x1, y1, x2, y2):
return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
def greedy_best_first_search(grid, start, goal):
rows = len(grid)
cols = len(grid[0])
pq = []
heapq.heappush(pq, Node(start[0], start[1], 0))
visited = set()
visited.add((start[0], start[1]))
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
while pq:
current = heapq.heappop(pq)
if (current.x, current.y) == goal:
print(f"Goal reached at ({current.x}, {current.y})")
return
for d in directions:
new_x, new_y = current.x + d[0], current.y + d[1]
if 0 <= new_x < rows and 0 <= new_y < cols and grid[new_x][new_y] == 0 and (new_x, new_y) not in visited:
cost = euclidean_distance(new_x, new_y, goal[0], goal[1])
heapq.heappush(pq, Node(new_x, new_y, cost))
visited.add((new_x, new_y))
print("Goal not reachable")
# Example grid
grid = [
[0, 1, 1, 1],
[1, 0, 1, 1],
[1, 0, 0, 1],
[1, 1, 0, 0]
]
start = (0, 0)
goal = (3, 3)
greedy_best_first_search(grid, start, goal)
When you run this code, it starts from the top-left corner (0, 0) and tries to move to the bottom-right corner (3, 3). It picks the next step based on which one looks closest to the goal using the Euclidean distance.
Advantages:
Disadvantages:
The Greedy Best-First Search algorithm provides a valuable technique for tackling pathfinding problems in grids or graphs. Its strength lies in rapidly identifying promising routes toward the goal by leveraging a well-designed heuristic function. However, it’s crucial to understand that the GBFS approach does not guarantee finding the optimal, shortest path. Its greedy nature may sometimes lead it astray if the heuristic is imperfect or misleading.
Despite this limitation, the algorithm’s simplicity, efficiency, and ability to produce reasonably good solutions quickly make it a valuable tool for programmers, particularly in time-sensitive situations where a near-optimal solution is preferable to an exhaustive but computationally expensive search for the absolute shortest path. Careful implementation and heuristic design can help harness the power of GBFS for a wide range of pathfinding challenges.
A. The Greedy Best-First Search algorithm is a pathfinding technique that selects the next move based on which option appears closest to the goal, using a heuristic to guide its decisions.
A. Unlike algorithms like A* that consider both the current cost and the estimated cost to the goal, GBFS focuses only on the heuristic estimate to the goal, making it faster but not always optimal.
A. No, GBFS does not guarantee the shortest path because it only considers the heuristic estimate and not the overall cost from the start to the goal.