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

AD3311 AI LAB MANUAL (1)

Uploaded by

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

AD3311 AI LAB MANUAL (1)

Uploaded by

stainexxz
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

AD3311-ARTIFICIAL INTELLIGENCE

LABORATORY

Name of the Student :……………………………….

Register Number :……………………………….

Year/ Semester/ Section :………………………………

Branch :……………………………….
AD3311 ARTIFICIAL INTELLIGENCE LABORATORY

OBJECTIVES:

o To design and implement search strategies


o To implement game playing techniques
o To implement CSP techniques
o To develop systems with logical reasoning
o To develop systems with probabilistic reasoning

LIST OF EXPERIMENTS:
1. Implement basic search strategies – 8-Puzzle, 8 - Queens’s problem, Cryptarithmetic.
2. Implement A* and memory bounded A* algorithms
3. Implement Minimax algorithm for game playing (Alpha-Beta pruning)
4. Solve constraint satisfaction problems
5. Implement propositional model checking algorithms
6. Implement forward chaining, backward chaining, and resolution strategies
7. Build naïve Bayes models
8. Implement Bayesian networks and perform inferences
9. Mini-Project

TOTAL: 45 PERIODS

OUTCOMES:
At the end of this course, the students will be able to:

CO1: Design and implement search strategies


CO2: Implement game playing and CSP techniques
CO3: Develop logical reasoning systems
CO4: Develop probabilistic reasoning systems
.

SOFTWARE:
 PYTHON or Java Software
Exp No 1 Implement basic search strategies – 8-Puzzle problem and 8-Queen
DATE: problem.

a) Implement basic search strategies – 8-Puzzle problem:

import copy

# Importing the heap methods from the python


# library for the Priority Queue
from heapq import heappush, heappop

# This particular var can be changed to transform


# the program from 8 puzzle(n=3) into 15
# puzzle(n=4) and so on ...
n=3

# bottom, left, top, right


rows = [ 1, 0, -1, 0 ]
cols = [ 0, -1, 0, 1 ]

# creating a class for the Priority Queue


class priorityQueue:

# Constructor for initializing a


# Priority Queue
def __init__(self):
self.heap = []

# Inserting a new key 'key'


def push(self, key):
heappush(self.heap, key)

# funct to remove the element that is minimum,


# from the Priority Queue
def pop(self):
return heappop(self.heap)

# funct to check if the Queue is empty or not


def empty(self):
if not self.heap:
return True
else:
return False
# structure of the node
class nodes:

def __init__(self, parent, mats, empty_tile_posi,


costs, levels):

# This will store the parent node to the


# current node And helps in tracing the
# path when the solution is visible
self.parent = parent

# Useful for Storing the matrix


self.mats = mats

# useful for Storing the position where the


# empty space tile is already existing in the matrix
self.empty_tile_posi = empty_tile_posi

# Store no. of misplaced tiles


self.costs = costs

# Store no. of moves so far


self.levels = levels

# This func is used in order to form the


# priority queue based on
# the costs var of objects
def __lt__(self, nxt):
return self.costs < nxt.costs

# method to calc. the no. of


# misplaced tiles, that is the no. of non-blank
# tiles not in their final posi
def calculateCosts(mats, final) -> int:

count = 0
for i in range(n):
for j in range(n):
if ((mats[i][j]) and
(mats[i][j] != final[i][j])):
count += 1

return count

def newNodes(mats, empty_tile_posi, new_empty_tile_posi,


levels, parent, final) -> nodes:
# Copying data from the parent matrixes to the present matrixes
new_mats = copy.deepcopy(mats)

# Moving the tile by 1 position


x1 = empty_tile_posi[0]
y1 = empty_tile_posi[1]
x2 = new_empty_tile_posi[0]
y2 = new_empty_tile_posi[1]
new_mats[x1][y1], new_mats[x2][y2] = new_mats[x2][y2], new_mats[x1][y1]

# Setting the no. of misplaced tiles


costs = calculateCosts(new_mats, final)

new_nodes = nodes(parent, new_mats, new_empty_tile_posi,


costs, levels)
return new_nodes

# func to print the N by N matrix


def printMatsrix(mats):

for i in range(n):
for j in range(n):
print("%d " % (mats[i][j]), end = " ")

print()

# func to know if (x, y) is a valid or invalid


# matrix coordinates
def isSafe(x, y):

return x >= 0 and x < n and y >= 0 and y < n

# Printing the path from the root node to the final node
def printPath(root):

if root == None:
return

printPath(root.parent)
printMatsrix(root.mats)
print()

# method for solving N*N - 1 puzzle algo


# by utilizing the Branch and Bound technique. empty_tile_posi is
# the blank tile position initially.
def solve(initial, empty_tile_posi, final):

# Creating a priority queue for storing the live


# nodes of the search tree
pq = priorityQueue()

# Creating the root node


costs = calculateCosts(initial, final)
root = nodes(None, initial,
empty_tile_posi, costs, 0)

# Adding root to the list of live nodes


pq.push(root)

# Discovering a live node with min. costs,


# and adding its children to the list of live
# nodes and finally deleting it from
# the list.
while not pq.empty():

# Finding a live node with min. estimatsed


# costs and deleting it form the list of the
# live nodes
minimum = pq.pop()

# If the min. is ans node


if minimum.costs == 0:

# Printing the path from the root to


# destination;
printPath(minimum)
return

# Generating all feasible children


for i in range(n):
new_tile_posi = [
minimum.empty_tile_posi[0] + rows[i],
minimum.empty_tile_posi[1] + cols[i], ]

if isSafe(new_tile_posi[0], new_tile_posi[1]):

# Creating a child node


child = newNodes(minimum.mats,
minimum.empty_tile_posi,
new_tile_posi,
minimum.levels + 1,
minimum, final,)

# Adding the child to the list of live nodes


pq.push(child)

# Main Code

# Initial configuration
# Value 0 is taken here as an empty space
initial = [ [ 1, 2, 3 ],
[ 5, 6, 0 ],
[ 7, 8, 4 ] ]

# Final configuration that can be solved


# Value 0 is taken as an empty space
final = [ [ 1, 2, 3 ],
[ 5, 8, 6 ],
[ 0, 7, 4 ] ]

# Blank tile coordinates in the


# initial configuration
empty_tile_posi = [ 1, 2 ]

# Method call for solving the puzzle


solve(initial, empty_tile_posi, final)

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 7 4

b) Implement basic search strategies – 8-Queens problem

global N
N=4

def printSolution(board):
for i in range(N):
for j in range(N):
print (board[i][j],end=' ')
print()

# A utility function to check if a queen can


# be placed on board[row][col]. Note that this
# function is called when "col" queens are
# already placed in columns from 0 to col -1.
# So we need to check only left side for
# attacking queens
def isSafe(board, row, col):

# Check this row on left side


for i in range(col):
if board[row][i] == 1:
return False

# Check upper diagonal on left side


for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False

# Check lower diagonal on left side


for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False

return True

def solveNQUtil(board, col):


# base case: If all queens are placed
# then return true
if col >= N:
return True

# Consider this column and try placing


# this queen in all rows one by one
for i in range(N):

if isSafe(board, i, col):
# Place this queen in board[i][col]
board[i][col] = 1

# recur to place rest of the queens


if solveNQUtil(board, col + 1) == True:
return True

# If placing queen in board[i][col


# doesn't lead to a solution, then
# queen from board[i][col]
board[i][col] = 0

# if the queen can not be placed in any row in


# this column col then return false
return False

# This function solves the N Queen problem using


# Backtracking. It mainly uses solveNQUtil() to
# solve the problem. It returns false if queens
# cannot be placed, otherwise return true and
# placement of queens in the form of 1s.
# note that there may be more than one
# solutions, this function prints one of the
# feasible solutions.
def solveNQ():
board = [ [0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]

if solveNQUtil(board, 0) == False:
print ("Solution does not exist")
return False

printSolution(board)
return True

# driver program to test above function


solveNQ()

output:
C) Crypt arithmetic solver
'''Crypt arithmetic puzzles are arithmetic problems made of letters instead of Numbers. The goal is to
replace each letter with a single, unique digit in order to make the arithmetic work out correctly.

Example: S E N D + M O R E = M O N E Y S E N D + M O R E
----------
MONEY
----------
Vales which satisfies this constraints
S = 9, E = 5, N = 6, D = 7, M = 1, O = 0, R = 8, Y = 2
'''
def find_value(word, assigned):
num = 0
for char in word:
num = num * 10
num += assigned[char]
return num
def is_valid_assignment(word1, word2, result, assigned):
# First letter of any word cannot be zero.
if assigned[word1[0]] == 0 or assigned[word2[0]] == 0 or assigned[
result[0]] == 0:
return False
return True
def _solve(word1, word2, result, letters, assigned, solutions):
if not letters:
if is_valid_assignment(word1, word2, result, assigned):
num1 = find_value(word1, assigned)
num2 = find_value(word2, assigned)
num_result = find_value(result, assigned)
if num1 + num2 == num_result:
solutions.append((f'{num1} + {num2} = {num_result}',
assigned.copy()))
return
for num in range(10):
if num not in assigned.values():
cur_letter = letters.pop()
assigned[cur_letter] = num
_solve(word1, word2, result, letters, assigned, solutions)
assigned.pop(cur_letter)
letters.append(cur_letter)
def solve(word1, word2, result):
letters = sorted(set(word1) | set(word2) | set(result))
if len(result) > max(len(word1), len(word2)) + 1 or len(letters) > 10:
print('0 Solutions!')
return
solutions = []
_solve(word1, word2, result, letters, {}, solutions)
if solutions:
print('\nSolutions:')
for soln in solutions:
print(f'{soln[0]}\t{soln[1]}')
if __name__ == '__main__':
print('CRYPTARITHMETIC PUZZLE SOLVER')
print('WORD1 + WORD2 = RESULT')
word1 = input('Enter WORD1: ').upper()
word2 = input('Enter WORD2: ').upper()
result = input('Enter RESULT: ').upper()
if not word1.isalpha() or not word2.isalpha() or not result.isalpha():
raise TypeError('Inputs should ony consists of alphabets.')
solve(word1, word2, result)
CRYPTARITHMETIC PUZZLE SOLVER
WORD1 + WORD2 = RESULT
Enter WORD1: SEND
Enter WORD2: MORE
Enter RESULT: MONEY
Solutions:
9567 + 1085 = 10652 {'Y': 2, 'S': 9, 'R': 8, 'O': 0, 'N': 6, 'M': 1, 'E':
5, 'D': 7}
Exp No 2 IMPLEMENT A* SEARCH ALGORITHM
DATE:

