0% found this document useful (0 votes)
59 views17 pages

AI Lab Manual: Search Algorithms

The document describes implementing various graph search algorithms like BFS, DFS, A*, and memory-bounded A* on sample graph data. It includes Python code implementing BFS and DFS, traversing a graph represented as an adjacency list and printing the node search order. Code for A* search is also provided, using a heuristic function to find the lowest cost path between nodes.

Uploaded by

shamilie17
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
59 views17 pages

AI Lab Manual: Search Algorithms

The document describes implementing various graph search algorithms like BFS, DFS, A*, and memory-bounded A* on sample graph data. It includes Python code implementing BFS and DFS, traversing a graph represented as an adjacency list and printing the node search order. Code for A* search is also provided, using a heuristic function to find the lowest cost path between nodes.

Uploaded by

shamilie17
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

EX.

NO: 1 Implementation of Uninformed search algorithms (BFS, DFS)

GRAPH:

PROGRAM: BFS

graph = {
'1': ['2','3','4'],
'2': ['5', '6'],
'3':[],
'5': ['9','10'],
'4': ['7','8'],
'7': ['11','12'],
'6':[],
'8':[],
'9':[],
'10':[],
'11':[],
'12':[]
}
visited = [] # List for visited nodes.
queue = [] #Initialize a queue

def bfs(visited, graph, node): #function for BFS


[Link](node)
[Link](node)

while queue: # Creating loop to visit each node


m = [Link](0)
print (m, end = " ")

for neighbour in graph[m]:


if neighbour not in visited:
[Link](neighbour)
[Link](neighbour)

# Driver Code
print("Following is the Breadth-First Search")
bfs(visited, graph, '5') # function calling

OUTPUT:
Following is the Breadth-First Search
1 2 3 4 5 6 7 8 9 10 11 12
GRAPH:

PROGRAM: DFS

# Using a Python dictionary to act as an adjacency list


graph = {
'1': ['2','3','4'],
'2': ['5', '6'],
'3':[],
'5': ['9','10'],
'4': ['7','8'],
'7': ['11','12'],
'6':[],
'8':[],
'9':[],
'10':[],
'11':[],
'12':[]
}
visited = set() # Set to keep track of visited nodes of graph.

def dfs(visited, graph, node): #function for dfs


if node not in visited:
print (node)
[Link](node)
for neighbour in graph[node]:
dfs(visited, graph, neighbour)
# Driver Code
print("Following is the Depth-First Search")
dfs(visited, graph, '5')

OUTPUT:
Following is the Depth-First Search
1
2
5
9
10
6
3
4
7
11
12
8
[Link]: 2 Implementation of Informed search algorithms (A*,
memory-bounded A*)
GRAPH: A*

PROGRAM:
def aStarAlgo(start_node, stop_node):

open_set = set(start_node)

closed_set = set()

g = {} #store distance from starting node

parents = {} # parents contains an adjacency map of all nodes

#distance of starting node from itself is zero

g[start_node] = 0

#start_node is root node i.e it has no parent nodes

#so start_node is set to its own parent node

parents[start_node] = start_node

while len(open_set) > 0:

n = None

#node with lowest f() is found

for v in open_set:

if n == None or g[v] + heuristic(v) < g[n] + heuristic(n):

n=v

if n == stop_node or Graph_nodes[n] == None:

pass

else:

for (m, weight) in get_neighbors(n):

#nodes 'm' not in first and last set are added to first
#n is set its parent

if m not in open_set and m not in closed_set:

open_set.add(m)

parents[m] = n

g[m] = g[n] + weight

#for each node m,compare its distance from start i.e g(m) to the

#from start through n node

else:

if g[m] > g[n] + weight:

#update g(m)

g[m] = g[n] + weight

#change parent of m to n

parents[m] = n

#if m in closed set,remove and add to open

if m in closed_set:

closed_set.remove(m)

open_set.add(m)

if n == None:

print('Path does not exist!')

return None

# if the current node is the stop_node

# then we begin reconstructin the path from it to the start_node

if n == stop_node:

path = []

