# Practical Assignment of Artificial intelligence

Practical no:-01 BFS and DFS

``````#import packages
import pandas as pd
import numpy as np

x=dataset.iloc[:,:-1]
y=dataset.iloc[:,5]

#Label encoder
from sklearn.preprocessing import LabelEncoder
le=LabelEncoder()
x=x.apply(le.fit_transform)
print(x)

# 1 1 0 0

#import Decesion Tree Classifier

from sklearn.tree import DecisionTreeClassifier
# Create decision tree classifer object
regressor=DecisionTreeClassifier()
# Train model
regressor.fit(x.iloc[:,1:5],y)

x_in=np.array([1,1,0,0])
y_pred=regressor.predict([x_in])

print(y_pred)

from sklearn.externals.six import StringIO
#from IPython.display import Image
from sklearn.tree import export_graphviz
import pydotplus

dot_data=StringIO()
export_graphviz(regressor,out_file=dot_data,filled=True,rounded=True,special_characters=True)

#Draw Graph
graph=pydotplus.graph_from_dot_data(dot_data.getvalue())

# Show graph & Create png File
graph.write_png("tree.png")

# see the tree in .spyder3 folder
``````

Practical no:-01 A Star Algorithm 8 -puzzels

``````class Node:
def __init__(self,data,level,fval):
""" Initialize the node with the data, level of the node and the calculated fvalue """
self.data = data
self.level = level
self.fval = fval

def generate_child(self):
""" Generate child nodes from the given node by moving the blank space
either in the four directions {up,down,left,right} """
x,y = self.find(self.data,'-')
""" val_list contains position values for moving the blank space in either of
the 4 directions [up,down,left,right] respectively. """
val_list = [[x,y-1],[x,y+1],[x-1,y],[x+1,y]]
children = []
for i in val_list:
child = self.shuffle(self.data,x,y,i,i)
if child is not None:
child_node = Node(child,self.level+1,0)
children.append(child_node)
return children

def shuffle(self,puz,x1,y1,x2,y2):
""" Move the blank space in the given direction and if the position value are out
of limits the return None """
if x2 >= 0 and x2 < len(self.data) and y2 >= 0 and y2 < len(self.data):
temp_puz = []
temp_puz = self.copy(puz)
temp = temp_puz[x2][y2]
temp_puz[x2][y2] = temp_puz[x1][y1]
temp_puz[x1][y1] = temp
return temp_puz
else:
return None

def copy(self,root):
""" Copy function to create a similar matrix of the given node"""
temp = []
for i in root:
t = []
for j in i:
t.append(j)
temp.append(t)
return temp

def find(self,puz,x):
""" Specifically used to find the position of the blank space """
for i in range(0,len(self.data)):
for j in range(0,len(self.data)):
if puz[i][j] == x:
return i,j

class Puzzle:
def __init__(self,size):
""" Initialize the puzzle size by the specified size,open and closed lists to empty """
self.n = size
self.open = []
self.closed = []

def accept(self):
""" Accepts the puzzle from the user """
puz = []
for i in range(0,self.n):
temp = input().split(" ")
puz.append(temp)
return puz

def f(self,start,goal):
""" Heuristic Function to calculate hueristic value f(x) = h(x) + g(x) """
return self.h(start.data,goal)+start.level

def h(self,start,goal):
""" Calculates the different between the given puzzles """
temp = 0
for i in range(0,self.n):
for j in range(0,self.n):
if start[i][j] != goal[i][j] and start[i][j] != '-':
temp += 1
return temp

def process(self):
""" Accept Start and Goal Puzzle state"""
print("Enter the start state matrix \n")
start = self.accept()
print("Enter the goal state matrix \n")
goal = self.accept()

start = Node(start,0,0)
start.fval = self.f(start,goal)
""" Put the start node in the open list"""
self.open.append(start)
print("\n\n")
while True:
cur = self.open
print("")
print("  | ")
print("  | ")
print(" \\\'/ \n")
for i in cur.data:
for j in i:
print(j,end=" ")
print("")
""" If the difference between current and goal node is 0 we have reached the goal node"""
if(self.h(cur.data,goal) == 0):
break
for i in cur.generate_child():
i.fval = self.f(i,goal)
self.open.append(i)
self.closed.append(cur)
del self.open

