Ai Document
Ai Document
DESCRIPTION: This program implements a simple calculator that can perform basic
arithmetic operations: addition, subtraction, multiplication, and division. The user selects an
operation and provides two numbers, and the program computes and displays the result.
AIM: Design of Intelligent systems. (Suggested exercise: to control the VACUUM Cleaner
moves)
1. Initialization The program initializes the goal state where both rooms are clean ({'A':
'0', 'B': '0'}).
2. User Input The initial location of the vacuum cleaner. The status of the current
location (clean or dirty).The status of the other room (clean or dirty).
3. Agent Behavior If the current location is dirty, the vacuum cleans it and incurs a cost.
If the other room is dirty, the vacuum moves to that room, cleans it, and incurs
additional costs for moving and cleaning.
4. Output The initial state of the rooms. The actions taken by the vacuum cleaner.The
final state of the rooms. The total cost of actions (performance measurement).
PROGRAM:
def vacuum_world():
goal_state = {'A': '0', 'B': '0'}
cost = 0
location_input = input("Enter Location of Vacuum (A/B): ").upper() # Location of the vacuum
status_input = input(f"Enter status of {location_input} (0 for CLEAN, 1 for DIRTY): ") # Status of
the current location
status_input_complement = input(f"Enter status of the other room (0 for CLEAN, 1 for DIRTY):
") # Status of the other room
if location_input == 'A':
print("\nVacuum is placed in Location A.")
if status_input == '1':
print("Location A is Dirty.")
goal_state['A'] = '0' # Clean Location A
cost += 1 # Cost for cleaning
print(f"Cost for CLEANING A: {cost}")
print("Location A has been Cleaned.")
if status_input_complement == '1':
print("Location B is Dirty.")
print("Moving RIGHT to Location B.")
cost += 1 # Cost for moving right
print(f"COST for moving RIGHT: {cost}")
if status_input_complement == '1':
print("Location B is Dirty.")
print("Moving RIGHT to Location B.")
cost += 1 # Cost for moving right
print(f"COST for moving RIGHT: {cost}")
goal_state['B'] = '0' # Clean Location B
cost += 1 # Cost for cleaning
print(f"COST for SUCK: {cost}")
print("Location B has been Cleaned.")
else:
print("No action. Location B is already clean.")
if status_input == '1':
print("Location B is Dirty.")
goal_state['B'] = '0' # Clean Location B
cost += 1 # Cost for cleaning
print(f"COST for CLEANING B: {cost}")
print("Location B has been Cleaned.")
if status_input_complement == '1':
print("Location A is Dirty.")
print("Moving LEFT to Location A.")
cost += 1 # Cost for moving left
print(f"COST for moving LEFT: {cost}")
goal_state['A'] = '0' # Clean Location A
cost += 1 # Cost for cleaning
print(f"COST for SUCK: {cost}")
print("Location A has been Cleaned.")
else:
print("No action. Location A is already clean.")
elif status_input == '0':
print("Location B is already clean.")
if status_input_complement == '1':
else:
print("Invalid location entered. Please enter 'A' or 'B'.")
return
vacuum_world()
OUTPUT
AIM: Implement the production system and derive a solution for the real world Al problem.
(Suggested exercise: Write a program to solve the following problem: You have two jugs, a 4-
gallon and a 3-gallon. Neither of the jugs has markings on them. There is a pump that can be
used to fill the jugs with water. How can you get exactly two gallons of water in the 4-gallon
jug?).
DESCRIPTION:
1. States: Represented by the current amounts of water in the two jugs, e.g., (j1, j2).
4. Rules (Productions): Define the actions that can be performed on the jugs:
o Pour water from one jug to the other until the source jug is empty or the
destination jug is full.
PROGRAM:
while queue:
j1, j2, seq = queue.pop(0)
if (j1, j2) not in visited:
visited.add((j1, j2))
if j1 == targetAmount or j2 == targetAmount:
return seq
for action in actions:
if action[0] == "fill":
next_state = (jug1Cap, j2) if action[1] == 1 else (j1, jug2Cap)
elif action[0] == "empty":
next_state = (0, j2) if action[1] == 1 else (j1, 0)
else:
result = waterJugProblem(4, 3, 2)
print(result)
OUTPUT :
DESCRIPTION: The A* (A-star) algorithm is a powerful and versatile search method used
in computer science to find the most efficient path between nodes in a graph. Widely used in
a variety of applications ranging from pathfinding in video games to network routing and AI,
A* remains a foundational technique in the field of algorithms and artificial intelligence.
Working of A* Algorithm
The core of the A* algorithm is based on cost functions and heuristics. It uses two main
parameters:
1. g(n): The actual cost from the starting node to any node n.
2. h(n): The heuristic estimated cost from node n to the goal. This is where A* integrates
knowledge beyond the graph to guide the search.
The sum, f(n)=g(n)+h(n)f(n)=g(n)+h(n), represents the total estimated cost of the cheapest
solution through nnn. The A* algorithm functions by maintaining a priority queue (or open
set) of all possible paths along the graph, prioritizing them based on their fff values. The steps
of the algorithm are as follows:
1. Initialization: Start by adding the initial node to the open set with its f(n).
2. Loop: While the open set is not empty, the node with the lowest f(n) value is removed
from the queue.
3. Goal Check: If this node is the goal, the algorithm terminates and returns the
discovered path.
4. Node Expansion: Otherwise, expand the node (find all its neighbors), calculating g,
h, and f values for each neighbor. Add each neighbor to the open set if it's not already
present, or if a better path to this neighbor is found.
5. Repeat: The loop repeats until the goal is reached or if there are no more nodes in the
open set, indicating no available path.
PROGRAM:
while open_list:
f_cost, current, path = heappop(open_list)
if __name__ == "__main__":
graph = {
"A": [("B", 1), ("C", 3)],
"B": [("D", 1), ("E", 5)],
"C": [("E", 2)],
"D": [("F", 4)],
"E": [("F", 1)],
"F": [],
}
heuristic = {"A": 6, "B": 4, "C": 4, "D": 2, "E": 1, "F": 0}
start_node = "A"
goal_node = "F"
if path:
print(f"Path found: {path} with cost: {cost}")
else:
print("No path found.")
OUTPUT:
AIM: Implement the Constraint Specific Problem. (Suggested exercise: a crossword puzzle).
1. Variables: The things that need to be determined are variables. Variables in a CSP are
the objects that must have values assigned to them in order to satisfy a particular set
of constraints. Boolean, integer, and categorical variables are just a few examples of
the various types of variables, for instance, could stand in for the many puzzle cells
that need to be filled with numbers in a sudoku puzzle.
2. Domains: The range of potential values that a variable can have is represented by
domains. Depending on the issue, a domain may be finite or limitless. For instance, in
Sudoku, the set of numbers from 1 to 9 can serve as the domain of a variable
representing a problem cell.
3. Constraints: The guidelines that control how variables relate to one another are
known as constraints. Constraints in a CSP define the ranges of possible values for
variables. Unary constraints, binary constraints, and higher-order constraints are only
a few examples of the various sorts of constraints. For instance, in a sudoku problem,
the restrictions might be that each row, column, and 3×3 box can only have one
instance of each number from 1 to 9.
PROGRAM:
ways = 0
def print_matrix(matrix):
for row in matrix:
print(" ".join(row))
print()
for i in range(n):
for j in range(max_len + 1):
temp = check_vertical(j, i, matrix.copy(), current_word)
if temp[0] != "@":
solve_puzzle(words, temp, index + 1, n)
for i in range(n):
for j in range(max_len + 1):
temp = check_horizontal(i, j, matrix.copy(), current_word)
if temp[0] != "@":
solve_puzzle(words, temp, index + 1, n)
else:
print(f"{ways + 1} way to solve the puzzle")
print_matrix(matrix)
print()
ways += 1
if __name__ == "__main__":
n1 = 10
matrix = [
"##########",
"##########",
"######+###",
"#+####++##",
OUTPUT:
AIM: Implement the alpha-beta pruning. (Suggested exercise: for a tic toc game).
Alpha is the best value that the maximizer currently can guarantee at that level or above.
Beta is the best value that the minimizer currently can guarantee at that level or below.
EXAMPLE:
1) Initial Setup:
a) The algorithm starts at node A (the root, a maximizer).
b) Initial values: alpha = -INFINITY (for maximizer), beta = +INFINITY (for
minimizer).
2) Exploring Node B:
a) A calls B (a minimizer).
b) B calls D (a maximizer).
i) D evaluates its left child (leaf node) with value 3.
(1) alpha at D becomes max(-INF, 3) = 3.
(2) Since beta > alpha, D continues to evaluate its right child.
ii) D evaluates its right child (leaf node) with value 5.
(1) alpha at D becomes max(3, 5) = 5.
iii) D returns 5 to B.
c) B updates beta = min(+INF, 5) = 5.
d) B calls E to check for a better (lower) value.
i) E evaluates its left child (leaf node) with value 6.
(1) alpha at E becomes max(-INF, 6) = 6.
(2) Since beta (5) <= alpha (6), E prunes its right subtree and returns 6 to B.
e) B updates beta = min(5, 6) = 5.
f) B returns 5 to A.
3) Exploring Node C:
a) A calls C (a minimizer) to check for a better (higher) value.
b) C calls F (a maximizer).
i) F evaluates its left child (leaf node) with value 1.
(1) alpha at F remains max(5, 1) = 5.
ii) F evaluates its right child (leaf node) with value 2.
(1) alpha at F remains max(5, 2) = 5.
PROGRAM:
if maximizingPlayer:
best = MIn
# Recur for left and right children
for i in range(0, 2):
OUTPUT:
AIM: Design a planning system using STRIPS. (Suggested exercise: an elevator problem to
move a passenger from the 1st floor to the 4th floor in a building).
STRIPS is a formal language used for expressing planning problems and was originally
designed to control the actions of a robot in a manipulable environment. It is primarily
concerned with the automatic generation of plans, which are sequences of actions that
transition a system from its initial state to a desired goal state.
4. Search for Solutions: Using a strategy like backward chaining from the goal state to
the initial state, identifying actions that satisfy the goal conditions
PROGRAM:
import random
import time
class Building:
def __init__(self, floors, customers):
def run(self):
print("++++++++++++++++++++++++++ ELEVATOR IS NOW STARTING
+++++++++++++++")
print(f"There are {len(self.customer_list)} customers in the building")
self.output()
def output(self):
for customer in self.customer_list:
print(f"Customer {customer.customerID} is on floor {customer.current_floor} and
wants to go to {customer.destination_floor}")
# Elevator moving up
while self.elevator.current_floor < self.elevator.number_of_floors:
self.elevator.current_floor += 1
print("ELEVATOR MOVING UP")
print(f"{len(self.customer_list)} Customers in lift.")
print("++++++++++++++++++++++++++++++++++++++++++++++++++++")
print(f"FLOOR {self.elevator.current_floor}")
class Elevator:
def __init__(self, number_of_floors, register_list):
self.number_of_floors = number_of_floors
self.register_list = register_list
self.current_floor = 0
def move(self):
pass
def register_customer(self, customers):
for customer in customers:
self.register_list.append(customer)
class Customer:
def __init__(self, customerID, floors):
self.customerID = customerID
if __name__ == "__main__":
main()
OUTPUT:
AIM: Implement a single neural network and test for different logic gates.
DESCRIPTION:
1. Input Layer: This is where the network receives its input data. Each input neuron in
the layer corresponds to a feature in the input data.
2. Hidden Layers: These layers perform most of the computational heavy lifting. A
neural network can have one or multiple hidden layers. Each layer consists of units
(neurons) that transform the inputs into something that the output layer can use.
3. Output Layer: The final layer produces the output of the model. The format of these
outputs varies depending on the specific task (e.g., classification, regression).
PROGRAM:
import numpy as np
from matplotlib import pyplot as plt
# Sigmoid Function
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# Forward Propagation
def forward_propagation(X, Y, parameters):
m = X.shape[1]
W1 = parameters["W1"]
W2 = parameters["W2"]
b1 = parameters["b1"]
b2 = parameters["b2"]
Z1 = np.dot(W1, X) + b1
A1 = sigmoid(Z1)
# Backward Propagation
def backward_propagation(X, Y, cache):
m = X.shape[1]
Z1, A1, W1, b1, Z2, A2, W2, b2 = cache
dZ2 = A2 - Y
dW2 = np.dot(dZ2, A1.T) / m
db2 = np.sum(dZ2, axis=1, keepdims=True) / m
gradients = {"dZ2": dZ2, "dW2": dW2, "db2": db2, "dZ1": dZ1, "dW1": dW1, "db1":
db1}
return gradients
epoch = 100000
learning_rate = 0.01
losses = np.zeros((epoch, 1))
OUTPUT: