Artificial Intelligence Laboratory
Artificial Intelligence Laboratory
P Engineering College
Thiruvannamalai
AD3311 - ARTIFICIAL
INTELLIGENCE LABORATORY
LAB MANUAL
B.TECH. ARTIFICIAL
INTELLIGENCE AND DATA
SCIENCE
SYLLABUS
LIST OF EXPERIMENTS:
Staff
Ex.No Date Name Of The Experiment Page Mark Sign
1A 8 Puzzle Problem 01
1B 8 Queen Problem 08
1C Crypt-Arithmetic Problem 10
2 A* Algorithm 16
3 Min-Max Algorithm 19
6 Forward Chaining 29
9
Mini-Project Dog Vs Cat 41
Classification
01
Algorithm
START
1. In order to maintain the list of live nodes, algorithm LCSearch employs the
functions Least() and Add().
2. Least() identifies a live node with the least c(y), removes it from the list, and
returns it.
3. Add(y) adds y to the list of live nodes.
4. Add(y) implements the list of live nodes as a min-heap.
END
Program
# Constructor to initialize a
# Priority Queue
def init (self):
self.heap = []
# Node structure
class node:
count = 0
for i in range(n):
for j in range(n):
if ((mat[i][j]) and
(mat[i][j] != final[i][j])):
count += 1
return count
for i in range(n):
for j in range(n):
print("%d " % (mat[i][j]), end = " ")
print()
if root == None:
return
05
printPath(root.parent)
printMatrix(root.mat)
print()
if isSafe(new_tile_pos[0], new_tile_pos[1]):
# Driver Code
# Initial configuration
# Value 0 is used for empty space
initial = [ [ 1, 2, 3 ],
[ 5, 6, 0 ],
[ 7, 8, 4 ] ]
[ 0, 7, 4 ] ]
Output
1 2 3
5 6 0
7 8 4
1 2 3
5 0 6
7 8 4
1 2 3
5 8 6
7 0 4
1 2 3
5 8 6
0 4 7
Algorithm
START
1. begin from the leftmost column
2. if all the queens are placed,
return true/ print configuration
3. check for all rows in the current column
a) if queen placed safely, mark row and column; and
recursively check if we approach in the current
configuration, do we obtain a solution or not
b) if placing yields a solution, return true
c) if placing does not yield a solution, unmark and
try other rows
4. if all rows tried and solution not obtained, return
false and backtrack
END
Program
for l in range(0,N):
if (k+l==i+j) or (k-l==i-j):
if board[k][l]==1:
return True
return False
def N_queens(n):
if n==0:
return True
for i in range(0,N):
for j in range(0,N):
if (not(attack(i,j))) and (board[i][j]!=1):
board[i][j] = 1
if N_queens(n-1)==True:
return True
board[i][j] = 0
return False
N_queens(N)
for i in board:
print (i)
Output
Enter the number of queens
8
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 1, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0]
Procedure
The Crypt-Arithmetic problem in Artificial Intelligence is a type of
encryption problem in which the written message in an alphabetical form which is easily
readable and understandable is converted into a numeric form which is neither easily
readable nor understandable. In simpler words, the crypt-arithmetic problem deals with
the converting of the message from the readable plain text to the non-readable ciphertext.
The constraints which this problem follows during the conversion is as follows:
SEND
MORE
MONEY
These alphabets then are replaced by numbers such that all the constraints are satisfied.
So initially we have all blank spaces.
These alphabets then are replaced by numbers such that all the constraints are satisfied.
So initially we have all blank spaces.
We first look for the MSB in the last word which is 'M' in the word 'MONEY' here. It is
the letter which is generated by carrying. So, carry generated can be only one. SO, we
have M=1.
Now, we have S+M=O in the second column from the left side. Here M=1. Therefore,
we have, S+1=O. So, we need a number for S such that it generates a carry when added
with 1. And such a number is 9. Therefore, we have S=9 and O=0.
11
Now, in the next column from the same side we have E+O=N. Here we have O=0.
Which means E+0=N which is not possible. This means a carry was generated by the
lower place digits. So we have:
1+E=N ---------- (i)
Next alphabets that we have are N+R=E-------- (ii)
So, for satisfying both equations (i) and (ii), we get E=5 and N=6.
Now, R should be 9, but 9 is already assigned to S, So, R=8 and we have 1 as a carry
which is generated from the lower place digits.
Now, we have D+5=Y and this should generate a carry. Therefore, D should be greater
than 4. As 5, 6, 8 and 9 are already assigned, we have D=7 and therefore Y=2.
Therefore, the solution to the given Crypt-Arithmetic problem is:
S=9; E=5; N=6; D=7; M=1; O=0; R=8; Y=2
Which can be shown in layout form as:
9567
1085
10652
Program
# Function to check if the
# assignment of digits to
# characters is possible
def isSolvable(words, result):
# Stores the value
# assigned to alphabets
mp = [-1]*(26)
# Stores if a number
# is assigned to any
# character or not
used = [0]*(10)
# in every string
Hash = [0]*(26)
# Stores if a character
# is at index 0 of any
# string
CharAtfront = [0]*(26)
# Update Hash[ch-'A]
Hash[ord(ch) - ord('A')] += pow(10, len(words[word]) - i - 1)
# If mp[ch-'A'] is -1
if mp[ord(ch) - ord('A')] == -1:
mp[ord(ch) - ord('A')] = 0
uniq += str(ch)
# If i is 0 and word
# length is greater
# than 1
if i == 0 and len(words[word]) > 1:
13
CharAtfront[ord(ch) - ord('A')] = 1
# If mp[ch-'A] is -1
if mp[ord(ch) - ord('A')] == -1:
mp[ord(ch) - ord('A')] = 0
uniq += str(ch)
# If i is 0 and length of
# result is greater than 1
if i == 0 and len(result) > 1:
CharAtfront[ord(ch) - ord('A')] = 1
mp = [-1]*(26)
# of ch
val = mp[ord(words[i]) - ord('A')]
# If val is -1
if val != -1:
# Recursion
return solve(words, i + 1, S + val * Hash[ord(ch) - ord('A')], mp, used, Hash,
CharAtfront)
# If used[l] is true
if used[l] == 1:
continue
# Assign l to ch
mp[ord(ch) - ord('A')] = l
# Marked l as used
used[l] = 1
# Backtrack
mp[ord(ch) - ord('A')] = -1
15
# Unset used[l]
used[l] = 0
# Function Call
if isSolvable(arr, S):
print("Yes")
else:
print("No")
Output
Yes
D=1 E=5 M=0 N=3 O=8 R=2 S=7 Y=6
Ex: 2 A* ALGORITHM
Algorithm
1. Add the starting square (or node) to the open list.
2. Repeat the following:
A) Look for the lowest F cost square on the open list. We refer to this as the current
square.
B). Switch it to the closed list.
C) For each of the 8 squares adjacent to this current square …
• If it is not walk able or if it is on the closed list, ignore it. Otherwise do the
following.
• If it isn’t on the open list, add it to the open list. Make the current square the
parent of this square. Record the F, G, and H costs of the square.
• If it is on the open list already, check to see if this path to that square is
better, using G cost as the measure. A lower G cost means that this is a
better path. If so, change the parent of the square to the current square, and
recalculate the G and F scores of the square. If you are keeping your open
list sorted by F score, you may need to resort the list to account for the
change.
D) Stop when you:
• Add the target square to the closed list, in which case the path has been
found, or
• Fail to find the target square, and the open list is empty. In this case, there is
no path.
3. Save the path. Working backwards from the target square, go from each square to
its parent square until you reach the starting square. That is your path.
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
17
Output
Path found: ['A', 'F', 'G', 'I', 'J']
Description
Suppose we have a binary tree representing a game state of a two player game. Every
internal node is filled with 0 and the leaves values represent the end score. Player 1
wants to maximize the end score while player 2 wants to minimize the end score.
Player 1 will always make moves on nodes at even levels and player 2 will always
make moves on odd levels. We have to fill in the binary tree with the resulting scores
assuming both of players play optimally. So, if the input is like
Algorithm
• Define a function helper() . This will take root, h, currentHeight
• if root is empty, then
o return
• helper(left of root, h, currentHeight + 1)
• helper(right of root, h, currentHeight + 1)
• if currentHeight < h, then
o if currentHeight is even, then
▪ if left of root and right of root are not null, then
▪ value of root := maximum of value of left of root, value of
right of root
▪ otherwise when left of root is not null, then
▪ value of root := value of left of root
▪ otherwise when right of root is not null, then
▪ value of root := value of right of root
o otherwise,
▪ if left of root and right of root are not null, then
20
Program
class TreeNode:
def init (self, data, left = None, right = None):
self.val = data
self.left = left
self.right = right
class Solution:
def helper(self, root, h, currentHeight):
if not root:
return
self.helper(root.left, h, currentHeight + 1)
self.helper(root.right, h, currentHeight + 1)
if currentHeight < h:
if currentHeight % 2 == 0:
if root.left and root.right:
root.val = max(root.left.val, root.right.val)
elif root.left:
root.val = root.left.val
elif root.right:
root.val = root.right.val
else:
if root.left and root.right:
21
Input
root = TreeNode(0)
root.left = TreeNode(3)
root.right = TreeNode(0)
root.right.left = TreeNode(0)
root.right.right = TreeNode(0)
root.right.left.left = TreeNode(-3)
root.right.right.right = TreeNode(4)
22
Output
3, 3, -3, -3, -3, 4, 4,
Description:
Constraint programming is an example of the declarative programming paradigm, as
opposed to the usual imperative paradigm that we use most of the time. Most
programming paradigms can be classified as a member of either the imperative or
declarative paradigm group.
Declarative programming does the opposite - we don't write the steps on how to
achieve a goal, we describe the goal, and the computer gives us a solution. A common
example you should be familiar with is SQL. Do you tell the computer how to give
you the results you need? No, you describe what you need - you need the values from
some column, from some table, where some conditions are met.
Procedure
Installing the python-constraint Module
In this procedure we'll be working with a module called python-constraint (Note:
there's a module called "constraint" for Python, that is not what we want), which aims
to bring the constraint programming idea to Python.
Example A
Find all (x,y) where x ∈ {1,2,3} and 0 <= y < 10, and x + y >= 5
If we look at this sentence, we can see several conditions (let's call them constraints)
that x and y have to meet.
For example, x is "constrained" to the values 1,2,3, y has to be less than 10 and their
sum has to be greater than or equal to 5. This is done in a few lines of code and in a
few minutes using constraint programming.
Looking at the problem above you probably thought "So what? I can do this with 2 for
loops and half a cup of coffee in Python in less than 10 minutes".
You're absolutely right, though through this example we can get an idea of what
constraint programming looks like:
Program
import constraint
problem = constraint.Problem()
solutions = problem.getSolutions()
print("Number of solutions found: {}\n".format(len(solutions)))
Output
Number of solutions found: 7
T = 7, W = 6, O = 5, F = 1, U = 3, R = 0
T = 7, W = 3, O = 4, F = 1, U = 6, R = 8
T = 8, W = 6, O = 7, F = 1, U = 3, R = 4
T = 8, W = 4, O = 6, F = 1, U = 9, R = 2
T = 8, W = 3, O = 6, F = 1, U = 7, R = 2
T = 9, W = 2, O = 8, F = 1, U = 5, R = 6
T = 9, W = 3, O = 8, F = 1, U = 7, R = 6
Problem Statement
Doctor Black has just been found dead in his mansion yesterday. Yesterday, there were
only Three People in Doctor Black’s mansion.
They are the prime suspects:
1. Col. Mustard
2. Prof. Plum
3. Ms. Scarlet
Police found Three Weapons in the mansion:
1. Knife
2. Revolver
3. Wrench
The murder has happened in one of the Three Rooms of the mansion:
1. Ballroom
2. Kitchen
3. Library
We have to find who the murderer of Dr. Black is. We can start creating the
knowledge base of our game engine by adding the above information. We will make
our game engine knowledgeable by implementing propositional logic. We will also
receive further clues during the investigation. That will be also added to the knowledge
base.
27
Program
import termcolor
# we have imported the logic file
from logic import *
#Now we are symboling all the characters,rooms,weapons
mustard=Symbol("col.mustard")
plum=Symbol("ProfPlum")
scarlet=Symbol("MsScarlet")
charecters=[mustard,plum,scarlet]
ballroom=Symbol("ballroom")
kitchen=Symbol("kitchen")
library=Symbol("library")
rooms=[ballroom,kitchen,library]
revolber=Symbol("revolber")
knife=Symbol("knife")
wrench=Symbol("wrench")
wreapons=[revolber,knife,wrench]
def check_knowledge(knowledge_base):
for symbol in symbols:
if model_check(knowledge_base,symbol):
termcolor.cprint(f"{symbol}:YES","green")
elif not model_check(knowledge_base,Not(symbol)):
print(f"{symbol}:Maybe")
# Createing knowledge base
knowledge_base=And(
28
Or(mustard,plum,scarlet),
Or(ballroom,kitchen,library),
Or(knife,revolber,wrench)
knowledge_base.add(Or(
Not(scarlet),Not(library),Not(wrench)
))
knowledge_base.add(Not(plum))
knowledge_base.add(Not(ballroom))
knowledge_base.add(Not(revolber))
check_knowledge(knowledge_base)
Output
MsScalket : Yes
Library : Yes
Knife : Yes
Procedure
Forward Chaining is one of the two methodologies using an inference engine, the
other one being backward Chaining. It starts with a base state and uses the inference
rules and available knowledge in the forward direction till it reaches the end state. The
process iterates till the final state is reached. Now Let’s understand Forward chaining
with FOL with an example:We will list down the facts initially and then convert facts
to First-order Logic (FOL) using inference laws until we reach the goal state.
Some Fact :
• It is crime for Americans to sell the weapon to the enemy of America
• Country Nono is an enemy of America
• Nono has some Missiles
• All missiles were sold to Nono by Colonel
• Colonel is American
• Missile is a weapon
Goal :
• Colonel is criminal
Steps to be followed :
Fact conversion to FOL:
Step1 : It is crime for Americans to sell the weapon to the enemy of America
FOL :American(x)Weapon(y)Enemy(z,America)Sell(x,y,z)Criminal(x)
Step2 : Country Nono is enemy of America
FOL : Enemy(Nono, America)
Step3 : Nono has some Missile
FOL : Owns(Nono ,x)
Missile(x)
Step4 : All missiles were sold to Nono by Colonel
FOL : Missile(x) ^ Owns(Nono,x) → Sell(Colonel,x,Nono)
Step5 : Colonel is American
30
FOL : American(Colonel)
Step6 : Missile is weapon
FOL : Missile(x) → Weapon (x)
Proof:
Iteration 1:
• Start with the knowledge base/known facts : The facts that are not deduced
from any other [ present in LHS of the statements ]
Iteration 2:
• Rule(1) has all the LHS conditions satisfied as we can see in the first iteration.
So all the four FOL in LHS are available, now we can add Criminal(x) from
RHS in our next state
Output
We reached the goal state to deduce that: Colonel is a criminal
Algorithm
Naive Bayes is among one of the very simple and powerful algorithms for
classification based on Bayes Theorem with an assumption of independence among
the predictors. The Naive Bayes classifier assumes that the presence of a feature in a
class is not related to any other feature. Naive Bayes is a classification algorithm for
binary and multi-class classification problems.
Bayes Theorem
Based on prior knowledge of conditions that may be related to an event, Bayes
theorem describes the probability of the event
• conditional probability can be found this way
• Assume we have a Hypothesis(H) and evidence(E),
According to Bayes theorem, the relationship between the probability of
Hypothesis before getting the evidence represented as P(H) and the probability
of the hypothesis after getting the evidence represented as P(H|E) is:
P(H|E) = P(E|H)*P(H)/P(E)
• Prior probability = P(H) is the probability before getting the evidence
Posterior probability = P(H|E) is the probability after getting evidence
• In general,
P(class|data) = (P(data|class) * P(class)) / P(data)
Assume we have to find the probability of the randomly picked card to be king given
that it is a face card. There are 4 Kings in a Deck of Cards which implies that P(King)
=4/52 as all the Kings are face Cards so P(Face|King) = 1
there are 3 Face Cards in a Suit of 13 cards and there are 4 Suits in total so P(Face) =
12/52 Therefore,
Program
# Importing library
import math
import random
import csv
# the categorical class names are changed to numberic data
33
# Calculating Mean
34
def mean(numbers):
return sum(numbers) / float(len(numbers))
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
for i in range(len(classSummaries)):
mean, std_dev = classSummaries[i]
x = test[i]
probabilities[classValue] *= calculateGaussianProbability(x, mean, std_dev)
return probabilities
# 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
36
# 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)
Input
Dataset Download
https://gist.github.com/ktisha/c21e73a1bd1700294ef790c56c8aec1f
37
Output
Aim: To implement the Bayesian networks and perform inferences using python
Procedure
A Bayesian network is a directed acyclic graph in which each edge corresponds to a
conditional dependency, and each node corresponds to a unique random variable.
Bayesian network consists of two major parts: a directed acyclic graph and a set of
conditional probability distributions
• The directed acyclic graph is a set of random variables represented by nodes.
• The conditional probability distribution of a node (random variable) is defined
for every possible outcome of the preceding causal node(s).
For illustration, consider the following example. Suppose we attempt to turn on our
computer, but the computer does not start (observation/evidence). We would like to
know which of the possible causes of computer failure is more likely. In this
simplified illustration, we assume only two possible causes of this misfortune:
electricity failure and computer malfunction.
The corresponding directed acyclic graph is depicted in below figure.
The goal is to calculate the posterior conditional probability distribution of each of the
possible unobserved causes given the observed evidence, i.e. P [Cause | Evidence].
Program
from pgmpy.models import BayesianNetwork
from pgmpy.factors.discrete import TabularCPD
import networkx as nx
39
model.check_model()
infer = VariableElimination(model)
posterior_p = infer.query(['Host'], evidence={'Guest': 2, 'Price': 2})
print(posterior_p)
nx.draw(model, with_labels=True)
plt.savefig('model.png')
plt.close()
Input
Datset Download
https://drive.google.com/file/d/17vwRLAY8uR-6vWusM5prn08it-BEGp-f/view
40
Output
Result : Thus the Bayesian networks and perform inferences using python is
implemented.
41
Download
https://www.kaggle.com/c/dogs-vs-cats/data
Image_Channels=3
model.add(Dense(512,activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(2,activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',metrics=['accuracy'])
5. Analyzing model:
. model.summary()
test_filenames = os.listdir("./dogs-vs-cats/test1")
test_df = pd.DataFrame({
'filename': test_filenames
})
nb_samples = test_df.shape[0]
predict = model.predict_generator(test_generator,
steps=np.ceil(nb_samples/batch_size))
8. Convert labels to categories:
test_df['category'] = test_df['category'].replace(label_map)
test_df['category'] = test_df['category'].replace({ 'dog': 1, 'cat': 0 })
9. Visualize the prediction results:
sample_test = test_df.head(18)
sample_test.head()
plt.figure(figsize=(12, 24))
for index, row in sample_test.iterrows():
filename = row['filename']
category = row['category']
img = load_img("./dogs-vs-cats/test1/"+filename, target_size=Image_Size)
plt.subplot(6, 3, index+1)
plt.imshow(img)
plt.xlabel(filename + '(' + "{}".format(category) + ')' )
plt.tight_layout()
plt.show()
Output