0% found this document useful (0 votes)
10 views43 pages

AI Lab File

The document is a lab report for an Artificial Intelligence course submitted by Eesha Singh at Thapar Institute of Engineering & Technology. It includes a detailed index of various Python programming experiments, covering topics such as recursion, array manipulation, matrix operations, and AI algorithms. Each experiment outlines the aim, theory, procedure, and code implementation, demonstrating practical applications of programming concepts.

Uploaded by

esingh1be22
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)
10 views43 pages

AI Lab File

The document is a lab report for an Artificial Intelligence course submitted by Eesha Singh at Thapar Institute of Engineering & Technology. It includes a detailed index of various Python programming experiments, covering topics such as recursion, array manipulation, matrix operations, and AI algorithms. Each experiment outlines the aim, theory, procedure, and code implementation, demonstrating practical applications of programming concepts.

Uploaded by

esingh1be22
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/ 43

Lab Report

UCS411
Artificial Intelligence
Sixth Semester

Submitted by: Eesha Singh (102205055)


3EI1
B.E Electronics (Instrumentation & Control)
(3rd Year)
Submitted to: Dr. Mukesh Singh

Department of Electrical & Instrumentation Engineering


Thapar Institute of Engineering & Technology
(Deemed to be University)
INDEX
Ex. No. Experiment Name Date Remark
1(a) Python program to find a given number's factorial using recursion 14-01-2025
taking input from the keyboard.
1(b) Python program to find the sum of two arrays. 14-01-2025
1(c) Python program to find the largest number in a given array. 14-01-2025
1(d) Python program to interchange the first and last elements in a list. 14-01-2025
1(e) Python program to add and multiply two matrices of 3X3. 14-01-2025
1(f) Python program to reverse a given string. 14-01-2025
1(g) Python program to split and join the string. 14-01-2025
2(a) WAP to Find the sum of the series (1 + x + x2/2! + . . . + x n/n!). 21-01-2025
Number x and n should be entered at run time.
2(b) WAP to create a list of 100 random numbers between 100 and 21-01-2025
900. Count and print the: (i) All odd numbers (ii) All even
numbers (iii)All prime numbers
2(c) WAP to find the prime numbers between two given numbers. 21-01-2025
2(d) WAP to Find the common elements from two lists. 21-01-2025
2(e) WAP to Print the leap years between any two years. The limit of 21-01-2025
the years should be entered at execution time.
Write a Python Program to input basic salary of an employee and 21-01-2025
2(f) calculate its Gross salary according to following: Basic Salary <=
10000 : HRA = 20%, DA = 80% Basic Salary <= 20000 : HRA =
25%, DA = 90% Basic Salary > 20000 : HRA = 30%, DA =95%.
Python program to check the validity of password input by users. 21-01-2025
2(g) Validation: At least 1 letter between [a-z] and 1 letter between [A-
Z];At least 1 number between [0-9]; At least 1 character from
[$#@]; Minimum length 6 characters; Maximum length 16
characters.
WAP to create a List L having data as= [10, 20, 30, 40, 50, 60, 70, 21-01-2025
2(h) 80]. (i) WAP to add 200 and 300 to L. (ii) WAP to remove 10 and
30 from L. (iii)WAP to sort L in ascending order. (iv) WAP to
sort L in descending order.
D is a dictionary defined as D= {1:”One”, 2:”Two”, 3:”Three”, 4: 21-01-2025
“Four”, 5:”Five”}. (i) WAP to add new entry in D; key=6 and
2(i) value is “Six” (ii) WAP to remove key=2.(iii)WAP to check if 6
key is present in D. (iv) WAP to count the number of elements
present in D. (v) WAP to add all the values present in D.
(i) Write a function which takes principal amount, interest rate and 21-01-2025
2(j) time. This function returns compound interest. Call this function
to print the output. (ii) Save this function (as a module) in a python
file and call it in another python file.
Explain how the PEAS framework is implemented in the given 28-01-2025
3 Vacuum Cleaner Agent program. Specifically, describe the roles
of sensors, actuators, environment, and performance measures in
the agent's functioning.
You are given a 4×4 chessboard, and your task is to place 4 queens 04-02-2025
on the board such that no two queens attack each other. Write a
4 Python program that uses backtracking to find a valid solution.
Your implementation should: 1. Use a recursive function to place
queens row by row. 2. Check for valid placements by ensuring no
two queens share the same column or diagonal. 3. Print one valid
solution where 'Q' represents a queen and '.' represents an empty
space. How would you modify the code to display all possible
solutions instead of just one?
Given two jugs- a 4 liters and 3 liters capacity. Neither has any 11-02-2025
5(a) measurable markers on it. There is a pump which can be used to
fill the jugs with water. Simulate the procedure in Python to get
exactly 2 liters of water into 4-liters jug (with simple steps).
Given two jugs- a 4 liters and 3 liters capacity. Neither has any 11-02-2025
5(b) measurable markers on it. There is a pump which can be used to
fill the jugs with water. Simulate the procedure in Python to get
exactly 2 liters of water into 4-litre jug (using BFS).
6 WAP in Python to implement Uniform Cost Search (UCS). 18-02-2025
To implement the Traveling Salesman Problem (TSP) to find the 25-03-2025
7 shortest possible route that visits all cities exactly once and returns
to the starting city.
8 Write a program to implement a block world problem using AI 08-04-2025
Planning.
9(a) WAP to implement a knowledge representation. 22-04-2025
9(b) WAP to implement a Logical representation. 22-04-2025
10(a) Write a program to implement crossover in genetic algorithm 29-04-2025
10(b) Write a program to implement crossover, mutation and selection 29-04-2025
in GA.
Experiment-01(a)

Aim: Write a python program to find a given number's factorial using recursion taking input from the
keyboard.
Software: VS Code
Theory: Factorial of a number is the product of all positive integers from 1 to that number and is denoted as
n!n!. It is defined mathematically as n!=n×(n−1)×(n−2)×...×1n! = n times (n-1) times (n-2) times ... times 1,
with the base cases being 0!=10! = 1 and 1!=11! = 1. In this experiment, we use recursion, a technique where
a function calls itself to solve a problem. The recursive function factorial(n) follows the logic that if n is 0 or
1, it returns 1, otherwise, it returns n× factorial(n−1)n times factorial(n-1). The program takes user input,
checks if the number is negative (as factorial is not defined for negative numbers), and then calculates the
factorial using recursion. Recursion simplifies the implementation, but for very large numbers, it may cause a
recursion depth error.
Procedure:
1. Open VS Code and create a new Python file (factorial.py).
2. Write the Code:
• Define a recursive factorial(n) function.
• Handle base cases (n == 0 or n == 1).
• Take user input, check for negatives, and compute factorial.
3. Save and Run:
4. Test with different inputs (positive, zero, negative)

Code:
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
number = int(input("Enter a number: "))
result = factorial(number)
print(f ' The factorial of {number} is {result}')

Output:
Experiment-01(b)

Aim: Write a python program to find the sum of two arrays.

Software: VS Code

Theory: This program defines a function add_arrays(arr1, arr2) that takes two lists as input and performs
element-wise addition. It first checks if both arrays have the same length since addition is only possible if their
sizes match. If they don’t, it prints an error message and returns None. Otherwise, it iterates through the lists,
adds corresponding elements, and stores the result in a new list. Finally, the function returns the summed list,
which is printed. This approach ensures accurate and efficient addition without using external libraries.

Procedure:
1. Open VS Code and create sum_arrays.py.
2. Define add_arrays(arr1, arr2), check lengths, and perform element-wise addition.
3. Save and run
4. Test with different inputs.

Code:

# Function to add two arrays


def add_arrays(arr1, arr2):
# Check if arrays have the same length
if len(arr1) != len(arr2):
print("Error: Arrays must have the same length.")
return None
# Element-wise addition
result = []
for i in range(len(arr1)):
result.append(arr1[i] + arr2[i])
return result
# Input arrays
arr1 = [1, 2, 3, 4]
arr2 = [5, 6, 7, 8]
# Call the function and print the result
sum_array = add_arrays(arr1, arr2)
if sum_array is not None:
print("The sum of the two arrays is:", sum_array)

Output:
Experiment-01(c)

Aim: Write a python program to find the largest number in a given array.

Software: VS Code

Theory: This program finds the largest number in a given array using a simple iterative approach. It initializes
the largest value with the first element of the array and then iterates through the remaining elements, updating
the largest value whenever a greater number is found. This method ensures efficient searching with a time
complexity of (O(n)), where (n) is the number of elements in the array. The program effectively determines
the maximum value without requiring additional memory, making it optimal for handling large datasets.

Procedure:
1. Initialize: Set the first element of the array as the largest number.
2. Iterate: Loop through each element in the array.
3. Compare & Update: If the current element is greater than the largest value, update it.
4. Return Result: After iterating through all elements, return the largest number.
5. Display Output: Print the largest number found in the array.

Code:

def find_largest(arr):
# Initialize the largest number with the first element of the array
largest = arr[0]
# Iterate through the array to find the largest number
for num in arr:
if num > largest:
largest = num
return largest
# Example usage
array = [8, 9, 7, 2, 3, 1, 4]
result = find_largest(array)
print("The largest number in the array is:", result)

Output:
Experiment-01(d)
Aim: Write a python program to interchange the first and last elements in a list.
Software: VS Code
Theory: This program swaps the first and last elements of a given list using direct indexing. It first checks if
the list is empty or has only one element, as swapping is unnecessary in such cases. If the list has at least two
elements, it exchanges the values at the first and last positions using simple assignment. This approach
efficiently modifies the list in-place with a constant time complexity of O(1), ensuring optimal performance
for element swapping.
Procedure:
1. Check List Length: If the list is empty or has only one element, return it as is.
2. Swap Elements: Exchange the first and last elements using indexing.
3. Return Result: Return the modified list.
4. Display Output: Print the updated list.

Code:
def interchange_first_last(arr):
# Check if the list is empty or has only one element
if len(arr) <= 1:
return arr
# Swap the first and last elements
arr[0], arr[-1] = arr[-1], arr[0]
return arr
# Example usage
array = [1, 2, 3, 4, 5]
result = interchange_first_last(array)
print("The list after interchanging the first and last elements is:", result)

Output:
Experiment-01(e)
Aim: Write a python program to add and multiply two matrices of 3X3.
Software: VS Code
Theory: This program performs addition and multiplication of two 3×3 matrices using nested loops. In matrix
addition, corresponding elements of both matrices are added to form a new matrix. In matrix multiplication,
each element in the resulting matrix is obtained by computing the dot product of the corresponding row from
the first matrix and the column from the second matrix. The program takes two 3×3 matrices as input,
processes them using loops, and stores the results in separate matrices for addition and multiplication. The
time complexity for both operations is O(n2)O(n^2) for addition and O(n3)O(n^3) for multiplication, ensuring
accurate matrix computations.
Procedure:
1. Input Matrices: Take user input for two 3×3 matrices.
2. Addition: Add corresponding elements and store them in a new matrix.
3. Multiplication: Compute the dot product of rows and columns to get the product matrix.
4. Display Results: Print both the sum and product matrices.

Code:
def add_matrices(matrix1, matrix2):
result = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(len(matrix1)):
for j in range(len(matrix1[0])):
result[i][j] = matrix1[i][j] + matrix2[i][j]
return result
def multiply_matrices(matrix1, matrix2):
result = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(len(matrix1)):
for j in range(len(matrix2[0])):
for k in range(len(matrix2)):
result[i][j] += matrix1[i][j] * matrix2[k][j]
return result
def input_matrix():
matrix = []
print("Enter the values for the 3x3 matrix:")
for i in range(3):
row = list(map(int, input().split()))
matrix.append(row)
return matrix
# Input matrices from the user
print("Input for Matrix 1:")
matrix1 = input_matrix()
print("Input for Matrix 2:")
matrix2 = input_matrix()
# Calculate sum and product
result_addition = add_matrices(matrix1, matrix2)
result_multiplication = multiply_matrices(matrix1, matrix2)
# Display results
print("The sum of the two matrices is:")
for row in result_addition:
print(row)
print("The product of the two matrices is:")
for row in result_multiplication:
print(row)

Output:
Experiment-01(f)
Aim: Write a python program to reverse a given string.
Software: VS Code
Theory: This program splits a string into a list of words using a specified delimiter and then joins the words
back into a single string using a chosen separator. The `split()` method divides the string based on the delimiter,
while the `join()` method concatenates the list elements with a specified separator. These operations are
commonly used in text processing, data formatting, and string manipulation, with a time complexity of (O(n)),
where (n) is the length of the string.
Procedure:
1. Input String: Take a string as input.
2. Reverse: Use slicing ([::-1]) to reverse the string.
3. Display Result: Print the reversed string.

Code:
def reverse_string(s):
return s[::-1]
# Example usage
input_string = input("Enter a string: ")
reversed_string = reverse_string(input_string)
print("The reversed string is:", reversed_string)

Output:
Experiment-01(g)
Aim: Write a python program to split and join the string.
Software: VS Code
Theory: This program splits a string into a list of words using the split() method and then joins them back
into a single string using the join() method with a specified separator. These operations are useful for text
processing, data manipulation, and formatting. The time complexity for both operations is O(n), where n is
the length of the string.
Procedure:
1. Input String: Take a string as input.
2. Split: Use split() to divide the string into a list of words.
3. Join: Use join() to merge the words into a single string.
4. Display Results: Print the list of words and the joined string

Code:
def split_and_join_string(s):
# Split the string into a list of words
words = s.split()
# Join the list of words back into a single string
joined_string = ' '.join(words)
return words, joined_string
input_string = input("Enter a string: ")
words, joined_string = split_and_join_string(input_string)
print("The list of words is:", words)
print("The joined string is:", joined_string)

Output:
Experiment-02(a)

Aim: Find the sum of the series (1 + x + x2/2! + . . . + xn/n!). Number x and n should be entered at run time.

Software: VS Code

Theory: This program calculates the sum of the given series, which represents the Maclaurin series expansion
of e^x truncated at n terms. The series involves computing factorials in the denominator, which can be done
iteratively. The sum is calculated dynamically using a loop, where each term is obtained by dividing x^i by i!.
The user provides the values of x (the exponent) and n (the number of terms) at runtime, and the program
iterates to compute the sum accordingly. This approach efficiently approximates the exponential function for
any given input values.

Procedure:
1. Input Values: Accept x (exponent) and n (number of terms) from the user.
2. Compute Factorial: Use a function to calculate factorial iteratively or recursively.
3. Calculate Series Sum: Use a loop to compute each term of the series and add it to the sum.
4. Display Result: Print the final computed sum.

Code:
def factorial(num):
if num == 0 or num == 1:
return 1
else:
return num * factorial(num - 1)
def calculate_series_sum(x, n):
series_sum = 1 # Initialize the series sum with the first term (1)
for i in range(1, n + 1):
series_sum += (x ** i) / factorial(i)
return series_sum
def main():
x = float(input("Enter the value of x: "))
n = int(input("Enter the value of n: "))
result = calculate_series_sum(x, n)
print(f"The sum of the series for x = {x} and n = {n} is: {result}")
if __name__ == "__main__":
main()

Output:
Experiment-02(b)

Aim: WAP to create a list of 100 random numbers between 100 and 900. Count and print the:
(i) All odd numbers
(ii) All even numbers
(iii)All prime numbers

Software: VS Code

Theory: This program generates a list of 100 random numbers between 100 and 900 and then categorizes
them into odd, even, and prime numbers. Random numbers are generated using the `random.randint()`
function. Odd and even numbers are identified using the modulus operator (`%`), where numbers divisible by
2 are even, and the rest are odd. Prime numbers are determined by checking divisibility from 2 to the square
root of the number. The program then counts and prints the total number of odd, even, and prime numbers
from the generated list.

Procedure:
1. Generate Numbers: Create a list of 100 random numbers between 100 and 900 using random.randint().
2. Identify Odd and Even Numbers: Use modulus (% 2) to separate odd and even numbers.
3. Check for Prime Numbers: Use a function to test divisibility from 2 to √num.
4. Display Results: Print the odd, even, and prime numbers along with their counts.

Code:

import random
def is_prime(num):
if num < 2:
return False
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return True
def main():
# Generate a list of 100 random numbers between 100 and 900
random_numbers = [random.randint(100, 900) for _ in range(100)]
print("Random Numbers:", random_numbers)
# Count and print all odd numbers
odd_numbers = [num for num in random_numbers if num % 2 != 0]
print("\nOdd Numbers:", odd_numbers)
print("Count of Odd Numbers:", len(odd_numbers))
# Count and print all even numbers
even_numbers = [num for num in random_numbers if num % 2 == 0]
print("\nEven Numbers:", even_numbers)
print("Count of Even Numbers:", len(even_numbers))
# Count and print all prime numbers
prime_numbers = [num for num in random_numbers if is_prime(num)]
print("\nPrime Numbers:", prime_numbers)
print("Count of Prime Numbers:", len(prime_numbers))
if __name__ == "__main__":
main()

Output:
Experiment-02(c)

Aim: Find the prime numbers between two given numbers.

Software: VS Code

Theory: This program finds all prime numbers between two user-inputted numbers. A prime number is
defined as a number greater than 1 that has no divisors other than 1 and itself. The program iterates through
the range of numbers between the given inputs and checks each number for primality. Primality is determined
by verifying that the number is not divisible by any integer from 2 to its square root. If a number meets this
condition, it is considered prime and added to the list of prime numbers, which is then printed as output.

Procedure:
1. Input Range: Take two numbers as input from the user (start and end).
2. Check for Prime Numbers: Iterate through the given range and check if each number is prime.
3. Primality Test: A number is prime if it is not divisible by any integer from 2 to √num.
4. Store and Display Results: Add prime numbers to a list and print them.

Code:

def is_prime(num):
if num < 2:
return False
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return True
def find_primes_between(start, end):
prime_numbers = []
for num in range(start, end + 1):
if is_prime(num):
prime_numbers.append(num)
return prime_numbers
def main():
start = int(input("Enter the start number: "))
end = int(input("Enter the end number: "))
prime_numbers = find_primes_between(start, end)
print(f"Prime numbers between {start} and {end} are:", prime_numbers)
if __name__ == "__main__":
main()

Output:
Experiment-02(d)

Aim: Find the common elements from two lists.

Software: VS Code

Theory: This program finds the common elements between two user-defined lists. It takes two lists as input
and compares their elements to identify duplicates. The common elements can be determined using loops,
list comprehension, or set operations. Using sets (set(list1) & set(list2)) is the most efficient approach, as it
eliminates duplicates and allows quick intersection computation. Finally, the program prints the list of
common elements.

Procedure:
1. Convert both lists to sets.
2. Find common elements using set intersection.
3. Convert the result to a list and return it.
4. Take user input, call the function, and print the result

Code:

def find_common_elements(list1, list2):


# Convert lists to sets to find common elements
set1 = set(list1)
set2 = set(list2)
# Find the intersection of the two sets
common_elements = set1.intersection(set2)
return list(common_elements)
def main():
# Sample lists
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
common_elements = find_common_elements(list1, list2)
print("Common elements:", common_elements)
if __name__ == "__main__":
main()

Output:
Experiment-02(e)

Aim: Print the leap years between any two years. The limit of the years should be entered at execution time.

Software: VS Code

Theory: This program finds and prints all leap years between two user-inputted years. A leap year is a year
that is divisible by 4, but if it is a century year (divisible by 100), it must also be divisible by 400. The
program iterates through the given range of years, checks each year against these conditions, and prints the
ones that qualify as leap years.

Procedure:
1. Take user input for the start and end year.
2. Check each year in the range using leap year conditions:
3. Divisible by 4 and not by 100, or divisible by 400.
4. Store and print all leap years in the given range.

Code:

def is_leap_year(year):
# Check if a year is a leap year
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
return True
return False
def find_leap_years(start_year, end_year):
leap_years = []
for year in range(start_year, end_year + 1):
if is_leap_year(year):
leap_years.append(year)
return leap_years
def main():
start_year = int(input("Enter the start year: "))
end_year = int(input("Enter the end year: "))
leap_years = find_leap_years(start_year, end_year)
print(f"Leap years between {start_year} and {end_year} are:", leap_years)
if __name__ == "__main__":
main()

Output:
Experiment-02(f)

Aim: Write a Python Program to input basic salary of an employee and calculate its Gross salary according
to following: Basic Salary <= 10000 : HRA = 20%, DA = 80% Basic Salary <= 20000 : HRA = 25%, DA =
90% Basic Salary > 20000 : HRA = 30%, DA = 95%.

Software: VS Code

Theory: This program calculates the Gross Salary of an employee based on the given conditions for House
Rent Allowance (HRA) and Dearness Allowance (DA). The user inputs the basic salary, and the program
determines the applicable HRA and DA percentages based on predefined salary ranges. HRA and DA are then
computed as a percentage of the basic salary, and the Gross Salary is obtained using the formula:
{Gross Salary} = {Basic Salary} + {HRA} + {DA}
The program then prints the calculated Gross Salary.

Procedure:
1. Take user input for the basic salary.
2. Determine HRA and DA based on salary range.
3. Calculate Gross Salary:
Gross Salary=Basic Salary+HRA+DA
4. Display the calculated Gross Salary.

Code:

def calculate_gross_salary(basic_salary):
if basic_salary <= 10000:
hra = 0.20 * basic_salary
da = 0.80 * basic_salary
elif basic_salary <= 20000:
hra = 0.25 * basic_salary
da = 0.90 * basic_salary
else:
hra = 0.30 * basic_salary
da = 0.95 * basic_salary
gross_salary = basic_salary + hra + da
return gross_salary
def main():
basic_salary = float(input("Enter the basic salary of the employee: "))
gross_salary = calculate_gross_salary(basic_salary)
print(f"The Gross Salary of the employee is: {gross_salary:.2f}")
if __name__ == "__main__":
main()

Output:
Experiment-02(g)

Aim: Write a Python program to check the validity of password input by users.
Validation:
• At least 1 letter between [a-z] and 1 letter between [A-Z].
• At least 1 number between [0-9].
• At least 1 character from [$#@].
• Minimum length 6 characters.
• Maximum length 16 characters.

Software: VS Code

Theory: This program validates a user's password based on specific security criteria. The input password must
contain at least one lowercase letter ([a-z]), one uppercase letter ([A-Z]), one digit ([0-9]), and at least one
special character from the set ($#@). Additionally, the password length must be between 6 and 16 characters.
The program checks these conditions using loops or regular expressions and prints whether the password is
valid or not.

Procedure:
1. Take user input for the password.
2. Check if the password meets length (6-16 characters) and required characters (lowercase, uppercase, digit,
special character $#@).
3. Print "Password is valid." if all conditions are met, otherwise "Password is invalid.

Code:

import re
def validate_password(password):
# Check if the password length is between 6 and 16 characters
if len(password) < 6 or len(password) > 16:
return False
# Check for at least 1 letter between [a-z]
if not re.search("[a-z]", password):
return False
# Check for at least 1 letter between [A-Z]
if not re.search("[A-Z]", password):
return False
# Check for at least 1 number between [0-9]
if not re.search("[0-9]", password):
return False
# Check for at least 1 character from [$#@]
if not re.search("[$#@]", password):
return False
# If all conditions are met
return True
def main():
password = input("Enter the password: ")
if validate_password(password):
print("Password is valid.")
else:
print("Password is invalid. Please ensure it meets the required criteria.")
if __name__ == "__main__":
main()

Output:
Experiment-02(h)

Aim: Create a List L having data as= [10, 20, 30, 40, 50, 60, 70, 80].
(i) WAP to add 200 and 300 to L.
(ii)WAP to remove 10 and 30 from L.
(iii)WAP to sort L in ascending order.
(iv) WAP to sort L in descending order

Software: VS Code

Theory: This program performs various operations on the given list `L = [10, 20, 30, 40, 50, 60, 70, 80]`. To
add `200` and `300` to the list, the values are placed at the end of the existing list. To remove `10` and `30`,
the program locates these values in the list and eliminates them. Sorting in ascending order involves
arranging the elements from the smallest to the largest, while sorting in descending order arranges them
from the largest to the smallest. Each modification updates the list accordingly, and the final results are
displayed after performing all operations.
Procedure:
1. Initialize List: Create list L = [10, 20, 30, 40, 50, 60, 70, 80].
2. Add Elements: Append 200 and 300.
3. Remove Elements: Delete 10 and 30.
4. Sort List:
• Ascending Order using sort().
• Descending Order using sort(reverse=True).
5. Print Results.

Code:

L = [10, 20, 30, 40, 50, 60, 70, 80]


print("Original List:", L)
L.append(200)
L.append(300)
print("List after adding 200 and 300:", L)
L.remove(10)
L.remove(30)
print("List after removing 10 and 30:", L)
L.sort()
print("List sorted in ascending order:", L)
L.sort(reverse=True)
print("List sorted in descending order:", L)

Output:
Experiment-02(i)

Aim: D is a dictionary defined as D= {1:”One”, 2:”Two”, 3:”Three”, 4: “Four”, 5:”Five”}.


(i) WAP to add new entry in D; key=6 and value is “Six”
(ii)WAP to remove key=2.
(iii)WAP to check if 6 key is present in D.
(iv) WAP to count the number of elements present in D.
(v) WAP to add all the values present in D.

Software: VS Code

Theory: This program performs various operations on the dictionary D = {1: "One", 2: "Two", 3: "Three",
4: "Four", 5: "Five"}. To add a new entry with key 6 and value "Six", the key-value pair is directly assigned
to the dictionary. Removing the key 2 is done by locating and deleting the specific key-value pair. Checking
for the presence of key 6 involves verifying whether it exists in the dictionary. Counting the number of
elements is achieved by determining the total number of key-value pairs. Finally, adding all the values refers
to concatenating the string values stored in the dictionary.

Procedure:
1. Initialize Dictionary: D = {1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five"}
2. Add Entry: D[6] = "Six"
3. Remove Entry: del D[2]
4. Check Key Presence: print(6 in D)
5. Count Elements: print(len(D))
6. Concatenate Values: print("".join(D.values()))
7. Print Final Dictionary.

Code:

D = {1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five"}


D[6] = "Six"
if 2 in D:
del D[2]
key_to_check = 6
is_present = key_to_check in D
print(f"Is key {key_to_check} present: {is_present}")
element_count = len(D)
print(f"Number of elements in the dictionary: {element_count}")
all_values = "".join(D.values())
print(f"Concatenated values: {all_values}")
print(f"Final dictionary: {D}")

Output:
Experiment-02(j)

Aim: (i) Write a function which takes principal amount, interest rate and time. This function returns
compound interest. Call this function to print the output.
(ii) Save this function (as a module) in a python file and call it in another python file.

Software: VS Code

Theory: This program calculates compound interest using a function that takes the principal amount,
interest rate, and time as input and returns the computed interest. The compound interest formula used is:
A=P*(1+r/100)^t
where A is the final amount, P is the principal amount, r is the interest rate, and tt is the time in years. The
compound interest is obtained by subtracting P from A.
To modularize the function, it is saved in a separate Python file (module) and then imported into another
Python script for execution. This approach promotes reusability and better code organization.

Procedure:
𝑟 𝑡
1. Create Function: Define calculate_ci(p, r, t) using the formula: 𝐶𝐼 = 𝑃 (1 + 100) − 𝑃 and save it in
interest.py.
2. Import & Use: In main.py, import the function using: from interest import calculate_ci and Call it with
sample values and print the result.
3. Run main.py to compute compound interest.

Code:

1. Write the Function


def calculate_compound_interest(principal, rate, time):
amount = principal * (1 + rate/100) ** time
compound_interest = amount - principal
return compound_interest
principal = 1000
rate = 5
time = 2
ci = calculate_compound_interest(principal, rate, time)
print(f"The compound interest is: {ci}")

2. Save the Function as a Module


def calculate_compound_interest(principal, rate, time):
amount = principal * (1 + rate/100) ** time
compound_interest = amount - principal
return compound_interest

3. Call the Function from Another Python File


from intrest_module import calculate_compound_interest
principal = 1000
rate = 5
time = 2
ci = calculate_compound_interest(principal, rate, time)
print(f"The compound interest is: {ci}")

Output:
Experiment-03

Aim: Explain how the PEAS framework is implemented in the given Vacuum Cleaner Agent program.
Specifically, describe the roles of sensors, actuators, environment, and performance measures in the agent's
functioning.

Software: VS Code

Theory:
1. Performance: The performance is tracked using a score. Cleaning a room increases the score, while moving
between rooms incurs a small penalty.
2. Environment: The agent interacts with a simple environment consisting of two rooms, each of which can
be "Dirty" or "Clean."
3. Actuators: The agent can "Clean" a room or "Move" between rooms.
4. Sensors: The agent senses the current state of both rooms.

Procedure:
1. Initialize Agent: Set up two dirty rooms and a performance score.
2. Sense: Check room cleanliness.
3. Decide (think()): If a room is dirty, clean it; else, stop.
4. Act (actuators()): Clean (+10 points) or move (-1 point).
5. Run (run()): Repeat sense-think-act until all rooms are clean.
6. Execute: Instantiate the agent and start.

Code:

class VacuumCleanerAgent:
def __init__(self):
# Initialize the state of the environment
self.environment = {"RoomA": "Dirty", "RoomB": "Dirty"}
self.performance = 0 # Performance measure
def sensors(self):
# Sense the state of the rooms
return self.environment
def actuators(self, action, room):
# Perform actions to clean or move
if action == "Clean":
if self.environment[room] == "Dirty":
self.environment[room] = "Clean"
self.performance += 10 # Reward for cleaning
elif action == "Move":
self.performance -= 1 # Penalty for movement
def think(self):
# Simple reflex agent logic
for room in self.environment:
if self.environment[room] == "Dirty":
return "Clean", room
return "NoOp", None
def run(self):
# Main loop to execute the agent's decisions
while True:
# Sense the environment
env_state = self.sensors()
print(f"Environment: {env_state}")
# Think and decide on the action
action, room = self.think()
if action == "NoOp":
print("All rooms are clean. Stopping agent.")
break
# Act based on the decision
print(f"Action: {action} in {room}")
self.actuators(action, room)
# Instantiate and run the agent
agent = VacuumCleanerAgent()
agent.run()
# Final performance measure
print(f"Final Performance: {agent.performance}")

Output:
Experiment-04

Aim: You are given a 4×4 chessboard, and your task is to place 4 queens on the board such that no two queens
attack each other. Write a Python program that uses backtracking to find a valid solution. Your implementation
should:
1. Use a recursive function to place queens row by row.
2. Check for valid placements by ensuring no two queens share the same column or diagonal.
3. Print one valid solution where 'Q' represents a queen and '.' represents an empty space. How would you
modify the code to display all possible solutions instead of just one?

Software: VS Code

Theory:

1. State Definition: The board state is represented as a 4×4 grid, where:


• 1 represents a queen.
• 0 represents an empty space.
2. Constraints: A queen cannot be placed in:
• The same column.
• The same diagonal.
3. Backtracking Approach:
• Try placing a queen row by row.
• If a valid position is found, move to the next row.
• If no valid position is found, backtrack (remove the last placed queen) and try the next column.
4. Solution Output: If a valid configuration is found, it prints the board with 'Q' for queens and '.' for empty
spaces.

Procedure:
1. Check Safety (is_safe) – Ensure no two queens attack each other.
2. Backtracking (solve_nqueens) – Place queens row by row, backtracking if needed.
3. Store & Print Solutions – Save valid boards and display them.
4. Run (main) – Initialize the board, solve, and print all solutions.

Code:

def is_safe(board, row, col):


# Check column
for i in range(row):
if board[i][col] == 'Q':
return False
# Check upper left diagonal
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 'Q':
return False
# Check upper right diagonal
for i, j in zip(range(row, -1, -1), range(col, len(board), 1)):
if board[i][j] == 'Q':
return False
return True
def solve_nqueens(board, row, solutions):
if row >= len(board):
solutions.append([''.join(row) for row in board])
return
for col in range(len(board)):
if is_safe(board, row, col):
board[row][col] = 'Q'
solve_nqueens(board, row + 1, solutions)
board[row][col] = '.'
def print_board(board):
for row in board:
print(' '.join(row))
print() # Add an empty line between solutions
def main():
N=4
board = [['.' for _ in range(N)] for _ in range(N)]
solutions = []
solve_nqueens(board, 0, solutions)
print(f"Found {len(solutions)} solutions:")
for solution in solutions:
print_board(solution)
if __name__ == "__main__":
main()

Output:
Experiment-05(a)

Aim: Given two jugs- a 4 litre and 3 litre capacity. Neither has any measurable markers on it. There is a
pump which can be used to fill the jugs with water. Simulate the procedure in Python to get exactly 2 litre of
water into 4-litre jug (with simple steps).

Software: VS Code

Theory: This program simulates the water jug problem using a step-by-step approach to measure exactly 2
litres in a 4-liter jug. The process involves filling, transferring, and emptying water between a 4-liter and a 3-
liter jug while maintaining the allowed operations. The algorithm follows a systematic sequence of pouring
and refilling to reach the target state efficiently. This problem is a classic example of using the Greedy
Algorithm and State Space Search techniques, demonstrating problem-solving using logical operations with a
time complexity of O(1)O(1), as the number of steps is fixed.

Procedure:
1. Initialize jugs – Start with both jugs empty.
2. Fill and transfer – Use the 4L jug to fill the 3L jug and empty it as needed.
3. Repeat steps – Continue filling, transferring, and emptying until 2L remains in the 4L jug.
4. Print steps – Track and display each step to reach the target state.

Code:
def water_jug_problem():
x, y = 0, 0 # Initial state: both jugs are empty
target = 2 # Goal: Get 2 liters in the 4-liter jug
steps = []
# Step-by-step process
steps.append((x, y))
x = 4 # Fill the 4L jug
steps.append((x, y))
y = 3 # Pour water from 4L to 3L jug (until it is full)
x -= 3
steps.append((x, y))
y = 0 # Empty 3L jug
steps.append((x, y))
y = x # Pour remaining 1L from 4L to 3L jug
x=0
steps.append((x, y))
x = 4 # Fill the 4L jug again
steps.append((x, y))
x -= (3 - y) # Pour water into 3L jug until full
y=3
steps.append((x, y))
y = 0 # Empty 3L jug
steps.append((x, y))
# Now, x will have 2 liters, which is the target
steps.append((x, y))
return steps
# Run and print solution
solution_steps = water_jug_problem()
for step in solution_steps:
print(step)

Output:
Experiment-05(b)

Aim: Given two jugs- a 4 litre and 3 litre capacity. Neither has any measurable markers on it. There is a
pump which can be used to fill the jugs with water. Simulate the procedure in Python to get exactly 2 litre of
water into 4-litre jug (using BFS).

Software: VS Code

Theory: This program solves the Water Jug Problem using Breadth-First Search (BFS) to find the shortest
sequence of steps to get exactly 2 liters in a 4-liter jug. The algorithm starts with both jugs empty and
explores all possible valid states by filling, emptying, or transferring water between the jugs. A queue is used
to track visited states, ensuring an optimal solution without revisiting the same states. A parent dictionary is
maintained to backtrack and reconstruct the solution path. The BFS approach guarantees finding the shortest
path to the target state, making it an efficient and systematic method for solving such constraint-based
problems.

Procedure:

1. Define Problem: Use a 4L and 3L jug with no markers to measure exactly 2L in the 4L jug.
2. Allowed Operations:
• Fill: 4L or 3L jug.
• Empty: 4L or 3L jug.
• Pour: Transfer water between jugs without overflowing.
3. BFS Approach:
• Start from (0, 0) (both jugs empty).
• Use a queue to track states and a visited set to avoid repetition.
• Store parent states to reconstruct the shortest path.
4. Find Solution:
• Explore all possible states using BFS.
• If (2, y) is reached in the 4L jug, backtrack to get steps.
• If no solution, return "No solution found".
Code:

from collections import deque


def water_jug_bfs():
# Initial state (0, 0) meaning both jugs are empty
start_state = (0, 0)
target = 2 # We need 2 liters in the 4-liter jug
# Queue for BFS with initial state
queue = deque([start_state])
visited = set()
visited.add(start_state)
# Parent dictionary to track steps
parent = {start_state: None}
while queue:
x, y = queue.popleft()
# If the goal is reached, backtrack to find the solution steps
if x == target:
steps = []
while (x, y) is not None:
steps.append((x, y))
prev_state = parent[(x, y)]
if prev_state is None:
break # Stop when reaching the initial state
(x, y) = prev_state # Move to the previous state
steps.reverse()
return steps
# Possible next states
next_states = set([
(4, y), # Fill 4L jug
(x, 3), # Fill 3L jug
(0, y), # Empty 4L jug
(x, 0), # Empty 3L jug
(max(x - (3 - y), 0), min(y + x, 3)), # Pour 4L -> 3L
(min(x + y, 4), max(y - (4 - x), 0)) # Pour 3L -> 4L ])
for state in next_states:
if state not in visited:
queue.append(state)
visited.add(state)
parent[state] = (x, y)
return "No solution found"
# Run the simulation
solution_steps = water_jug_bfs()
if isinstance(solution_steps, list):
for step in solution_steps:
print(step)
else:
print(solution_steps)

Output:
Experiment-06

Aim: WAP in Python to implement Uniform Cost Search (UCS).

Software: VS Code

Theory: Uniform Cost Search (UCS) is a graph search algorithm that finds the least-cost path from a source
node to a goal node in a weighted graph. Unlike Depth First Search (DFS) or Breadth First Search (BFS),
UCS considers the cost of reaching a node rather than just the number of edges. It expands nodes in the
order of their cumulative cost from the start node, using a priority queue (min-heap) to always explore the
least-cost node first.

Procedure:
1. Initialize a priority queue with the start node (cost = 0) and an empty path.
2. While the queue is not empty:
• Extract the node with the lowest cost.
• If it is the goal, return the path.
• If not visited, mark it visited and explore its neighbours:
o Push neighbours into the queue with updated cost and path.
3. If the goal is not found, return "Goal not reachable".

Code:

def uniform_cost_search(graph, start, goal):


visited = set()
queue = [(0, start, [])] # (cost, node, path)
while queue:
cost, node, path = heapq.heappop(queue)
if node == goal:
return path + [node]
if node not in visited:
visited.add(node)
for neighbor, edge_cost in graph[node].items():
heapq.heappush(queue, (cost + edge_cost, neighbor, path + [node]))
return None # Goal not reachable
# Example graph represented as an adjacency list
graph = {
'A': {'B': 4, 'C': 3},
'B': {'C': 1, 'D': 5},
'C': {'D': 8},
'D': {'E': 2},
'E': {}
}
start_node = 'A'
goal_node = 'E'
result = uniform_cost_search(graph, start_node, goal_node)
if result:
print("Path from", start_node, "to", goal_node, ":", result)
else:
print("Goal", goal_node, "not reachable from", start_node)

Output:
Experiment-07

Aim: To implement the Traveling Salesman Problem (TSP) to find the shortest possible route that visits all
cities exactly once and returns to the starting city.

Software: VS Code

Theory: The Traveling Salesman Problem (TSP) is a combinatorial optimization problem where a salesman
must visit all cities with the shortest total distance. The brute-force approach generates all possible city
orderings (permutations) and selects the one with the minimum travel distance. This ensures the optimal
solution but has O(n!) time complexity, making it inefficient for large inputs.

Procedure:

1. Define the distance matrix representing the distances between cities.


2. Generate all possible city orders (permutations).
3. For each order, calculate the total travel distance (including return to the starting city).
4. Track the order with the minimum distance.
5. Return the best order and minimum distance.

Code:

from sys import maxsize


from itertools import permutations
def calculate_total_distance(order, distances):
total_distance = 0
for i in range(len(order) - 1):
total_distance += distances[order[i]][order[i+1]]
total_distance += distances[order[-1]][order[0]] # Return to the starting city
return total_distance
def traveling_salesman_bruteforce(distances):
num_cities = len(distances)
all_possible_orders = permutations(range(num_cities))
min_distance = float('inf')
best_order = None
for order in all_possible_orders:
total_distance = calculate_total_distance(order, distances)
if total_distance < min_distance:
min_distance = total_distance
best_order = order
return best_order, min_distance
# Example distance matrix (4 cities)
distances =
[
[0, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 30, 0]
]
best_order, min_distance = traveling_salesman_bruteforce(distances)
print(f"Best order: {best_order}")
print(f"Minimum distance: {min_distance}")

Output:
Experiment-08

Aim: Write a program to implement a block world problem using AI Planning.

Software Used: VS Code

Theory: The Block World problem is a classic AI planning task where blocks are stacked on a table and the
goal is to reach a desired configuration using legal operations like pick-up, put-down, stack, and unstack. It
involves state-space search and is typically solved using STRIPS-like operators in AI planning. The aim is to
minimize actions while transforming the initial state into the goal state.

Procedure:
1. Define initial and goal state.
2. List actions (pick-up, put-down, stack, unstack) with preconditions and effects.
3. Use Forward Search or Backward Search to reach the goal state.
4. Use planning algorithm like DFS, BFS, or A* to find the sequence of actions.

Code:

class Block:
def __init__(self, name):
self.name = name
self.on_top_of = None
def stack_on(self, other_block):
self.on_top_of = other_block
def unstack(self):
self.on_top_of = None
def __str__(self):
return self.name
class BlockWorld:
def __init__(self):
self.blocks = {}
def add_block(self, block):
self.blocks[block.name] = block
def remove_block(self, block_name):
if block_name in self.blocks:
del self.blocks[block_name]
def stack_blocks(self, block_name, on_top_of_name):
if block_name in self.blocks and on_top_of_name in self.blocks:
self.blocks[block_name].stack_on(self.blocks[on_top_of_name])
def unstack_block(self, block_name):
if block_name in self.blocks:
self.blocks[block_name].unstack()
def print_world_state(self):
print("Current World State:")
for block_name, block in self.blocks.items():
print(block_name, "is on top of", block.on_top_of if block.on_top_of else "the table")
# Example usage:
block_world = BlockWorld()
# Adding blocks to the world
block_world.add_block(Block("A"))
block_world.add_block(Block("B"))
block_world.add_block(Block("C"))
# Stack blocks
block_world.stack_blocks("B", "A")
block_world.stack_blocks("C", "B")
# Print world state
block_world.print_world_state()

Output:
Experiment-09(a)

Aim: WAP to implement a knowledge representation.

Software Used: VS Code

Theory: Knowledge Representation (KR) is a method used in AI to represent real-world information in a form
that a computer can understand and reason about. It includes facts, rules, and relationships using structures
like semantic networks, frames, or predicate logic. KR helps machines make intelligent decisions based on
stored knowledge.

Procedure:
1. Choose a representation method (e.g., rules, semantic network).
2. Define facts and relationships.
3. Implement logic for inference or querying.
4. Use the system to answer or deduce new facts.

Code:

class KnowledgeGraph:
def __init__(self):
self.graph = {}
def add_relation(self, entity1, relation, entity2):
if entity1 not in self.graph:
self.graph[entity1] = {}
if relation not in self.graph[entity1]:
self.graph[entity1][relation] = []
self.graph[entity1][relation].append(entity2)
def get_relations(self, entity):
if entity in self.graph:
return self.graph[entity]
else:
return {}
# Creating a knowledge graph instance
kg = KnowledgeGraph()
# Adding some relations to the knowledge graph
kg.add_relation("Cat", "is_a", "Animal")
kg.add_relation("Dog", "is_a", "Animal")
kg.add_relation("Animal", "has_property", "Can_move")
# Retrieving relations for a specific entity
print("Relations for Cat:", kg.get_relations("Cat"))

Output:
Experiment-09(b)

Aim: WAP to represent Logical representation.

Software Used: VS Code

Theory: Logical representation in AI uses formal logic (like propositional or first-order logic) to represent
facts and rules about the world. It allows reasoning through logical inference. Statements are represented as
symbols, and conclusions are derived using rules like modus ponens.

Procedure:
1. Define facts and rules using propositional or predicate logic.
2. Apply inference rules to derive new facts.
3. Implement logic in code to simulate deduction.
4. Output conclusions based on given conditions.

Code:
from sympy import symbols, Implies, Not, And, Or
from sympy.logic.boolalg import to_cnf
# Define propositional symbols
R, W = symbols('R W')
# Represent the statements using logical operators
statement1 = Implies(R, W) # If R, then W
statement2 = Implies(Not(R), Not(W)) # If not R, then not W
statement3 = R # R
# Combine all statements into a single logical expression
all_statements = And(statement1, statement2, statement3)
# Convert the logical expression to conjunctive normal form (CNF)
cnf_form = to_cnf(all_statements)
# Print the CNF representation
print("CNF representation:", cnf_form)

Output:
Experiment-10(a)

Aim: Write a program to implement crossover in genetic algorithm

Software: VS Code

Theory: Crossover is a genetic algorithm operator used to combine the genetic information of two parent
solutions to generate new offspring. It simulates biological reproduction and plays a crucial role in exploring
the search space. The most common types are single-point, two-point, and uniform crossover. This enhances
the solution diversity and helps the algorithm converge towards an optimal solution.

Procedure:
1. Select two parent chromosomes from the population.
2. Choose a crossover point (for single-point crossover).
3. Swap the genetic material after the crossover point between parents to create two new offspring.
4. Replace the old population or add the new offspring based on the selection criteria.

Code:
import random
def crossover(parent1, parent2):
crossover_point = random.randint(0, len(parent1) - 1)
offspring = parent1[:crossover_point] + parent2[crossover_point:]
return offspring
parent1 = [1, 2, 3, 4, 5]
parent2 = [6, 7, 8, 9, 10]
offspring = crossover(parent1, parent2)
print("Parent 1:", parent1)
print("Parent 2:", parent2)
print("Offspring:", offspring)

Output:
Experiment-10(b)

Aim: Write a program to implement crossover, mutation and selection in GA

Software: VS Code

Theory: Genetic Algorithms (GAs) are optimization techniques inspired by natural selection. They work by
evolving a population of candidate solutions using three main operators: Selection (choosing fittest
individuals), Crossover (recombining genes of parents), and Mutation (randomly altering genes). These
operators help explore the search space and converge to an optimal or near-optimal solution.

Procedure:
1. Initialize a population of chromosomes randomly.
2. Evaluate fitness of each chromosome.
3. Select parent chromosomes based on fitness (e.g., roulette wheel or tournament).
4. Apply crossover to produce offspring.
5. Mutate offspring with a small probability.
6. Replace old population with new offspring.
7. Repeat steps 2–6 for multiple generations.

Code:
import random
def roulette_wheel_selection(population, fitness_scores):
#Selects an individual from the population using roulette wheel selection based on their fitness scores.
# Args:
#population (list): List of individuals in the population.
#fitness_scores (list): List of fitness scores corresponding to each individual in the population.
#Returns:selected_individual: Selected individual from the population.
total_fitness = sum(fitness_scores)
# Generate a random number between 0 and the total fitness
rand_num = random.uniform(0, total_fitness)
cumulative_fitness = 0
for individual, fitness in zip(population, fitness_scores):
cumulative_fitness += fitness
# If the cumulative fitness exceeds the random number, select this individual
if cumulative_fitness >= rand_num:
return individual
def crossover(parent1, parent2):
#Performs crossover operation between two parents to produce offspring.
# Args:
# parent1 (list): First parent chromosome.
# parent2 (list): Second parent chromosome.
#Returns:
# offspring (list): New offspring chromosome.
# Choose a random crossover point
crossover_point = random.randint(0, len(parent1) - 1)
# Create offspring by combining parts of both parents
offspring = parent1[:crossover_point] + parent2[crossover_point:]
return offspring
def mutation(individual, mutation_rate):
# Performs mutation operation on an individual with a given mutation rate.
#Args:
# individual (list): Individual chromosome to be mutated.
# mutation_rate (float): Probability of mutation for each gene.
# Returns:
# mutated_individual (list): Mutated individual chromosome.
mutated_individual = []
for gene in individual:
if random.random() < mutation_rate:
mutated_gene = 1 - gene
else:
mutated_gene = gene
mutated_individual.append(mutated_gene)
return mutated_individual
# Example usage
population = [[0, 1, 0, 1, 1], [1, 0, 1, 0, 1], [1, 1, 0, 0, 1], [0, 0, 1, 1, 0]]
fitness_scores = [5, 3, 4, 6]
mutation_rate = 0.1
# Select two parents using roulette wheel selection
parent1 = roulette_wheel_selection(population, fitness_scores)
parent2 = roulette_wheel_selection(population, fitness_scores)
# Perform crossover
offspring = crossover(parent1, parent2)
# Perform mutation on the offspring
mutated_offspring = mutation(offspring, mutation_rate)
print("Parent 1:", parent1)
print("Parent 2:", parent2)
print("Offspring after crossover:", offspring)
print("Mutated offspring:", mutated_offspring)

Output:

You might also like