""" sort the opne list based on f value """
self.open.sort(key = lambda x:x.fval,reverse=False)

puz = Puzzle(3)
puz.process()``````

3. Practicle no-3 Kruskal MST

``````from collections import defaultdict

# Class to represent a graph

class Graph:

def __init__(self, vertices):
self.V = vertices  # No. of vertices
self.graph = []  # default dictionary
# to store graph

# function to add an edge to graph
def addEdge(self, u, v, w):
self.graph.append([u, v, w])

# A utility function to find set of an element i
# (uses path compression technique)
def find(self, parent, i):
if parent[i] == i:
return i
return self.find(parent, parent[i])

# A function that does union of two sets of x and y
# (uses union by rank)
def union(self, parent, rank, x, y):
xroot = self.find(parent, x)
yroot = self.find(parent, y)

# Attach smaller rank tree under root of
# high rank tree (Union by Rank)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:
parent[yroot] = xroot

# If ranks are same, then make one as root
# and increment its rank by one
else:
parent[yroot] = xroot
rank[xroot] += 1

# The main function to construct MST using Kruskal's
# algorithm
def KruskalMST(self):

result = []  # This will store the resultant MST

# An index variable, used for sorted edges
i = 0

# An index variable, used for result[]
e = 0

# Step 1:  Sort all the edges in
# non-decreasing order of their
# weight.  If we are not allowed to change the
# given graph, we can create a copy of graph
self.graph = sorted(self.graph,
key=lambda item: item)

parent = []
rank = []

# Create V subsets with single elements
for node in range(self.V):
parent.append(node)
rank.append(0)

# Number of edges to be taken is equal to V-1
while e < self.V - 1:

# Step 2: Pick the smallest edge and increment
# the index for next iteration
u, v, w = self.graph[i]
i = i + 1
x = self.find(parent, u)
y = self.find(parent, v)

# If including this edge does't
#  cause cycle, include it in result
#  and increment the indexof result
# for next edge
if x != y:
e = e + 1
result.append([u, v, w])
self.union(parent, rank, x, y)
# Else discard the edge

minimumCost = 0
print ("Edges in the constructed MST")
for u, v, weight in result:
minimumCost += weight
print("%d -- %d == %d" % (u, v, weight))
print("Minimum Spanning Tree" , minimumCost)

# Driver code
g = Graph(4)

# Function call
g.KruskalMST()``````

4 .Practical no-04 map coloring and N-queen

``````# Algorithm:
# 1. Create a recursive function that takes the graph, current index, number of vertices, and output color array.
# 2. If the current index is equal to the number of vertices. Print the color configuration in output array.
# 3. Assign a color to a vertex (1 to m).
# 4. For every assigned color, check if the configuration is safe, (i.e. check if the adjacent vertices do not have the same color) recursively call the function with next index and number of vertices
# 5. If any recursive function returns true break the loop and return true.
# 6. If no recursive function returns true then return false.

class Graph():

def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]\
for row in range(vertices)]

# A utility function to check
# if the current color assignment
# is safe for vertex v
def isSafe(self, v, colour, c):
for i in range(self.V):
if self.graph[v][i] == 1 and colour[i] == c:
return False
return True

# A recursive utility function to solve m
# coloring  problem
def graphColourUtil(self, m, colour, v):
if v == self.V:
return True

for c in range(1, m + 1):
if self.isSafe(v, colour, c) == True:
colour[v] = c
if self.graphColourUtil(m, colour, v + 1) == True:
return True
colour[v] = 0

def graphColouring(self, m):
colour =  * self.V
if self.graphColourUtil(m, colour, 0) == None:
return False

# Print the solution
print ("Solution exist and Following are the assigned colours:")
for c in colour:
print (c,end=' ')
return True

# Driver Code
g = Graph(4)
g.graph = [[0, 1, 1, 1], [1, 0, 1, 0], [1, 1, 0, 1], [1, 0, 1, 0]]
m = 3
g.graphColouring(m)``````