Lab 4
Lab 4
Student Name: Ibrahim, Hassaan, Huzaifa Reg. No: 220391, 222563, 222590
Objective: ____________________
LAB ASSESMENT:
Ability to
Conduct
Experiment
Ability to
assimilate the
results
Effective use of lab
equipment and
follows
the lab safety rules
Data presentation
Experimental results
Conclusion
Date: Signature:
Lab no. 03: Search Algorithms
Objective: The objective of this lab is to explore and compare different search strategies in artificial
intelligence, particularly focusing on the differences between informed (heuristic-based) and uninformed
(blind) search algorithms, as well as the distinction between finding any path versus finding the optimal
path.
1. Implementing and analyzing uninformed search algorithms such as branch and Bound (BnB).
2. Implementing and analyzing informed search algorithms such as A* search.
Search Algorithm:
Branch and Bound
The branch and bound is a depth first search based algorithm that considers the best path so far,
backtracking whenever it encounters a node whose value is larger than its current upper bound. The
algorithm terminates when all paths have been explored or pruned.
Function Definition:
Initialization:
The function is set up to explore paths in the graph, starting from the Start node.
It initializes a path with a cost of 0 and records the node being processed.
The main loop allows the function to continue searching for the Goal, processing one potential path at a
time. Each iteration involves checking a new node and the path taken to get there.
The function checks if the current node is the goal. If it is, it records the path and prints the result, then
exits the loop.
If the goal is not reached, it retrieves all neighboring nodes and marks the current node as visited,
preparing for further exploration of potential paths in subsequent iterations of the loop.
The function explores all neighboring nodes of the current node, calculating the costs to reach each
neighbor and updating the path accordingly.
It appends new paths to the Path list for further exploration.
By sorting the Path, the algorithm prioritizes lower-cost paths in subsequent iterations, which is key for
finding the optimal solution in terms of cost. Finally, the current state of Path is printed for debugging or
tracking purposes.
Lab Task:
1. Write down the code for A* search algorithm. Explain code in steps
properly.
from collections import deque # a double-ended queue for efficient FIFO queue operations.
graph = {
'A': ['B', 'C'], # Node A is connected to B and C
'B': ['D', 'E'], # Node B is connected to D and E
'C': ['F', 'G'], # Node C is connected to F and G
'D': [], # Node D is a leaf node (no connections)
'E': [], # Node E is a leaf node (no connections)
'F': [], # Node F is a leaf node (no connections)
'G': ['H', 'I'], # Node G is connected to H and I
'H': [], # Node H is a leaf node (no connections)
'I': [] # Node I is a leaf node (no connections)
}
Parameters:
graph (dict): The adjacency list representation of the graph.
start (str): The starting node.
goal (str): The target node to reach.
heuristic (dict): A dictionary representing heuristic values for each node.
Returns:
list: The path from the start node to the goal node, or None if no path is found.
"""
while queue:
queue = deque(sorted(list(queue), key=lambda x: x[2]))
(node, path, cost) = queue.popleft() # dequeue the node with the lowest cost.
if node not in visited: # if the node has not been visited before, process it.
visited.add(node) # mark the node as visited.
if node == goal: # if the goal is reached, return the path.
return path
for neighbor in graph[node]: # explore the neighbors of the current node.
if neighbor not in visited: # only add unvisited neighbors to the queue.
queue.append((neighbor, path + [neighbor], heuristic[neighbor]))
return None # return None if no path is found.
# heuristic values
heuristic = {
'A': 10,
'B': 8,
'C': 5,
'D': 7,
'E': 3,
'F': 6,
'G': 5,
'H': 3,
'I': 0
}
Conclusions:
The A* search algorithm effectively finds the shortest path by combining path cost and a heuristic estimate. In
our implementation, it consistently identified optimal paths across various scenarios. The performance of A*
heavily depends on the accuracy of the heuristic function, which influences its efficiency. Overall, the lab
demonstrated A* as a reliable and efficient algorithm for pathfinding problems.