AIM:
To write a Java python program to Implement A* search algorithm.

ALGORITHM:
1. Initialize the open list
2. Initialize the closed list put the starting node on the open list (you can leave its f at zero)
3. while the open list is not empty
a) find the node with the least f on the open list, call it &quot;q&quot;
b) pop q off the open list
c) generate q&#39;s 8 successors and set their parents to q
d) for each successor
i) if successor is the goal, stop search
ii) else, compute both g and h for successor
successor.g = q.g + distance between successor and q
successor.h = distance from goal to
successor (This can be done using many ways, we will discuss three heuristics-Manhattan,
Diagonal and Euclidean Heuristics)
successor.f = successor.g + successor.h
iii) if a node with the same position as successor is in the OPEN list which has a lower f than
successor, skip this successor
iv) if a node with the same position as successor is in the CLOSED list which has
a lower f than successor, skip this successor otherwise, add the node to the open list end (for
loop)
e) push q on the closed list end (while loop)
PROGRAM:
public class Node implements Comparable&lt;Node&gt; {
// Id for readability of result purposes
private static int idCounter = 0;
public int id;
// Parent in the path
public Node parent = null;
public List&lt;Edge&gt; neighbors;
// Evaluation functions
public double f = Double.MAX_VALUE;
public double g = Double.MAX_VALUE;
// Hardcoded heuristic
public double h;
Node(double h){
this.h = h;
this.id = idCounter++;
this.neighbors = new ArrayList&lt;&gt;();
}
@Override
public int compareTo(Node n) {
return Double.compare(this.f, n.f);
}
public static class Edge {
Edge(int weight, Node node){
this.weight = weight;
this.node = node;
}
public int weight;
public Node node;
}
public void addBranch(int weight, Node node){
Edge newEdge = new Edge(weight, node);
neighbors.add(newEdge);
}
public double calculateHeuristic(Node target){
return this.h;
}
}
And here&#39;s the algorithm itself:
public static Node aStar(Node start, Node target){

PriorityQueue&lt;Node&gt; closedList = new PriorityQueue&lt;&gt;();


PriorityQueue&lt;Node&gt; openList = new PriorityQueue&lt;&gt;();
start.f = start.g + start.calculateHeuristic(target);
openList.add(start);
while(!openList.isEmpty()){
Node n = openList.peek();
if(n == target){
return n;
}
for(Node.Edge edge : n.neighbors){
Node m = edge.node;
double totalWeight = n.g + edge.weight;
if(!openList.contains(m) &amp;&amp; !closedList.contains(m)){
m.parent = n;
m.g = totalWeight;
m.f = m.g + m.calculateHeuristic(target);
openList.add(m);
} else {
if(totalWeight &lt; m.g){
m.parent = n;
m.g = totalWeight;
m.f = m.g + m.calculateHeuristic(target);
if(closedList.contains(m)){
closedList.remove(m);
openList.add(m);
}
}
}
}
openList.remove(n);
closedList.add(n);
}
return null;
}
public static void printPath(Node target){
Node n = target;
if(n==null)
return;
List&lt;Integer&gt; ids = new ArrayList&lt;&gt;();
while(n.parent != null){
ids.add(n.id);
n = n.parent;
}
ids.add(n.id);
Collections.reverse(ids);

for(int id : ids){
System.out.print(id + &quot; &quot;);
}
System.out.println(&quot;&quot;);
}
And now, let&#39;s construct a graph and call this method:
public static void main(String[] args) {
Node head = new Node(3);
head.g = 0;
Node n1 = new Node(2);
Node n2 = new Node(2);
Node n3 = new Node(2);
head.addBranch(1, n1);
head.addBranch(5, n2);
head.addBranch(2, n3);
n3.addBranch(1, n2);
Node n4 = new Node(1);
Node n5 = new Node(1);
Node target = new Node(0);
n1.addBranch(7, n4);
n2.addBranch(4, n5);
n3.addBranch(6, n4);
n4.addBranch(3, target);
n5.addBranch(1, n4);
n5.addBranch(3, target);
Node res = aStar(head, target);
printPath(res);
}
When we run this, we&#39;ll get the result printed out:
0 3 2 5 6.

CO-PO MAPPING:
CO3- PO2,PO3, PO5,PO9,PO10
RESULT:
Thus, the program has been written for implementing A* search algorithm in Java.
Exp No 3
DATE: IMPLEMENT ALPHA-BETA TREESEARCH

AIM:
To write a Java program to implement alpha-beta tree search.

ALGORITHM:
The Max player will only update the value of alpha.
o The Min player will only update the value of beta.
o While backtracking the tree, the node values will be passed to upper nodes instead of
values of alpha and beta.
o We will only pass the alpha, beta values to the child nodes.
o The main condition which required for alpha-beta pruning is:
α&gt;=β
If the condition is true the successor of that node is pruned.
PROGRAM:

public Best chooseMove(boolean side,int[]board,int alpha,int beta,int depth,int maxDepth){


Best myBest = new Best();
Best reply;
int num;
if(Board.checkGameOver(board)||depth==maxDepth){
Best fakeBest = new Best();
fakeBest.setScore(returnPositionScore(board));
return fakeBest;
}
if(side){
myBest.setScore(alpha);
num = numberOfEngine;
}
else{
myBest.setScore(beta);
num = numberOfOpponent;
}
ArrayList&lt;Integer&gt; availableMoves = new
ArrayList&lt;Integer&gt;(searchAvailableMoves(board));
for(Integer move:availableMoves){
board[move.intValue()] = num;

reply = chooseMove(!side,board,alpha,beta,depth+1,maxDepth);
board[move.intValue()] = 0;
if(side&amp;&amp;reply.getScore()&gt;myBest.getScore()){
myBest.setMove(move.intValue());
myBest.setScore(reply.getScore());
alpha = reply.getScore();
}
else if(!side&amp;&amp;reply.getScore()&lt;myBest.getScore()){
myBest.setMove(move.intValue());
myBest.setScore(reply.getScore());
beta = reply.getScore();
}
if(alpha&gt;=beta){
return myBest;
}
}
return myBest;
}

CO-PO MAPPING:
CO3- PO2,PO3, PO5,PO9,PO10, PO12
RESULT:
Thus, the program has been written to implement alpha-beta treesearch in Java.
Exp No 4
SOLVE CONSTRAINT SATISFACTION PROBLEM
DATE:

AIM:
To write a Java program to implement backtracking algorithms for CSP.
ALGORITHM:
BT(Level)
If all variables assigned
PRINT Value of each Variable
RETURN or EXIT (RETURN for more solutions)
(EXIT for only one solution)
PickUnassignedVariable()
Variable[Level] := V
Assigned[V] := TRUE
for d := each member of Domain(V)
Value[V] := d
OK := TRUE
for each constraint C such that
V is a variable of C
and all other variables of C are assigned.
if C is not satisfied by the current set of assignments
OK := FALSE
if(OK)
BT(Level+1)
return

PROGRAM:
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collections;

