0% found this document useful (0 votes)
17 views

Lab 4

Uploaded by

220391
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

Lab 4

Uploaded by

220391
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

AIR UNIVERSITY

DEPARTMENT OF ELECTRICAL AND


COMPUTER ENGINEERING
LAB NO 4

Lab Title: Search Algorithms: Branch and Bound, A*

Student Name: Ibrahim, Hassaan, Huzaifa Reg. No: 220391, 222563, 222590

Objective: ____________________

LAB ASSESMENT:

Attributes Excellent(5) Good Average Satisfactory Unsatisfactory


(4) (3) (2) (1)

Ability to
Conduct
Experiment
Ability to
assimilate the
results
Effective use of lab
equipment and
follows
the lab safety rules

Total Marks: Obtained Marks:

LAB REPORT ASSESSMENT:

Attributes Excellent(5) Good Average Satisfactory Unsatisfactory


(4) (3) (2) (1)

Data presentation

Experimental results

Conclusion

Total Marks: Obtained Marks:

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)
}

def A_code(graph, start, goal, heuristic):


"""
A simple A* algorithm to find a path from the start node to the goal node in a graph.

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.
"""

queue = deque([(start, [start], heuristic[start])]) # initialize a queue with the


start node, its current path, and its heuristic cost.

visited = set() # set to keep track of visited nodes.

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
}

path = A_code(graph, 'A', 'I', heuristic)


if path:
print(path)
else:
print("No path found")

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.

You might also like