while parents[n] != n:

[Link](n)

n = parents[n]

[Link](start_node)

[Link]()

print('Path found: {}'.format(path))

return path

# remove n from the open_list, and add it to closed_list

# because all of his neighbors were inspected

open_set.remove(n)

closed_set.add(n)
print('Path does not exist!')

return None

#define fuction to return neighbor and its distance

#from the passed node

def get_neighbors(v):

if v in Graph_nodes:

return Graph_nodes[v]

else:

return None

def heuristic(n):

H_dist = {

'A': 11,

'B': 6,

'C': 99,

'D': 1,

'E': 7,

'G': 0,

return H_dist[n]

#Describe your graph here

Graph_nodes = {

'A': [('B', 2), ('E', 3)],

'B': [('A', 2), ('C', 1), ('G', 9)],

'C': [('B', 1)],

'D': [('E', 6), ('G', 1)],

'E': [('A', 3), ('D', 6)],

'G': [('B', 9), ('D', 1)]

aStarAlgo('A', 'G')

OUTPUT:

Path found: ['A', 'E', 'D', 'G']

['A', 'E', 'D', 'G']


[Link] Implementing Naive Bayes algorithm from scratch
using Python

PROGRAM:
# Importing library
import math
import random
import csv

# the categorical class names are changed to numberic data


# eg: yes and no encoded to 1 and 0
def encode_class(mydata):
classes = []
for i in range(len(mydata)):
if mydata[i][-1] not in classes:
[Link](mydata[i][-1])
for i in range(len(classes)):
for j in range(len(mydata)):
if mydata[j][-1] == classes[i]:
mydata[j][-1] = i
return mydata

# Splitting the data


def splitting(mydata, ratio):
train_num = int(len(mydata) * ratio)
train = []
# initially testset will have all the dataset
test = list(mydata)
while len(train) < train_num:
# index generated randomly from range 0
# to length of testset
index = [Link](len(test))
# from testset, pop data rows and put it in train
[Link]([Link](index))
return train, test

# Group the data rows under each class yes or


# no in dictionary eg: dict[yes] and dict[no]
def groupUnderClass(mydata):
dict = {}
for i in range(len(mydata)):
if (mydata[i][-1] not in dict):
dict[mydata[i][-1]] = []
dict[mydata[i][-1]].append(mydata[i])
return dict

# Calculating Mean
def mean(numbers):
return sum(numbers) / float(len(numbers))

# Calculating Standard Deviation


def std_dev(numbers):
avg = mean(numbers)
variance = sum([pow(x - avg, 2) for x in numbers]) /
float(len(numbers) - 1)
return [Link](variance)

def MeanAndStdDev(mydata):
info = [(mean(attribute), std_dev(attribute)) for attribute in
zip(*mydata)]
# eg: list = [ [a, b, c], [m, n, o], [x, y, z]]
# here mean of 1st attribute =(a + m+x), mean of 2nd attribute
= (b + n+y)/3
# delete summaries of last class
del info[-1]
return info

# find Mean and Standard Deviation under each class


def MeanAndStdDevForClass(mydata):
info = {}
dict = groupUnderClass(mydata)
for classValue, instances in [Link]():
info[classValue] = MeanAndStdDev(instances)
return info

# Calculate Gaussian Probability Density Function


def calculateGaussianProbability(x, mean, stdev):
expo = [Link](-([Link](x - mean, 2) / (2 *
[Link](stdev, 2))))
return (1 / ([Link](2 * [Link]) * stdev)) * expo

# Calculate Class Probabilities


def calculateClassProbabilities(info, test):
probabilities = {}
for classValue, classSummaries in [Link]():
probabilities[classValue] = 1
for i in range(len(classSummaries)):
mean, std_dev = classSummaries[i]
x = test[i]
probabilities[classValue] *=
calculateGaussianProbability(x, mean, std_dev)
return probabilities

# Make prediction - highest probability is the prediction


def predict(info, test):
probabilities = calculateClassProbabilities(info, test)
bestLabel, bestProb = None, -1
for classValue, probability in [Link]():
if bestLabel is None or probability > bestProb:
bestProb = probability
bestLabel = classValue
return bestLabel
# returns predictions for a set of examples
def getPredictions(info, test):
predictions = []
for i in range(len(test)):
result = predict(info, test[i])
[Link](result)
return predictions

# Accuracy score
def accuracy_rate(test, predictions):
correct = 0
for i in range(len(test)):
if test[i][-1] == predictions[i]:
correct += 1
return (correct / float(len(test))) * 100.0

# driver code

# add the data path in your system


filename = r'E:\user\MACHINE LEARNING\machine learning algos\
Naive bayes\[Link]'

# load the file and store it in mydata list


mydata = [Link](open(filename, "rt"))
mydata = list(mydata)
mydata = encode_class(mydata)
for i in range(len(mydata)):
mydata[i] = [float(x) for x in mydata[i]]

# split ratio = 0.7


# 70% of data is training data and 30% is test data used for testing
ratio = 0.7
train_data, test_data = splitting(mydata, ratio)
print('Total number of examples are: ', len(mydata))
print('Out of these, training examples are: ', len(train_data))
print("Test examples are: ", len(test_data))

# prepare model
info = MeanAndStdDevForClass(train_data)

# test model
predictions = getPredictions(info, test_data)
accuracy = accuracy_rate(test_data, predictions)
print("Accuracy of your model is: ", accuracy)
OUTPUT:
Total number of examples are: 200
Out of these, training examples are: 140
Test examples are: 60
Accuracy of your model is: 71.2376788
[Link] Implement Bayesian Networks

PROGRAM:
import numpy as np
import pandas as pd
import csv
from [Link] import MaximumLikelihoodEstimator
from [Link] import BayesianModel
from [Link] import VariableElimination

heartDisease = pd.read_csv('[Link]')
heartDisease = [Link]('?',[Link])

print('Sample instances from the dataset are given below')


print([Link]())

print('\n Attributes and datatypes')


print([Link])

model= BayesianModel([('age','heartdisease'),('sex','heartdisease'),
('exang','heartdisease'),('cp','heartdisease'),('heartdisease','restecg'),
('heartdisease','chol')])
print('\nLearning CPD using Maximum likelihood estimators')
[Link](heartDisease,estimator=MaximumLikelihoodEstimator)

print('\n Inferencing with Bayesian Network:')


HeartDiseasetest_infer = VariableElimination(model)
print('\n 1. Probability of HeartDisease given evidence= restecg')
q1=HeartDiseasetest_infer.query(variables=['heartdisease'],evidence
={'restecg':1})
print(q1)

print('\n 2. Probability of HeartDisease given evidence= cp ')


q2=HeartDiseasetest_infer.query(variables=['heartdisease'],evidence
={'cp':2})
print(q2)

OUTPUT:
[Link] Build Regression models

PROGRAM: LINEAR REGRESSION MODELS


import numpy as np
import [Link] as plt

def estimate_coef(x, y):


# number of observations/points
n = [Link](x)

# mean of x and y vector


m_x = [Link](x)
m_y = [Link](y)

# calculating cross-deviation and deviation about x


SS_xy = [Link](y*x) - n*m_y*m_x
SS_xx = [Link](x*x) - n*m_x*m_x

# calculating regression coefficients


b_1 = SS_xy / SS_xx
b_0 = m_y - b_1*m_x

return (b_0, b_1)

def plot_regression_line(x, y, b):


# plotting the actual points as scatter plot
[Link](x, y, color = "m",
marker = "o", s = 30)

# predicted response vector


y_pred = b[0] + b[1]*x

# plotting the regression line


[Link](x, y_pred, color = "g")

# putting labels
[Link]('x')
[Link]('y')

# function to show plot


[Link]()

def main():
# observations / data
x = [Link]([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y = [Link]([1, 3, 2, 5, 7, 8, 8, 9, 10, 12])

# estimating coefficients
b = estimate_coef(x, y)
print("Estimated coefficients:\nb_0 = {} \
\nb_1 = {}".format(b[0], b[1]))

# plotting regression line


plot_regression_line(x, y, b)
if __name__ == "__main__":
main()

OUTPUT:
Estimated coefficients:
b_0 = 1.2363636363636363
b_1 = 1.1696969696969697

Common questions

Powered by AI

Constructing a regression model involves estimating coefficients to fit a continuous output variable and validating the fit through measures such as R-squared. In contrast, classification models like Naive Bayes focus on predicting discrete outcomes by calculating the likelihood of feature variables contributing to classes. Regression stresses modeling of variable relationships, while classification emphasizes probability estimation and prediction accuracy across classes. Both involve data preparation, but regression typically involves more complex statistical techniques and validation metrics .

The BFS algorithm handles exploring each node in a graph by using a queue to maintain the nodes scheduled to be explored. It starts from a selected root node, adds it to the visited list, and explores each node at the present depth level before moving onto nodes at the next depth level in an iterative manner. A key characteristic of its traversal pattern is that it explores all neighbors of a node before moving to a node on the next level, thereby ensuring a breadth-wise approach to traversal .

In complex Bayesian Networks, inference is typically performed using algorithms such as Variable Elimination, Belief Propagation, or Approximate Inference methods. These strategies look to efficiently compute marginal probabilities despite the potential exponential complexity in the number of network nodes. Although effective for many networks, these methods can become infeasible in terms of computational resources or time when dealing with very large networks or networks with high connectivity, prompting the need for approximations or simulations like Monte Carlo methods .

The A* algorithm finds the shortest path by combining the lowest cost from the starting node and a heuristic function that estimates the cost to the goal. It uses open and closed sets to explore nodes with the lowest estimated total cost. The heuristic function guides the search towards the goal by estimating the least cost remaining to reach the goal, enabling efficient pathfinding by reducing the number of nodes explored compared to other search methods. The choice of the heuristic can significantly affect the performance of the algorithm .

The primary steps involved in preparing a dataset for a Naive Bayes classification include encoding categorical class labels to numeric values, splitting the dataset into training and testing subsets, and calculating the mean and standard deviation for numerical data attributes. Numerical attributes are handled by treating them as Gaussian-distributed, allowing calculation of probabilities using the Gaussian Probability Density Function, which enables the classifier to handle continuous data .

The Naive Bayes model calculates the probability of a class given the attributes of a test instance by multiplying the likelihood of each attribute, assumed independent within each class, by the prior probability of the class. This product provides an unnormalized likelihood score for each class. The model then predicts the class with the highest score as this indicates the most probable class for the given attributes .

The DFS algorithm differs from BFS by using a stack or recursion instead of a queue, resulting in a depth-wise exploration. Unlike BFS, which explores all neighbors of a node first, DFS goes deep along one branch until a dead end is reached, then backtracks. This leads to a traversal that finishes exploring one deep path before moving to another branch, often resulting in different traversal orders .

The mathematical foundation underlying linear regression is finding a linear relationship between a dependent variable and one or more independent variables using the method of least squares. The goal is to estimate coefficients that minimize the sum of squared residuals between observed and predicted values. The regression coefficients are estimated by calculating the slope and intercept through the cross-deviation of X and Y and variance of X, enabling the best-fit line to be drawn .

The implications of using different heuristic functions in the A* algorithm are significant on both search efficiency and accuracy. A well-designed heuristic can greatly improve efficiency by reducing the number of explored nodes, as it guides the search in more promising directions. However, if the heuristic overestimates or is poorly designed, it can lead to inaccurate results or inefficient exploration paths, potentially impacting the optimality of the found solution. Therefore, heuristic design should balance between accuracy and computational complexity .

Constructing a Bayesian Network involves defining the graphical structure with nodes representing variables and directed edges denoting dependencies. Each node has a Conditional Probability Table (CPT) that quantifies the effect of the parent nodes on the node, representing the conditional probabilities of each state of the node given its parents. During inference, these CPTs are used to calculate the likelihood of different hypotheses or query variables, thus facilitating estimation of probabilities under given evidence .

You might also like