/**
* &lt;h3&gt;The Algorithm class&lt;/h3&gt;
* &lt;p&gt;
* Given a CSP, use an algorithm in this class to solve it. It will output a result set.
* &lt;/p&gt;
* &lt;p&gt;
* The algorithm is the backtracking algorithm with MRV heuristic. There are 2
backtracking methods. All the other methods are static methods
* for dealing with specific backtracking tasks.
* &lt;/p&gt;
* @author adnan
*
*/
public class CSPAlgorithm {
private CSP csp;
/**
* Create the Algorithm object to be used to solve the CSP that is given to it
* @param csp
*/
public CSPAlgorithm(CSP csp) {
this.csp = csp;
}
private String getVariable(ArrayList&lt;String&gt; configOrder) {
int minVal, tmpVal;
String minVar = null;
//reverse the configOrder, thereby favouring the variables at the front of the list
Collections.reverse(configOrder);
minVal = Integer.MAX_VALUE; // some very large number
//Go through all the remaining variables in the order specified (that don&#39;t

have a value in config and figure out which one has the MRV)

//retrieve a variable based on a heuristic or the next &#39;unfilled&#39; one if there is

no heuristic
for (String s : configOrder) {
if(csp.config.get(s).equalsIgnoreCase(&quot;&quot;)) {
tmpVal = 0;
//need to check ALL values for each variable
for(String adj: csp.constraintsTable.get(s)) {
for(String val: csp.constraintsTable.get(s).get(adj)) {
if(consistent(val, s)) {
tmpVal++;
}

}
}

if(tmpVal &lt;= minVal) {


minVal = tmpVal;
minVar = s;
}

}
}
//Return the variable that has the least number of legal values
return minVar;
}
private SET&lt;String&gt; orderDomainValue(String variable) {
//return the SET of domain values for the variable
return csp.domainTable.get(variable);
}
private boolean complete() {
for(String s: csp.config) {
//if we find a variable in the config with no value, then csp means

that the config is NOT complete

if(csp.config.get(s).equalsIgnoreCase(&quot;&quot;))
return false;

}
//ALL variables in config have a value, so the configuration is complete
return true;
}
private boolean consistent(String value, String variable) {
//we need to get the constraint list for the variable
for(String constraints: csp.constraintsTable.get(variable)) {
//if the adjacency list member&#39;s value is equal to the variable&#39;s

selected value, then consistency fails

System.out.print(&quot;csp.config: &quot;);
for(String conf: csp.config) {
System.out.print(conf + &quot; = &quot; + csp.config.get(conf) + &quot;, &quot;);
}
System.out.println();
System.out.format(&quot;consistent: %s, %s, %s\n&quot;, constraints,
csp.config.get(constraints), csp.constraintsTable.get(variable).get(constraints).get(value));
if(csp.constraintsTable.get(variable).get(constraints).get(value) !=

null &amp;&amp;

!csp.config.get(constraints).equals(&quot;&quot;) &amp;&amp;

!(csp.constraintsTable.get(variable).get(constraints).get(value).contains(csp.config.get(con
straints)))) {

return false;
}
}
//consistency check passed according to the variable&#39;s adjacancy list
return true;
}
/**
* Backtracking with default ordering (alphabetical)
* @return
*/
ST&lt;String, String&gt; backtracking() {
ArrayList&lt;String&gt; configOrder = new ArrayList&lt;String&gt;();
for(String node: csp.G.vertices()) {
configOrder.add(node);

}
return this.backtracking(configOrder);
}
/**
* Backtracking with user-defined ordering of variables
*
* @param configOrder - the user defined ordering of variables
* @return
*/
ST&lt;String, String&gt; backtracking(ArrayList&lt;String&gt; configOrder) {
//recursion base case - check configuration completeness
if(this.complete())
return csp.config;
ST&lt;String, String&gt; result = null;
//get a variable
String v = this.getVariable(configOrder);
//get a SET of all the variable&#39;s values
SET&lt;String&gt; vu = this.orderDomainValue(v);
//loop through all the variable&#39;s values

for(String u: vu) {
//if(consistent(u, v, config, g)) {
if(this.consistent(u, v)) {
csp.config.put(v, u);
result = this.backtracking(configOrder);
if(result != null)
return result;
csp.config.put(v, &quot;&quot;);
}
}
return null;
}
}

CO-PO MAPPING:
CO3-PO1,PO2,PO3, PO4, O8,,PO11,PO12
RESULT:
Thus, the program has been written to implement backtracking algorithms
forCSP in Java.

Exp No 5
IMPLEMENT PROPOSITIONAL MODEL CHECKING (DPLL
DATE: ALGORITHM)

Program
import re
class Literal: #CLass Literal, it has attributes name and sign to denote
whether the literal is positve or negative in use
def __init__(self,name, sign = True ):
self.name = str(name)
self.sign = sign
def __neg__(self): #returns a new literal with the same name but the
opposite sign of its parent literal
return Literal(self.name, False)
def __str__(self):
return str(self.name)
def __repr__(self): #returns the string of the literal name,( or the
string with a negative sign) each time the instance of the ltieral is called
if self.sign:
return '%r' %str(self.__str__())
else:
return '%r' %str("-" + self.__str__())
def CNFconvert(KB): #This function converts the Kb from a list of sets to a
list of list for easire computing
storage = []
for i in KB:
i = list(i)
for j in i:
j = str(j)
storage.append(i)
return storage
def VariableSet(KB): #This function finds all the used literals in the KB,
and in order to assist with running the DPLL
KB = eval((CNFconvert(KB).__str__()))
storage = []
for obj in KB:
for item in obj:
if item[0] == '-' and item[1:] not in storage:
storage.append(str(item[1:]))
elif item not in storage and item[0] != '-':
storage.append(str(item))
return storage
def Negativeofx(x): #This function is for holding the negative form of the
literal, for use in the DPLL algorithm
check = re.match("-",str(x))
if(check):
return str(x[1:])
else:
return "-"+str(x)
def pickX(literals,varList): #This function picks a literal from the variable
set and works with it as a node in the tree
for x in varList:
if x not in literals:
break
return x
def splitFalseLiterals(cnf,x):
holder = []
for item in cnf:
if x in item:
item.remove(x)
holder.append(item)
return holder
def splitTrueLiteral(cnf,x):
holder = []
for item in cnf:
if x in item:
continue
else:
holder.append(item)
return holder
def unitResolution(clauses):
literalholder = {} #dictionary for holding the literalholder and their
bool
i=0
# This part of the code goes through each and every clause until the all
literals in the KB are resolved
while i < len(clauses): #for each clause
newClauses = []
clause = clauses[i]
# picks a clause to work on
if(len(clause) == 1):
literal = str(clause[0])
pattern = re.match("-",literal)
# Populates the dictionary
if(pattern):
nx = literal[1:]
literalholder[nx] = False
else:
nx = "-"+literal
literalholder[literal] = True
# Checks for all other appearances o the literal or its opposite
int he KB
for item in clauses:
if item != clauses[i]:
if(nx in item):
item.remove(nx)
newClauses.append(item)
i=0
clauses = newClauses
# no unit clause
else:
i += 1
return literalholder, clauses
def dpll(clauses,varList):#recursively performs the dpll algorithm
literals, cnf = unitResolution(clauses)
if(cnf == []):
return literals
elif([] in cnf):
return "notsatisfiable"
else:
# pick a literal which isn't set yet but has an impact on the Kb, and
then work on it recursively
while True:
x = pickX(literals,varList)
x = str(x)
nx = Negativeofx(x)
ncnf = splitTrueLiteral(cnf,x)
ncnf = splitFalseLiterals(ncnf,nx)
if ncnf == cnf:
varList.remove(x)
else:
break
# does the same dpll recursively, but follows the true path for that
variable
case1 = dpll(ncnf,varList)
if(case1 != "notsatisfiable"):
copy = case1.copy()
copy.update(literals)
copy.update({x: True})
return copy
# does the dpll recursively, but follows the false path for that
variable
case1 = dpll(ncnf,varList)
if not case1:
copy = case1.copy()
copy.update(literals)
copy.update({x: False})
return copy
else:
return "notsatisfiable"
def DPLL(KB): #Finally restructures the output to fit the required output by
the assignment description
KB=eval((CNFconvert(KB).__str__()))
varList = VariableSet(KB)
result = dpll(KB, varList)
if result == 'notsatisfiable':
False
else:
for i in varList:
if i in result and result[i] == True:
result[i] = 'true'
elif i in result and result[i] == False:
result[i] = 'false'
else:
result[i] = 'free'
return [True, result]
A = Literal('A')
B = Literal('B')
C = Literal('C')
D = Literal('D')
KB = [{A,B},{A,-C},{-A,B,D}]
print (DPLL(KB))
[True, {'B': 'true', 'A': True, 'C': 'free', 'D': 'free'}]

Exp No 6 Implement forward chaining


DATE:

Forward chaining:
global facts
global is_changed

is_changed = True
facts = [["vertebrate","duck"],["flying","duck"],["mammal","cat"]]

def assert_fact(fact):
global facts
global is_changed
if not fact in facts:
facts += [fact]
is_changed = True
while is_changed:
is_changed = False
for A1 in facts:
if A1[0] == "mammal":
assert_fact(["vertebrate",A1[1]])
if A1[0] == "vertebrate":
assert_fact(["animal",A1[1]])
if A1[0] == "vertebrate" and ["flying",A1[1]] in facts:
assert_fact(["bird",A1[1]])

print(facts)

Output:
[['vertebrate', 'duck'], ['flying', 'duck'], ['mammal', 'cat'], ['animal', 'duck'], ['bird', 'duck'],
['vertebrate', 'cat'], ['animal', 'cat']]

Exp No 7
Build native Bayes models
DATE:

1) Data Pre-processing step:

In this step, we will pre-process/prepare the data so that we can use it efficiently in our code.
It is similar as we did in data-pre-processing. The code for this is given below:
Importing the libraries
import numpy as nm
import matplotlib.pyplot as mtp
import pandas as pd

# Importing the dataset


dataset = pd.read_csv('user_data.csv')
x = dataset.iloc[:, [2, 3]].values
y = dataset.iloc[:, 4].values

# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.25, random_state = 0)
# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
x_train = sc.fit_transform(x_train)
x_test = sc.transform(x_test)
In the above code, we have loaded the dataset into our program using "dataset =
pd.read_csv('user_data.csv'). The loaded dataset is divided into training and test set, and
then we have scaled the feature variable.
Output:

