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

AI Lab Manual

AIT ai lab manual solution

Uploaded by

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

AI Lab Manual

AIT ai lab manual solution

Uploaded by

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

Ahmedabad Institute of Technology

CE Department
ARTIFICIAL INTELLIGENCE
(3170716)

Laboratory Manual

NAME

ENROLLMENT NUMBER

BATCH

YEAR

SUBJECT COORDINATOR
DEPARTMENT OF COMPUTER ENGINEERING

VISION

“To create competent professionals in the field of Computer Engineering and promote
research with a motive to serve as a valuable resource for the IT industry and society.”

MISSION

1. To produce technically competent and ethically sound Computer Engineering


professionals by imparting quality education, training, hands on experience and value-
based education.
2. To pursue creative research, adapt to rapidly changing technologies and promote self-
learning approaches in Computer Engineering and across disciplines to serve the dynamic
needs of industry, government and society.
3. To inculcate ethical attitude, sense of responsibility towards society and leadership ability
required for a responsible professional computer engineer.

Program Educational Objectives (PEO):


PEO1: To provide the fundamentals of science, mathematics, electronics and computer science and
engineering and skills necessary for a successful IT professional.
PEO2: To provide scope to learn, apply skills, techniques and competency to use modern engineering
tools to solve computational problems.
PEO3: To enable young graduates to adapt to the challenges of evolving career opportunities in their
chosen fields of career including higher studies, research avenues, entrepreneurial activities etc.
PEO4: To inculcate life-long learning aptitude, leadership qualities and teamwork ability with sense
of ethics for a successful professional career in their chosen field.
PROGRAM OUTCOMES (POs)

Engineering Graduates will be able to:

1. Engineering knowledge: Apply the knowledge of mathematics, science, engineering


fundamentals, and an engineering specialization to the solution of complex engineering problems.
2. Problem analysis: Identify, formulate, review research literature, and analyze complex
engineering problems reaching substantiated conclusions using first principles of mathematics,
natural sciences, and engineering sciences.
3. Design/development of solutions: Design solutions for complex engineering problems and
design system components or processes that meet the specified needs with appropriate
consideration for the public health and safety, and the cultural, societal, and environmental
considerations.
4. Conduct investigations of complex problems: Use research-based knowledge and research
methods including design of experiments, analysis and interpretation of data, and synthesis of the
information to provide valid conclusions.
5. Modern tool usage: Create, select, and apply appropriate techniques, resources, and modern
engineering and IT tools including prediction and modeling to complex engineering activities with
an understanding of the limitations.
6. The engineer and society: Apply reasoning informed by the contextual knowledge to assess
societal, health, safety, legal and cultural issues and the consequent responsibilities relevant to the
professional engineering practice.
7. Environment and sustainability: Understand the impact of the professional engineering
solutions in societal and environmental contexts, and demonstrate the knowledge of, and need for
sustainable development.
8. Ethics: Apply ethical principles and commit to professional ethics and responsibilities and norms
of the engineering practice.
9. Individual and team work: Function effectively as an individual, and as a member or leader in
diverse teams, and in multidisciplinary settings.
10. Communication: Communicate effectively on complex engineering activities with the
engineering community and with society at large, such as, being able to comprehend and write
effective reports and design documentation, make effective presentations, and give and receive
clear instructions.
11. Project management and finance: Demonstrate knowledge and understanding of the
engineering and management principles and apply these to one‟s own work, as a member and
leader in a team, to manage projects and in multidisciplinary environments.
12. Life-long learning: Recognize the need for, and have the preparation and ability to engage in
independent and life-long learning in the broadest context of technological change.
ARTIFICIAL INTELLIGENCE PRACTICAL BOOK
DEPARTMENT OF COMPUTER ENGINEERING
PREFACE

It gives us immense pleasure to present the first edition of Artificial Intelligence Design Practical
Book for the B.E. 3rd year students of Ahmedabad Institute of Technology.
This manual is intended for use in an introductory Artificial Intelligence course. Artificial
intelligence (AI), sometimes called machine intelligence, is intelligence demonstrated by
machines, in contrast to the natural intelligence displayed by humans and other animals, such as
"learning" and "problem solving. . In computer science AI research is defined as the study of
"intelligent agents": any device that perceives its environment and takes actions that maximize its
chance of successfully achieving its goals.
In addition, the effort put into the laboratory experiments will ultimately reward the student with a
better understanding of the concepts presented in the classroom.
The student is required to keep a laboratory manual in which the raw data will be recorded as well
as the questions will be kept. The lab write-ups form a permanent record of your work.

Lab Manual Revised by:


INSTRUCTIONS TO STUDENTS

1. Be punctual in arriving to the laboratory with your lab manual and always wear your ID card.

2. It is mandatory to bring lab manual in every practical session.

3. Students have to maintain the discipline in lab and should not create any unnecessary chaos.

4. Students are supposed to occupy the systems allotted to them and are not supposed to talk or
make noise in the lab.

5. Students are required to carry their observation book and lab records with completed exercises
while entering the lab.

6. Lab records need to be submitted every week.

7. Students are not supposed to use pen drives in the lab.

8. All the observations have to be neatly recorded in the Operating System Practical Book and
verified by the instructor before leaving the laboratory.

9. The answers of all the questions mentioned under the section „Post Practical Questions‟ at the
end of each experiment in the Operating System.
Ahmedabad Institute of Technology
CE Department

CERTIFICATE
This is to certify that Mr. / Ms. of
Enrolment No has Satisfactorily completed the
course in as by the Gujarat
Technological University for Year (B.E.) semester of Computer Engineering
in the Academic year .
Date of Submission:-

Faculty Name : Dr. Dushyantsinh Rathod


Signature Head of Department, CE
INDEX

SR PAGE
PRACTICAL DATE SIGN
NO NO
Write a program to implement Tic-Tac-Toe game problem
1
using Magic Square.
Write a program to implement Breath First Search (BFS) for 8
2
tile Puzzle problem.

3 Write a program to implement Depth First Search (DFS) for 8 tile


puzzle problem.
4 Write a program to Implement A* Algorithm.

5 Write a program to Implement AO* Algorithm.

Write a program to implement min-max algorithm for tic tac


6
toe game.
Implement Prolog Family Tree.
7
8 Write a program to solve Tower of Hanoi problem using Python.
9 Write a program to solve N-Queens problem using Python.

10
Write a program to solve travelling salesman problem
using Python.
PRACTICAL 1
AIM: Write a program to implement a Tic-Tac-Toe game problem using Magic Square.

Printing the board

First, we need a board to play the game of course. Let's draw on in the terminal! But wait, you
can't really draw in the terminal. What we can do though is print horizontal lines with Hyphen --
and vertical lines with pipes |.

We are going to start by defining our main function. Let's name it TicTacToe. You can go ahead
and draw a board with print. Don't forget to run the main function at the end.

def TicTacToe():

print(" | | ")

print("---|---|---")

print(" | | ")

print("---|---|---")

print(" | | ")

TicTacToe();

We got our board printed in the terminal. Now we can save the board data in board. When a
player chooses a number on the board, we will change the corresponding number in board with
the players sign - "X" or "O".

board = [1, 2, 3, 4, 5, 6, 7, 8, 9]

Now go ahead and print the box number with the values from board . Let's also put it into a
function while we are at it. This will make printing the board easy later on.

def TicTacToe():

board = [1, 2, 3, 4, 5, 6, 7, 8, 9]

def PrintBoard():

print()
print('', board[0], "|", board[1], "|", board[2])

print("---|---|---")

print('', board[3], "|", board[4], "|", board[5])

print("---|---|---")

print('', board[6], "|", board[7], "|", board[8])

print()

PrintBoard()

TicTacToe()

You should get something like this when you run the code:

Getting input from the user

We have to take input from the players and keep it as simple as possible. The players can type
any number from 1 to 9 to place their corresponding sign, cross X or nought O in the boxes. We
are going to print a message asking for an input later in the main loop. For now, let's just create
a function to get a valid number from the user.

Any number outside 1 to 9 is not on the board. We can simply check it by converting the input
to an integer and checking if it is within a range of 1 to 10. Range can be a bit confusing, it
consists of numbers starting from the first number, to the number before the second number. So
range(1, 5) gives us 1 to 4, range(50, 100) gives 50 to 99 and so on.

number = input()

if number not in range(1, 10):

print("\nNumber not on board")

Any input that is not a number is also unacceptable. So you can use try...except to see if there
was any problem converting number to an integer. If the program fails to convert it to an
integer, it's probably not a number and we can print an error.

Like this:

number = input()

try:

number = int(number)

if number not in range(1, 10):

print("\nNumber not on board")

return

except ValueError:

print("\nThat's not a number. Try again")

Let's now put it all into a function. We will also need a loop so that we can ask for an input
again in case the previous one was invalid. So make a while loop and keep it running until you
get a valid input from the user. Also, check if the number is in the range instead of checking if
the number is not in the range. Finally, return the valid number. It'll look something like this:

def GetNumber():
while True:

number = input()

try:

number = int(number)

if number in range(1, 10):

return number

else:

print("\nNumber not on board")

except ValueError:

print("\nThat's not a number. Try

again") continue

You can now go ahead and run the function to see if it filters out invalid inputs properly.

The main loop

Now comes the fun part! We are finally going to run the game.
end = False
while not end:
PrintBoard()
print("Choose a box Player X")
n = GetNumber()
board[n - 1] = "X"
PrintBoard()
print("Choose a box Player O")
n = GetNumber()
board[n - 1] = "O"

We need a loop to run the game, as there will be up to 9 turns (one for each box). So let's run a
while loop as long as a variable is true. Name it something like end. The loop will run as long as
end is False. We can later change end to True when a player wins or the match is a tie. In our
loop, we first print the board and ask for an input from Player 1 or simply Player X. Then print
the board again but this time with the sign placed into the board. Note that we have to reduce
GetNumber() by one to for the index of board[]. Then we do the same thing for Player O.

Both players should now be able to place a sign in turns now.

But, we never checked if a player has won or players have run out of moves. Let's now work on
that next.
Checking for win: Magic Square

This is the most exciting part of the game, we are gonna find out which player wins. There are 8
ways a player can win in this game, which are the straight lines in 3 vertical rows, 3 columns or
2 diagonal combinations.

There are a few possible ways we could check for a win. One on of the most common trick is
having an array of possible winning combinations, which as you can probably already guess,
would be a long list of array with 8 combinations. Then cross checking it with our board to find
a match. While it does work, it's neither efficient nor fun. What we are going to use is a Magic

Square ✨. It's a square grid of numbers that when added up in rows or columns or diagonally,

always sums up to a magic number. Which in our case is going to be 15.

OUTPUT:

Exercise:

1. Implement Tic-Tac Toe Problem using Python.


Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 2

AIM : Write a program to implement Breath First Search (BFS) for 8 tile Puzzle problem.

The 8 puzzle problem solution is covered in this article. A 3 by 3 board with 8 tiles (each tile
has a number from 1 to 8) and a single empty space is provided. The goal is to use the vacant
space to arrange the numbers on the tiles such that they match the final arrangement. Four
neighbouring (left, right, above, and below) tiles can be moved into the available area.

For instance,

BFS (Brute - Force) :

We can search the state space tree using a breadth-first approach. It always locates the goal state
that is closest to the root. However, the algorithm tries the same series of movements as DFS
regardless of the initial state.

Excercise:

1. Write a Python program to implement BFS for 8 tile Puzzle problem.


Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 3

AIM: Write a program to implement Depth First Search (DFS) for 8 tile Puzzle problem.

DFS :
On the state-space tree (Set of all configurations of a particular issue, i.e., all states that may be
reached from the beginning state), we can do a depth-first search.

In this solution, successive moves can take us away from the goal rather than bringing us
closer. The search of state-space tree follows the leftmost path from the root regardless of
the initial state. An answer node may never be found in this approach.

Excercise:
Write a Python program to implement 8 tile puzzle DFS problem.
Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 4

AIM : Write a program to Implement A* Algorithm.

Numbers written on edges represent the distance between nodes. Numbers written on nodes
represent the heuristic value.

Given the graph, find the cost-effective path from A to G. That is A is the source node and G
is the goal node.

Now from A, we can go to point B or E, so we compute f(x) for each of

them, A → B = g(B) + h(B) = 2 + 6 = 8

A → E = g(E) + h(E) = 3 + 7 = 10

Since the cost for A → B is less, we move forward with this path and compute the f(x) for
the children nodes of B.

Now from B, we can go to point C or G, so we compute f(x) for each of

them, A → B → C = (2 + 1) + 99= 102

A → B → G = (2 + 9 ) + 0 = 11

Here the path A → B → G has the least cost but it is still more than the cost of A → E, thus
we explore this path further.
Now from E, we can go to point D, so we compute

f(x), A → E → D = (3 + 6) + 1 = 10
Comparing the cost of A → E → D with all the paths we got so far and as this cost is least of
all we move forward with this path.

Now compute the f(x) for the children of

D A → E → D → G = (3 + 6 + 1) +0 = 10

Now comparing all the paths that lead us to the goal, we conclude that A → E → D → G is the
most cost-effective path to get from A to G.

OUTPUT:

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

Excercise:

Write a Python program to Implement A* Algorithm.


Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 5
AIM : Write a program to Implement AO* Algorithm.

Best-first search is what the AO* algorithm does. The AO* method divides any given difficult
problem into a smaller group of problems that are then resolved using the AND-OR graph
concept. AND OR graphs are specialized graphs that are used in problems that can be divided
into smaller problems. The AND side of the graph represents a set of tasks that must be
completed to achieve the main goal, while the OR side of the graph represents different
methods for accomplishing the same main goal.

In the above figure, the buying of a car may be broken down into smaller problems or tasks that
can be accomplished to achieve the main goal in the above figure, which is an example of a
simple AND-OR graph. The other task is to either steal a car that will help us accomplish the
main goal or use your own money to purchase a car that will accomplish the main goal. The
AND symbol is used to indicate the AND part of the graphs, which refers to the need that all
subproblems containing the AND to be resolved before the preceding node or issue may be
finished.
The start state and the target state are already known in the knowledge-based search strategy
known as the AO* algorithm, and the best path is identified by heuristics. The informed search
technique considerably reduces the algorithm‟s time complexity. The AO* algorithm is far more
effective in searching AND-OR trees than the A* algorithm.
Working of AO* algorithm:
The evaluation function in AO* looks like this:
f(n) = g(n) + h(n)
f(n) = Actual cost + Estimated cost
here,
f(n) = The actual cost of traversal.
g(n) = the cost from the initial node to the current node.
h(n) = estimated cost from the current node to the goal state.
Difference between the A* Algorithm and AO* algorithm
● A* algorithm and AO* algorithm both works on the best first search.
● They are both informed search and works on given heuristics values.
● A* always gives the optimal solution but AO* doesn‟t guarantee to give the
optimal solution.
● Once AO* got a solution doesn‟t explore all possible paths but A* explores all paths.
● When compared to the A* algorithm, the AO* algorithm uses less memory.
● opposite to the A* algorithm, the AO* algorithm cannot go into an endless loop.

Example:

Here in the above example below the Node which is given is the heuristic value i.e h(n). Edge
length is considered as 1.

With help of f(n) = g(n) + h(n) evaluation function,


Start from node A,
f(A⇢B) = g(B) + h(B)
= 1 + 5 here g(n)=1 is taken by default for path cost
=6

f(A⇢C+D) = g(c) + h(c) + g(d) + h(d)


= 1 + 2 + 1 + 4 here we have added C & D because they are in AND
= 8 So, by calculation A⇢B path is chosen which is the minimum path, i.e f(A⇢B)

Step 2
According to the answer of step 1, explore node B
Here the value of E & F are calculated as follows,

f(B⇢E) = g(e) + h(e)


f(B⇢E) = 1 + 7
=8

f(B⇢f) = g(f) + h(f)


f(B⇢f) = 1 + 9
= 10
So, by above calculation B⇢E path is chosen which is minimum path, i.e f(B⇢E)because B's
heuristic value is different from its actual value The heuristic is updated and the minimum
cost path is selected. The minimum value in our situation is 8.
Therefore, the heuristic for A must be updated due to the change in B's heuristic. So we need
to calculate it again.

f(A⇢B) = g(B) + updated h(B)


=1+8
=9
We have Updated all values in the above tree.

Step 3

By comparing f(A⇢B) & f(A⇢C+D)


f(A⇢C+D) is shown to be smaller. i.e 8 <
9 Now explore f(A⇢C+D)
So, the current node is C

f(C⇢G) = g(g) + h(g)


f(C⇢G) = 1 + 3
=4

f(C⇢H+I) = g(h) + h(h) + g(i) + h(i)


f(C⇢H+I) = 1 + 0 + 1 + 0 ……here we have added H & I because they are in AND
=2

f(C⇢H+I) is selected as the path with the lowest cost and the heuristic is also left unchanged
because it matches the actual cost. Paths H & I are solved because the heuristic for those paths
is 0, but Path A⇢D needs to be calculated because it has an AND.

f(D⇢J) = g(j) + h(j)


f(D⇢J) = 1 + 0
=1
the heuristic of node D needs to be updated to 1.

f(A⇢C+D) = g(c) + h(c) + g(d) + h(d)


=1+2+1+1
=5

as we can see that path f(A⇢C+D) is get solved and this tree has become a solved tree now.
In simple words, the main flow of this algorithm is that we have to find firstly level 1st
heuristic value and then level 2nd and after that update the values with going upward means
towards the root node. In the above tree diagram, we have updated all the values.

# Cost to find the AND and OR path


def Cost(H, condition, weight = 1):
cost = {}
if 'AND' in condition:
AND_nodes = condition['AND']
Path_A = ' AND '.join(AND_nodes)
PathA = sum(H[node]+weight for node in AND_nodes)
cost[Path_A] = PathA

if 'OR' in condition:
OR_nodes = condition['OR']
Path_B =' OR '.join(OR_nodes)
PathB = min(H[node]+weight for node in OR_nodes)
cost[Path_B] = PathB
return cost

# Update the cost


def update_cost(H, Conditions, weight=1):
Main_nodes = list(Conditions.keys())
Main_nodes.reverse()
least_cost= {}
for key in Main_nodes:
condition = Conditions[key]
print(key,':', Conditions[key],'>>>', Cost(H, condition,
weight)) c = Cost(H, condition, weight)
H[key] = min(c.values())
least_cost[key] = Cost(H, condition, weight)
return least_cost

# Print the shortest path


def shortest_path(Start,Updated_cost, H):
Path = Start
if Start in Updated_cost.keys():
Min_cost = min(Updated_cost[Start].values())
key = list(Updated_cost[Start].keys())
values = list(Updated_cost[Start].values())
Index = values.index(Min_cost)

# FIND MINIMIMUM PATH KEY

Next = key[Index].split()
# ADD TO PATH FOR OR PATH
if len(Next) == 1:

Start =Next[0]
Path += '<--' +shortest_path(Start, Updated_cost, H)
# ADD TO PATH FOR AND PATH
else:
Path +='<--('+key[Index]+') '

Start = Next[0]
Path += '[' +shortest_path(Start, Updated_cost, H) + ' + '

Start = Next[-1]
Path += shortest_path(Start, Updated_cost, H) + ']'

return Path

H = {'A': -1, 'B': 5, 'C': 2, 'D': 4, 'E': 7, 'F': 9, 'G': 3, 'H': 0, 'I':0, 'J':0}

Conditions = {
'A': {'OR': ['B'], 'AND': ['C', 'D']},
'B': {'OR': ['E', 'F']},
'C': {'OR': ['G'], 'AND': ['H', 'I']},
'D': {'OR': ['J']}
}
# weight
weight = 1
# Updated cost
print('Updated Cost :')
Updated_cost = update_cost(H, Conditions, weight=1)
print('*'*75)
print('Shortest Path :\n',shortest_path('A', Updated_cost,H))

OUTPUT:
Updated Cost :
D : {'OR': ['J']} >>> {'J': 1}
C : {'OR': ['G'], 'AND': ['H', 'I']} >>> {'H AND I': 2, 'G': 4}
B : {'OR': ['E', 'F']} >>> {'E OR F': 8}
A : {'OR': ['B'], 'AND': ['C', 'D']} >>> {'C AND D': 5, 'B': 9}
***************************************************************************
Shortest Path :
A<--(C AND D) [C<--(H AND I) [H + I] + D<--J]
Excercise:
1. Write a Python program to Implement AO* Algorithm.
Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 6

AIM: Write a program to implement min-max algorithm for tic tac toe game Code

Let us combine what we have learnt so far about minimax and evaluation function to write a
proper Tic-Tac-Toe AI (Artificial Intelligence) that plays a perfect game. This AI will consider
all possible scenarios and makes the most optimal move.
Finding the Best Move :
We shall be introducing a new function called findBestMove(). This function evaluates all the
available moves using minimax() and then returns the best move the maximizer can make. The
pseudocode is as follows :
function findBestMove(board):
bestMove = NULL
for each move in board :
if current move is better than bestMove
bestMove = current move
return bestMove
Minimax :
To check whether or not the current move is better than the best move we take the help of
minimax() function which will consider all the possible ways the game can go and returns the
best value for that move, assuming the opponent also plays optimally
The code for the maximizer and minimizer in the minimax() function is similar to
findBestMove(), the only difference is, instead of returning a move, it will return a value. Here
is the pseudocode :
function minimax(board, depth, isMaximizingPlayer):

if current board state is a terminal state :


return value of the board

if isMaximizingPlayer :
bestVal = -INFINITY
for each move in board :
value = minimax(board, depth+1, false)
bestVal = max( bestVal, value)
return bestVal

else :
bestVal = +INFINITY
for each move in board :
value = minimax(board, depth+1, true)
bestVal = min( bestVal, value)
return bestVal
Checking for GameOver state :
To check whether the game is over and to make sure there are no moves left we use
isMovesLeft() function. It is a simple straightforward function which checks whether a move is
available or not and returns true or false respectively. Pseudocode is as follows :
function isMovesLeft(board):
for each cell in board:
if current cell is empty:
return true
return false
Making our AI smarter :
One final step is to make our AI a little bit smarter. Even though the following AI plays
perfectly, it might choose to make a move which will result in a slower victory or a faster loss.
Lets take an example and explain it.
Assume that there are 2 possible ways for X to win the game from a given board state.
● Move A : X can win in 2 move
● Move B : X can win in 4 moves

Our evaluation function will return a value of +10 for both moves A and B. Even though the
move A is better because it ensures a faster victory, our AI may choose B sometimes. To
overcome this problem we subtract the depth value from the evaluated score. This means that in
case of a victory it will choose a the victory which takes least number of moves and in case of a
loss it will try to prolong the game and play as many moves as possible. So the new evaluated
value will be
● Move A will have a value of +10 – 2 = 8
● Move B will have a value of +10 – 4 = 6

Now since move A has a higher score compared to move B our AI will choose move A over
move B. The same thing must be applied to the minimizer. Instead of subtracting the depth we
add the depth value as the minimizer always tries to get, as negative a value as possible. We can
subtract the depth either inside the evaluation function or outside it. Anywhere is fine. I have
chosen to do it outside the function. Pseudocode implementation is as follows.
if maximizer has won:
return WIN_SCORE – depth

else if minimizer has won:


return LOOSE_SCORE + depth
This image depicts all the possible paths that the game can take from the root board state. It is
often called the Game Tree.
The 3 possible scenarios in the above example are :
● Left Move : If X plays [2,0]. Then O will play [2,1] and win the game. The value of
this move is -10
● Middle Move : If X plays [2,1]. Then O will play [2,2] which draws the game. The
value of this move is 0
● Right Move : If X plays [2,2]. Then he will win the game. The value of this move is

+10;

Remember, even though X has a possibility of winning if he plays the middle move, O will
never let that happen and will choose to draw instead.
Therefore the best choice for X, is to play [2,2], which will guarantee a victory for him.

Minimax may confuse programmers as it thinks several moves in advance and is very hard to
debug at times.
Remember this implementation of minimax algorithm can be applied any 2 player board game
with some minor changes to the board structure and how we iterate through the moves.
Also sometimes it is impossible for minimax to compute every possible game state for complex
games like Chess. Hence we only compute upto a certain depth and use the evaluation function
to calculate the value of the board.

Excercise:
1. Write a Python program to implement min-max algorithm for tic tac toe game Code
Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 7

AIM : Implement Prolog Family Tree.

The prolog family tree, defined as the prolog, is a logical programming language with symbolic

and non-numeric data processing. It is especially well suited for solving problems that require

objects and relationships between the objects. It is a user-friendly programming language

because it uses logic in its programming, prolog family trees can be constructed by using the

facts, rules, and queries, collection of facts and rules is called a knowledge-base, which describe

the relationship of their objects. The prolog programming is all about knowledge- base and by

posing queries means by asking questions to prolog about the information stored in knowledge-

base.

Syntax of Prolog Family Tree


The prolog syntax for mother-sister relationship is given as below:

Mother Relationship
Sister Relationship

● mother(M,N): parent(M,N), female(M).

● sister(M,N): parent(O,M), parent(O,N), female(M), M\= =N.

We can also define:

● father(M,N): parent(M,N),female(M).

● haschild(M): parent(M,_).

● brother(M,N): parent(O,M), parent(O,N), male(M),M\==N.

Where _(underscore) indicates that it is an anonymous variable.

We can also write the syntax for some other relationships as follows:

● grandparent(M,N): parent(M,O), parent(O,N).

● grandmother(M,O): mother(M,N), parent(N,O).

● grandfather(M,O): father(M,N), parent(N,O).

● wife(M,N): parent(M,O), parent(N,O), female(M),male(N).

● uncle(M,O): brother(M,N), parent(N,O).

How to Create a Family Tree in Prolog?


The program in prolog specifies the relationship between objects and the properties of objects;

the family trees tell us how to construct a database of family. The database also contains facts

and rules; let us consider the example “Sumit has a car.” We can declare the original

relationship between two objects where one object is Sumit. Another object is a car; if we say,

“does Sumit own a car?” there are many types of relationships; some of them are ruled by using

rules in the program, we can find the relationship between objects used, and it is not defined as a

fact. Tree
diagrams are very good in representations the information is clearly mentioned, and due to that,

users can understand easily, our programs in prolog are the sets of clauses.

Brother relationship:

● If they both are male.

● If they have the same parent.

Suppose we have some clauses to illustrate the relationship:

● parent(somit,komal).

● parent(somit,manish).

● male(komal).

● male(manish).

● brother(X,Y): parent(Z,X), parent(Z, Y), male(X), male(Y)

From the above clauses, we can conclude that b and c are brothers, but we can create 3

combinations that are true, combinations are (komal,komal), (komal,manish), (manish,manish)

but actually (komal,komal) and (manish,manish) are not real brothers because they are same

brothers.

Let us see the working of the family tree by considering an example that can be formed from the

prolog family tree. We want to make a family tree and as per our definition that can be mapped

into facts and rules, so that we can run some queries on them,

The sample family tree is given below:


Here we are having one family tree, so from the above sample of the family tree, there are some

relationships between them; from the above family tree diagram, we can say that „C‟ is a child

of A and B, which means that A is a parent of C and B is also a parent of C, B also has one child

D, C has one brother D, whose parent is also A and B, so we can make predicates to call

families as follows, C has two child E and F and F also has a child G, following above family

tree we have written some clauses below, and every clause must be terminated by a full stop(.).

● parent(A,C).

● parent(B,C).

● parent(B,D).

● parent(C,E).

● parent(C,F).

● parent(F,G).

From the above examples, we can illustrate some important points that we can define parent

relation by taking n-number of objects which is based on the given information of family tree so

that user can easily pose the query to prolog system about relations which are defined in
programs, the prolog programs terminated by clauses and that consists of clauses, the arguments

of relations are of a constant type or related to any general object as we given above, objects are

of atom or variables types.

Examples of Prolog Family Tree


Different examples are mentioned
below:

Example #1
Knowledge base

Code:

female(pammi).
female(lizza).
female(patty).
female(anny).
male(jimmy).
male(bobby).
male(tomy).
male(pitter).
parent(pammi,bobby).
parent(tomy,bobby).
parent(tomy,lizza).
parent(bobby,anny).
parent(bobby,patty).
parent(patty,jimmy).
parent(bobby,pitter).
parent(pitter,jimmy).
mother(X,Y):- parent(X,Y),female(X).
father(X,Y):- parent(X,Y),male(X).
haschild(X):- parent(X,_).
sister(X,Y):- parent(Z,X),parent(Z,Y),female(X),X\==Y.
brother(X,Y):-
parent(Z,X),parent(Z,Y),male(X),X\==Y. Input:
parent(X,jimmy).
mother(X,Y).
haschild(X).
sister(X,Y).

Output:
Excercise:
1. Write a prolog code and write an output for the given relationship sibling (karim,kabil).

Code:

female(trisha).
female(joseph).
male(rahil).
male(karim).
male(kabil).
male(riya).
parent(rahil,karim).
parent(rahil,kabil).
parent(karim,trisha).
parent(karim,joseph).
son(X,Y):-male(X) ,parent(Y,X).
daughter(X, Y):- female(X) ,parent(Y ,X).
sibling(X, Y):-
parent(Z, X) ,parent(Z,Y), X \=
Y. Input:
son(karim,rahil).
son(joseph,karim).
daughter(trisha,kabil).
daughter(riya,kabir).
sibling(karim,kabil)
EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 8
AIM : Write a program to solve the Tower of Hanoi problem using Python.

Tower of Hanoi Problem in Python:


● The ancient puzzle of the Tower of Hanoi consists of some wooden disks and three
poles attached to a baseboard. The disks each have different diameters and a hole in
the middle large enough for the poles to pass through. The object of the puzzle is to
move all the disks over to the right pole, one at a time, so that they end up in the
original order on that pole. The middle pole may be used as a temporary resting
place for disks, but at no time is a larger disk to be on top of a smaller one. The
Tower of Hanoi problem can be easily solved with one or two disks but becomes
more difficult with three or more disks.

A simple strategy for solving the puzzle is


1. A single disk can be moved directly.
2. N disks can be moved in three steps:
i. Move N-1 disks to the middle pole.
ii. Move the last disk directly over to the right pole.
iii. Move the N-1 disks from the middle pole to the right pole.

Why do we present a Python implementation of the "Towers of Hanoi"? The hello-world of


recursion is the Factorial. This means, you will hardly find any book or tutorial about
programming languages which doesn't deal with the first and introductory example about
recursive functions. Another one is the calculation of the n-th Fibonacci number. Both are well
suited for a tutorial because of their simplicity but they can be easily written in an iterative way
as well.

If you have problems in understanding recursion, we recommend that you go through the
chapter "Recursive Functions" of our tutorial.

That's different with the "Towers of Hanoi". A recursive solution almost forces itself on the
programmer, while the iterative solution of the game is hard to find and to grasp. So, with the
Towers of Hanoi we present a recursive Python program, which is hard to program in an
iterative way.

There is an old legend about a temple or monastery, which contains three poles. One of them
filled with 64 gold disks. The disks are of different sizes, and they are put on top of each other,
according to their size, i.e. each disk on the pole a little smaller than the one beneath it. The
priests, if the legend is about a temple, or the monks, if it is about a monastery, have to move
this stack from one of the three poles to another one. But one rule has to be applied: a large disk
can never be placed on top of a smaller one. When they would have finished their work, the
legend tells, the temple would crumble into dust, and the world would end. But don't be afraid,
it's not very likely that they will finish their work soon, because 264 - 1 moves are necessary,
i.e. 18,446,744,073,709,551,615 to move the tower according to the rules. But there is - most
probably - no ancient legend. The legend and the game "towers of Hanoi" had been conceived
by the French mathematician Edouard Lucas in 1883.

Rules of the Game

The rules of the game are very simple, but the solution is not so obvious. The game "Towers of
Hanoi" uses three rods. A number of disks is stacked in decreasing order from the bottom to the
top of one rod, i.e. the largest disk at the bottom and the smallest one on top. The disks build a
conical tower.

The aim of the game is to move the tower of disks from one rod to another rod.

The following rules have to be obeyed:

● Only one disk may be moved at a time.


● Only the most upper disk from one of the rods can be moved in a move
● It can be put on another rod, if this rod is empty or if the most upper disk of this rod is
larger than the one which is moved.

Number of Moves

The number of moves necessary to move a tower with n disks can be calculated as: 2n - 1

Playing around to Find a Solution From the formula above, we know that we need 7 moves to
move a tower of size 3 from the most left rod (let's call it SOURCE to the most right tower
(TARGET). The pole in the middle (we will call it AUX) is needed as an auxiliary stack to
deposit disks temporarily. Before we examine the case with 3 disks, as it is depicted in the
image on the right side, we will have a look at towers of size 1 (i.e. just one disk) and size 2.
The solution for a tower with just one disk is straightforward: We will move the one disk on the
SOURCE tower to the TARGET tower and we are finished. Let's look now at a tower with size
2, i.e. two disks. There are two possibilities to move the first disk, the disk on top of the stack of
SOURCE: We can move this disk either to TARGET or to AUX.

We have seen in the cases n=1 and n=2 that it depends on the first move, if we will be able to
successfully and with the minimal number of moves solve the riddle. We know from our
formula that the minimal number of moves necessary to move a tower of size 3 from the
SOURCE peg to the target peg is 7 (23 - 1) You can see in the solution, which we present in our
image that the first disk has to be moved from the peg SOURCE to the peg TARGET. If your
first step consists of moving the smallest disk to AUX, you will not be capable of finishing the
task with less than 9 moves. Let's number the disks as D1 (smallest), D2 and D3 (largest) and
name the pegs as S (SOURCE peg), A (AUX), T (TARGET). We can see that we move in three
moves the tower of size 2 (the disks D1 and D2) to A. Now we can move D3 to T, where it is
finally positioned. The last three moves move the tower consisting of D2D1 from peg A to T to
place them on top of D3. There is a general rule for moving a tower of size n (n > 1) from the
peg S to the peg T:

● So let's start by moving the smallest disk from SOURCE to TARGET. Now there are
two choices: We can move this disk again, either back to the SOURCE peg, which
obviously doesn't make sense, or we could move it to AUX, which doesn't make sense
either, because we could have moved there as our first step. So the only move which
makes sense is moving the other disk, i.e. the largest disk, to peg AUX. Now, we have to
move the smallest disk again, because we don't want to move the largest disk back to
SOURCE again. We can move the smallest disk to AUX. Now we can see that we have
moved the tower of size 2 to the peg AUX, but the target had been peg TARGET. We
have already used the maximal number of moves, i.e. 22 - 1 = 3

● Moving the smallest disk from peg SOURCE to TARGET as our first step has not
shown to be successful. So, we will move this disk to peg AUX in our first step. After
this we move the second disk to TARGET. After this we move the smallest disk from
AUX to TARGET and we have finished our task!
○ move a tower of n - 1 discs Dn-1 ... D1 from S to A. Disk Dn is left alone on peg S
○ Move disk Dn to T
○ move the tower of n - 1 discs Dn-1 ... D1 on A to T, i.e. this tower will be put on
top of Disk Dn

The algorithm, which we have just defined, is a recursive algorithm to move a tower of size n. It
actually is the one, which we will use in our Python implementation to solve the Towers of
Hanoi. Step 2 is a simple move of a disk. But to accomplish the steps 1 and 3, we apply the
same algorithm again on a tower of n-1. The calculation will finish with a finite number of
steps, because very time the recursion will be started with a tower which is 1 smaller than the
one in the calling function. So finally we will end up with a tower of size n = 1, i.e. a simple
move.

Recursive Python Program

The following Python script contains a recursive function "hanoi", which implements a
recursive solution for Towers of Hanoi:

def hanoi(n, source, helper, target):


if n > 0:
# move tower of size n - 1 to helper:
hanoi(n - 1, source, target, helper)
# move disk from source peg to target peg
if source:
target.append(source.pop())
# move tower of size n-1 from helper to target
hanoi(n - 1, helper, source, target)

source = [4,3,2,1]
target = []
helper = []
hanoi(len(source),source,helper,target)

print(source, helper, target)

OUTPUT:
[] [] [4, 3, 2, 1]

This function is an implementation of what we have explained in the previous subchapter. First
we move a tower of size n-1 from the peg source to the helper peg. We do this by calling

hanoi(n - 1, source, target, helper)

After this, there will be the largest disk left on the peg source. We move it to the empty peg
target by the statement

if source:
target.append(source.pop())

After this, we have to move the tower from "helper" to "target", i.e. on top of the largest

disk: hanoi(n - 1, helper, source, target)

If you want to check, what's going on, while the recursion is running, we suggest the following
Python programm. We have slightly changed the data structure. Instead of passing just the
stacks of disks to the function, we pass tuples to the function. Each tuple consists of the stack
and the function of the stack:

Excercise:

Write a program to solve the Tower of Hanoi problem using Python.


Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL 9

AIM : Write a program to solve N-Queens problem using Python.

The N Queen is the problem of placing N chess queens on an N×N chessboard so that no two
queens attack each other. For example, the following is a solution for 4 Queen problem.

The expected output is a binary matrix that has 1s for the blocks where queens are placed. For
example, the following is the output matrix for above 4 queen solution.
{ 0, 1, 0, 0}
{ 0, 0, 0, 1}
{ 1, 0, 0, 0}
{ 0, 0, 1, 0}

Exercise:
1. Write a Python program to solve N Queen Problem using backtracking
Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature
PRACTICAL - 10

AIM : Write a program to solve traveling salesman problem using Python.

Given a set of cities and distance between every pair of cities, the problem is to find the shortest
possible tour that visits every city exactly once and returns to the starting point.

For example, consider the graph shown in figure on right side. A TSP tour in the graph is 0-1-3-
2-0. The cost of the tour is 10+25+30+15 which is 80.
Branch and Bound Solution
As seen in the previous articles, in Branch and Bound method, for current node in tree, we
compute a bound on best possible solution that we can get if we down this node. If the bound on
best possible solution itself is worse than current best (best computed so far), then we ignore the
subtree rooted with the node.
Note that the cost through a node includes two costs.
1) Cost of reaching the node from the root (When we reach a node, we have this cost computed)
2) Cost of reaching an answer from current node to a leaf (We compute a bound on this cost to
decide whether to ignore subtree with this node or not).

● In cases of a maximization problem, an upper bound tells us the maximum possible


solution if we follow the given node. For example in 0/1 knapsack we used Greedy
approach to find an upper bound.
● In cases of a minimization problem, a lower bound tells us the minimum possible
solution if we follow the given node. For example, in Job Assignment Problem, we
get a lower bound by assigning least cost job to a worker.

In branch and bound, the challenging part is figuring out a way to compute a bound on best
possible solution. Below is an idea used to compute bounds for Travelling salesman problem.
Cost of any tour can be written as below.
Cost of a tour T = (1/2) * ∑ (Sum of cost of two edge adjacent to u and in the tour T)
where u ∈ V
For every vertex u, if we consider two edges through it in T, and sum their costs. The overall
sum for all vertices would be twice of cost of tour T (We have considered every edge twice.)

(Sum of two tour edges adjacent to u) >= (sum of minimum weight two edges adjacent to u)

Cost of any tour >= 1/2) * ∑ (Sum of cost of two minimum weight edges adjacent to u) where u
∈V
For example, consider the above shown graph. Below are minimum cost two edges adjacent to
every node.

Node Least cost edges Total cost


0 (0, 1), (0, 2) 25
1 (0, 1), (1, 3) 35
2 (0, 2), (2, 3) 45
3 (0, 3), (1, 3) 45

Thus a lower bound on the cost of any tour = 1/2(25 + 35 + 45 + 45) = 75


Refer this for one more example.
Now we have an idea about computation of lower bound. Let us see how to how to apply it state
space search tree. We start enumerating all possible nodes (preferably in lexicographical order)
1. The Root Node: Without loss of generality, we assume we start at vertex “0” for which the
lower bound has been calculated above.
Dealing with Level 2: The next level enumerates all possible vertices we can go to (keeping in
mind that in any path a vertex has to occur only once) which are, 1, 2, 3… n (Note that the
graph is complete). Consider we are calculating for vertex 1, Since we moved from 0 to 1, our
tour has now included the edge 0-1. This allows us to make necessary changes in the lower
bound of the root.

Lower Bound for vertex 1 = Old lower bound - ((minimum edge cost of 0 + minimum edge cost
of 1) / 2) + (edge cost 0-1)

How does it work? To include edge 0-1, we add the edge cost of 0-1, and subtract an edge
weight such that the lower bound remains as tight as possible which would be the sum of the
minimum edges of 0 and 1 divided by 2. Clearly, the edge subtracted can‟t be smaller than this.
Dealing with other levels: As we move on to the next level, we again enumerate all possible
vertices. For the above case going further after 1, we check out for 2, 3, 4, …n.
Consider lower bound for 2 as we moved from 1 to 1, we include the edge 1-2 to the tour and
alter the new lower bound for this node.

Lower bound(2) = Old lower bound - ((second minimum edge cost of 1 + minimum edge cost of
2)/2) + edge cost 1-2)
Note: The only change in the formula is that this time we have included second minimum edge
cost for 1, because the minimum edge cost has already been subtracted in previous level.
Excercise:
Write a Python program to solve Traveling Salesman Problem using Branch
and Bound.
Output:

EVALUATION:
Understanding / Timely
Involvement (4) Total (10)
Problem solving Completion
(3) (3)

Signature

You might also like