2) Fitting Naive Bayes to the Training Set:

After the pre-processing step, now we will fit the Naive Bayes model to the Training set.
Below is the code for it:

# Fitting Naive Bayes to the Training set


from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(x_train, y_train)

In the above code, we have used the GaussianNB classifier to fit it to the training dataset.
We can also use other classifiers as per our requirement.

Output:

Out[6]:GaussianNB(priors=None,var_smoothing=1e-09)

3) Prediction of the test set result:

Now we will predict the test set result. For this, we will create a new predictor
variable y_pred, and will use the predict function to make the predictions.

# Predicting the Test set results


y_pred = classifier.predict(x_test)

Output:
The above output shows the result for prediction vector y_pred and real vector y_test. We
can see that some predications are different from the real values, which are the incorrect
predictions.

4) Creating Confusion Matrix:

Now we will check the accuracy of the Naive Bayes classifier using the Confusion matrix.
Below is the code for it:

# Making the Confusion Matrix


from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)

Output:
5) Visualizing the training set result:

Next we will visualize the training set result using Naïve Bayes Classifier. Below is the code
for it:

# Visualising the Training set results


from matplotlib.colors import ListedColormap
x_set, y_set = x_train, y_train
X1, X2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() -
1, stop = x_set[:, 0].max() + 1, step = 0.01),
nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01))
mtp.contourf(X1, X2, classifier.predict(nm.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),

alpha = 0.75, cmap = ListedColormap(('purple', 'green')))


mtp.xlim(X1.min(), X1.max())
mtp.ylim(X2.min(), X2.max())
for i, j in enumerate(nm.unique(y_set)):
mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1],
c = ListedColormap(('purple', 'green'))(i), label = j)
mtp.title('Naive Bayes (Training set)')
mtp.xlabel('Age')
mtp.ylabel('Estimated Salary')
mtp.legend()
mtp.show()

Output:
In the above output we can see that the Naïve Bayes classifier has segregated the data points
with the fine boundary. It is Gaussian curve as we have used GaussianNB classifier in our
code.

6) Visualizing the Test set result:

# Visualising the Test set results


from matplotlib.colors import ListedColormap
x_set, y_set = x_test, y_test
X1, X2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() -
1, stop = x_set[:, 0].max() + 1, step = 0.01),
nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01))
mtp.contourf(X1, X2, classifier.predict(nm.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),

alpha = 0.75, cmap = ListedColormap(('purple', 'green')))


mtp.xlim(X1.min(), X1.max())
mtp.ylim(X2.min(), X2.max())
for i, j in enumerate(nm.unique(y_set)):
mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1],
c = ListedColormap(('purple', 'green'))(i), label = j)
mtp.title('Naive Bayes (test set)')
mtp.xlabel('Age')
mtp.ylabel('Estimated Salary')
mtp.legend()
mtp.show()

Output:
The above output is final output for test set data. As we can see the classifier has created a
Gaussian curve to divide the "purchased" and "not purchased" variables. There are some
wrong predictions which we have calculated in Confusion matrix. But still it is pretty good
classifier.

Exp No 8
DATE: Implement Bayesian networks and perform inference

from pgmpy.models import BayesianNetwork


from pgmpy.factors.discrete import TabularCPD
import networkx as nx
import pylab as plt

# Defining Bayesian Structure


model = BayesianNetwork([('Guest', 'Host'), ('Price', 'Host')])

# Defining the CPDs:


cpd_guest = TabularCPD('Guest', 3, [[0.33], [0.33], [0.33]])
cpd_price = TabularCPD('Price', 3, [[0.33], [0.33], [0.33]])
cpd_host = TabularCPD('Host', 3, [[0, 0, 0, 0, 0.5, 1, 0, 1, 0.5],
[0.5, 0, 1, 0, 0, 0, 1, 0, 0.5],
[0.5, 1, 0, 1, 0.5, 0, 0, 0, 0]],
evidence=['Guest', 'Price'], evidence_card=[3, 3])

# Associating the CPDs with the network structure.


model.add_cpds(cpd_guest, cpd_price, cpd_host)
# Infering the posterior probability
from pgmpy.inference import VariableElimination

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

Output:

Exp No 7 IMPLEMENT BACKTRACKING ALGORITHMS FOR CSP


DATE:

AIM:
To write a Java program to implement backtracking algorithms for CSP.
ALGORITHM:
BT(Level)
If all variables assigned
PRINT Value of each Variable
RETURN or EXIT (RETURN for more solutions)
(EXIT for only one solution)
PickUnassignedVariable()
Variable[Level] := V
Assigned[V] := TRUE
for d := each member of Domain(V)
Value[V] := d
OK := TRUE
for each constraint C such that
V is a variable of C
and all other variables of C are assigned.
if C is not satisfied by the current set of assignments
OK := FALSE
if(OK)
BT(Level+1)
return

PROGRAM:
import java.util.ArrayList;

import java.util.ArrayList;
import java.util.Collections;

/**
* &lt;h3&gt;The Algorithm class&lt;/h3&gt;
* &lt;p&gt;
* Given a CSP, use an algorithm in this class to solve it. It will output a result set.
* &lt;/p&gt;
* &lt;p&gt;
* The algorithm is the backtracking algorithm with MRV heuristic. There are 2
backtracking methods. All the other methods are static methods
* for dealing with specific backtracking tasks.
* &lt;/p&gt;
* @author adnan
*
*/
public class CSPAlgorithm {
private CSP csp;
/**
* Create the Algorithm object to be used to solve the CSP that is given to it
* @param csp
*/
public CSPAlgorithm(CSP csp) {
this.csp = csp;
}
private String getVariable(ArrayList&lt;String&gt; configOrder) {
int minVal, tmpVal;
String minVar = null;
//reverse the configOrder, thereby favouring the variables at the front of the list
Collections.reverse(configOrder);
minVal = Integer.MAX_VALUE; // some very large number
//Go through all the remaining variables in the order specified (that don&#39;t

have a value in config and figure out which one has the MRV)

//retrieve a variable based on a heuristic or the next &#39;unfilled&#39; one if there is

no heuristic
for (String s : configOrder) {
if(csp.config.get(s).equalsIgnoreCase(&quot;&quot;)) {
tmpVal = 0;
//need to check ALL values for each variable
for(String adj: csp.constraintsTable.get(s)) {
for(String val: csp.constraintsTable.get(s).get(adj)) {
if(consistent(val, s)) {
tmpVal++;
}
}
}

if(tmpVal &lt;= minVal) {


minVal = tmpVal;
minVar = s;
}

}
}
//Return the variable that has the least number of legal values

return minVar;
}
private SET&lt;String&gt; orderDomainValue(String variable) {
//return the SET of domain values for the variable
return csp.domainTable.get(variable);
}
private boolean complete() {
for(String s: csp.config) {
//if we find a variable in the config with no value, then csp means

that the config is NOT complete

if(csp.config.get(s).equalsIgnoreCase(&quot;&quot;))
return false;

}
//ALL variables in config have a value, so the configuration is complete
return true;
}
private boolean consistent(String value, String variable) {
//we need to get the constraint list for the variable
for(String constraints: csp.constraintsTable.get(variable)) {
//if the adjacency list member&#39;s value is equal to the variable&#39;s

selected value, then consistency fails

System.out.print(&quot;csp.config: &quot;);
for(String conf: csp.config) {
System.out.print(conf + &quot; = &quot; + csp.config.get(conf) + &quot;, &quot;);
}
System.out.println();
System.out.format(&quot;consistent: %s, %s, %s\n&quot;, constraints,
csp.config.get(constraints), csp.constraintsTable.get(variable).get(constraints).get(value));
if(csp.constraintsTable.get(variable).get(constraints).get(value) !=

null &amp;&amp;

!csp.config.get(constraints).equals(&quot;&quot;) &amp;&amp;

!(csp.constraintsTable.get(variable).get(constraints).get(value).contains(csp.config.get(con
straints)))) {

return false;
}
}
//consistency check passed according to the variable&#39;s adjacancy list
return true;
}
/**
* Backtracking with default ordering (alphabetical)
* @return
*/
ST&lt;String, String&gt; backtracking() {
ArrayList&lt;String&gt; configOrder = new ArrayList&lt;String&gt;();
for(String node: csp.G.vertices()) {
configOrder.add(node);

}
return this.backtracking(configOrder);
}
/**
* Backtracking with user-defined ordering of variables
*
* @param configOrder - the user defined ordering of variables
* @return
*/
ST&lt;String, String&gt; backtracking(ArrayList&lt;String&gt; configOrder) {
//recursion base case - check configuration completeness
if(this.complete())
return csp.config;
ST&lt;String, String&gt; result = null;
//get a variable
String v = this.getVariable(configOrder);
//get a SET of all the variable&#39;s values
SET&lt;String&gt; vu = this.orderDomainValue(v);
//loop through all the variable&#39;s values
for(String u: vu) {
//if(consistent(u, v, config, g)) {
if(this.consistent(u, v)) {
csp.config.put(v, u);
result = this.backtracking(configOrder);
if(result != null)
return result;
csp.config.put(v, &quot;&quot;);
}
}
return null;
}

CO-PO MAPPING:
CO3-PO1,PO2,PO3, PO4, O8,,PO11,PO12
RESULT:
Thus, the program has been written to implement backtracking algorithms
forCSP in Java.

You might also like