Lab Manual CL III
Lab Manual CL III
LABORATORY MANUAL
Institute Vision
• To enrich the role of nation building by imparting the qualitative technical
education.
Institute Mission
• Impart technical knowledge through prescribed curriculum of university.
• Inculcate ethical and moral values in students for environmental and sustainable
development.
• Equip the aspirants through co-curricular and extra- curricular activities to excel
in career.
Department Vision
• To provide current technical education and train competitive engineering
professionals in Artificial Intelligence and Data Science with a commitment to
fulfilling industry requirements.
Department Mission
• To foster students with latest technologies in the field of Artificial Intelligence
and Data Science.
• To provide skill-based education to master the students in problem solving and
analytical skills in the area of Artificial Intelligence and Data Science.
• To develop employability skills among students in the fields of Artificial
Intelligence, Data Science.
PEO1 work in the domain of Artificial Intelligence and Data Science to design
ability of a computer system.
PEO2 apply analytical skills, decision making skills, leadership skills and critical
thinking skills to develop Artificial Intelligence and Data Science based solutions
for business problems.
Course Objectives:
• To introduce the concepts inspired by the human immune system and their application in
problem-solving and optimization.
• To make students aware about security issues and protection mechanisms for distributed
environments.
Course Outcomes:
CO1: Apply the principles on which the internet and other distributed systems are based.
CO2: Understand and apply the basic theoretical concepts and algorithms of distributed systems
in problem solving.
CO4: Design and implement evolutionary algorithms to solve optimization and search
problems in diverse domains.
CO5: Design and implement artificial immune system algorithms to solve complex problems
in different domains.
Table Of Contents
Assignment No. 01
Title: Design a Distributed Application Using RPC for Remote Computation of Factorial
Problem Statement: Develop a distributed application using Remote Procedure Call (RPC)
where a client submits an integer value to a remote server. The server calculates the factorial of
the given integer and returns the result to the client program. The application should demonstrate
the concept of distributed computing by enabling remote execution of the factorial computation.
Hardware Requirements: Intel Core i3 or higher, 4GB RAM, 100MB free disk space, and
network connectivity for client-server communication.
Theory:
Remote Procedure Call (RPC) is a communication protocol that allows a program to execute
procedures on a remote server as if they were local function calls. The RPC mechanism
abstracts network communication complexities, making distributed computing seamless and
efficient.
Working of RPC:
1. The client sends a request to the server with the necessary input data.
2. The server processes the request, executes the remote function (factorial calculation in
this case), and prepares the response.
3. The server sends the computed result back to the client.
4. The client receives the result and processes it accordingly.
Factorial Computation:
The factorial of a non-negative integer n is the product of all positive integers from 1 to n and
is denoted as n!. It is defined as:
For example:
• 5! = 5 × 4 × 3 × 2 × 1 = 120
• 3! = 3 × 2 × 1 = 6
• 1! = 1
• 0! = 1 (by definition)
Implementation Approach:
• Simplifies distributed computing by making remote function calls appear as local calls.
• Reduces computational load on client devices by offloading heavy calculations to the
server.
• Enables modular and scalable application design.
• Facilitates resource sharing and efficient computing in networked environments.
Source Code –
Client.py
import xmlrpc.client
Output -
Server.py
class FactorialServer:
def calculate_factorial(self, n):
if n < 0:
raise ValueError("Input must be a non-negative integer.")
result = 1
for i in range(1, n + 1):
result *= i
return result
# Create server
with SimpleXMLRPCServer(('localhost', 8000), requestHandler=RequestHandler) as
server:
server.register_introspection_functions()
server.register_instance(FactorialServer())
print("FactorialServer is ready to accept requests.")
server.serve_forever()
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No.2
Title: Design a Distributed Application Using RMI for Remote String Concatenation
Problem Statement: Develop a distributed application using Remote Method Invocation (RMI)
where a client submits two strings to a remote server. The server concatenates the given strings
and returns the result to the client program. The application should demonstrate the concept of
distributed computing by enabling remote execution of string concatenation.
Hardware Requirements: Intel Core i3 or higher, 4GB RAM, 100MB free disk space, and
network connectivity for client-server communication.
Theory:
Remote Method Invocation (RMI) enables a program to call methods on remote objects hosted
on another machine. In Python, this can be implemented using the RPyC (Remote Python Call)
library, which simplifies communication between distributed applications by enabling remote
execution of functions.
1. The client sends a request to the server with two input strings.
2. The server processes the request, concatenates the given strings, and prepares the
response.
3. The server sends the concatenated result back to the client.
4. The client receives the result and processes it accordingly.
String Concatenation:
String concatenation is the process of joining two or more strings together. In Python, it can be
performed using:
For example:
Implementation Approach:
1. Client Program: Sends two strings to the server via an RMI request.
2. Server Program: Receives the request, concatenates the given strings, and sends the
result back to the client.
3. Communication Layer: Handles the exchange of requests and responses between the
client and server using the RPyC library.
Source Code –
Client.py
import Pyro4
Output
PYRO:obj_3f70c6b68e9e4712a73a4167337c1e58@localhost:61368
Server.py
import Pyro4
@Pyro4.expose
class StringConcatenator(object):
def concatenate(self, str1, str2):
return str1 + " " + str2
Output –
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 03
Prerequisites: Basic understanding of fuzzy set theory, fuzzy relations, mathematical operations
on fuzzy sets, max-min composition, and Python programming.
Hardware Requirements: Intel Core i3 or higher, 4GB RAM, 200MB free disk space, and an
active Python environment.
Theory:
A fuzzy set is an extension of a classical set where each element has a degree of membership
between 0 and 1. Fuzzy sets are used in approximate reasoning and decision-making
applications.
1. Union (A ∪ B): The maximum membership value for each element from both sets.
o Formula: μ(A ∪ B) = max(μA, μB)
2. Intersection (A ∩ B): The minimum membership value for each element from both sets.
o Formula: μ(A ∩ B) = min(μA, μB)
3. Complement (A’): The degree of non-membership of each element.
o Formula: μ(A') = 1 - μ(A)
4. Difference (A - B): Elements that belong to A but not to B.
o Formula: μ(A - B) = min(μA, 1 - μB)
A fuzzy relation is a mapping between two fuzzy sets using the Cartesian product.
• If A and B are two fuzzy sets, their Cartesian product results in a fuzzy relation R.
• The membership function of the relation is defined as:
o μR(A, B) = min(μA(x), μB(y))
• The max-min composition is used to derive a new fuzzy relation from two existing fuzzy
relations.
• Formula:
o μR∘S(x, z) = max_y (min(μR(x, y), μS(y, z)))
Implementation Approach:
Source Code –
import numpy as np
# Example usage
union_result = fuzzy_union(A, B)
intersection_result = fuzzy_intersection(A, B)
complement_A = fuzzy_complement(A)
difference_result = fuzzy_difference(A, B)
print("Union:", union_result)
print("Intersection:", intersection_result)
print("Difference:", difference_result)
# Fuzzy relations
cartesian_result = cartesian_product(R, S)
composition_result = max_min_composition(R, S)
print(composition_result)
Conclusion: This practical demonstrates the implementation of fuzzy set operations and fuzzy
relations using Python. It highlights the importance of fuzzy logic in decision-making and real-
world applications.
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 04
Title: Simulation of Client Requests and Load Distribution Using Load Balancing Algorithms
Problem Statement: To design and implement a simulation of client requests and distribute
these requests among multiple servers using various load balancing algorithms such as Round
Robin, Least Connections, and Random Selection in Jupyter Notebook.
Prerequisites:
Software Requirements:
• Jupyter Notebook
• Python 3.x
Hardware Requirements:
Theory: Load balancing is a technique used to distribute network or application traffic across
multiple servers. This ensures no single server bears too much demand, enhancing
responsiveness and availability of applications.
1. Static Load Balancing: In this method, the distribution of traffic is predefined and
does not change based on server conditions. It works well for systems with uniform
load distribution.
2. Dynamic Load Balancing: This method adapts to changing conditions in real-time,
distributing traffic based on current server load, response time, or other metrics.
1. Round Robin: Requests are distributed cyclically to all servers. This is simple to
implement and works well when all servers have similar capabilities.
2. Least Connections: Requests are sent to the server with the fewest active connections.
This algorithm is efficient in environments where requests have varying processing
times.
3. Random Selection: Requests are assigned to a randomly selected server. It is easy to
implement but may lead to uneven load distribution if not managed properly.
Source Code –
import random
import time
class Server:
def__init__(self, id):
self.id=id
self.current_connections = 0
def handle_request(self):
self.current_connections + = 1
def release_request(self):
If self.current_connections > 0:
self.current_connections -= 1
class LoadBalancer:
def__init__(self, servers):
self.servers = servers
self.server_count = len(servers)
self.round_robin_index = 0
def round_robin(self):
server = self.servers[self.round_robin_index]
return server
def least_connections(self):
return server
def random_selection(self):
return random.choice(self.servers)
If algorithm = = "round_robin":
server = self.round_robin()
server = self.least_connections()
server = self.random_selection()
else:
server.handle_request()
def simulate_requests():
load_balancer = LoadBalancer(servers)
for_in range(10):
load_balancer.distribute_request(algorithm)
server.release_request()
simulate_requests()
Conclusion - Through this practical, we have explored the fundamental concepts of load
balancing and its significance in distributed systems. By simulating client requests and
implementing various load balancing algorithms such as Round Robin, Least Connections, and
Random Selection, we observed how different strategies impact the distribution of traffic among
servers.
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 05
Hardware Requirements: Intel Core i5 or higher, 8GB RAM, 500MB free disk space, and an
active Python environment.
Theory:
• Spray drying is a process used to convert liquid coconut milk into powder form.
• The optimization of process parameters (e.g., inlet air temperature, feed concentration) is
crucial for maximizing yield and quality.
• The GA-NN model improves predictive capability, enabling better control over drying
conditions.
Implementation Approach:
Source Code –
np.random.seed(42)
n_samples = 100
# Normalize inputs
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), loss='mse')
return model
def evaluate_fitness(individual):
return mse,
# GA Configuration
toolbox = base.Toolbox()
# Run GA
random.seed(42)
population = toolbox.population(n=10)
ngen = 20
# Best Solution
best_individual =tools.selBest(population,k=1)[0]
y_pred = final_model.predict(X_test)
# Visualize Results
plt.xlabel("True Values")
plt.ylabel("Predicted Values")
plt.legend()
plt.show()
Conclusion: This practical demonstrates the application of a hybrid GA-NN model for
optimizing genetic algorithm parameters in spray drying of coconut milk. The approach enhances
predictive accuracy and improves process efficiency through AI-driven optimization techniques.
Roll No.
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 06
Problem Statement: To design and implement the Clonal Selection Algorithm (CSA) using
Python in Jupyter Notebook to optimize problem-solving capabilities inspired by the natural
immune system.
Prerequisites:
Software Requirements:
• Jupyter Notebook
• Python 3.x
Hardware Requirements:
Theory: The Clonal Selection Algorithm (CSA) is a bio-inspired optimization technique based
on the clonal selection principle of the adaptive immune system. It is used to solve complex
optimization problems by mimicking the process of natural selection, cloning, and mutation of
immune cells.
Key Concepts:
The Clonal Selection Algorithm operates in an iterative manner, improving the solution
population over successive generations. The fundamental processes are inspired by the natural
immune response mechanism, which efficiently identifies and eliminates pathogens.
Applications of CSA:
• Optimization problems
• Pattern recognition
• Machine learning
• Data mining
• Network security
• Robotics path planning
Source Code –
import numpy as np
def objective_function(x):
# Initialize Population
def evaluate_fitness(population):
return 1 / (1 + objective_function(population))
sorted_indices = np.argsort(-fitness)
return population[sorted_indices[:num_best]]
return clones
population[-num_replace:] = new_population[:num_replace]
return population
best_fitness_history = []
fitness = evaluate_fitness(population)
fitness_mutated = evaluate_fitness(mutated_clones)
best_fitness_history.append(np.max(fitness))
if generation % 10 = = 0:
plt.plot(best_fitness)
plt.xlabel('Generations')
plt.ylabel('Best Fitness')
plt.show()
Conclusion - Through this practical, we have explored the Clonal Selection Algorithm and its
role in solving optimization problems inspired by the natural immune system. This practical
highlighted the efficiency of bio-inspired algorithms in addressing complex problem-solving
tasks, demonstrating the algorithm's ability to find optimal solutions through adaptive processes.
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 07
Problem Statement: To apply artificial immune pattern recognition techniques to perform the
task of structural damage classification, utilizing bio-inspired algorithms to detect and classify
damage in structural components.
Prerequisites:
Software Requirements:
• Jupyter Notebook
• Python 3.x
• Required Python libraries: NumPy, Pandas, Scikit-learn, Matplotlib
Hardware Requirements:
Theory: Artificial Immune Systems (AIS) are computational models inspired by the principles
and processes of the biological immune system. AIS are particularly effective in pattern
recognition tasks, such as structural damage classification, due to their adaptive learning
capabilities, robustness, and efficiency in handling complex, dynamic data environments.
The AIS framework operates by simulating the immune system's mechanisms of recognizing,
learning, and remembering patterns. In the context of structural damage classification, AIS
mimics the immune system’s ability to detect and classify anomalies (damages) based on
extracted structural features. The system utilizes concepts such as antigen-antibody interactions,
clonal selection, and affinity maturation to optimize classification performance.
Key Concepts:
Mathematical Model:
• Affinity Calculation: Measures the similarity between structural features (antigens) and
candidate solutions (antibodies) using distance metrics or similarity functions.
• Classification Rule: Assigns structural conditions (e.g., damaged or undamaged) based
on the highest affinity score.
• Mutation Operator: Applies controlled alterations to cloned antibodies to maintain
diversity and prevent overfitting.
Applications:
Source Code –
import numpy as np
import pandas as pd
df = pd.read_csv(r"C:\Users\saira\Downloads\structural_damage_data.csv")
df.head()
df.tail()
df.isnull().sum()
class AIPR:
self.n_clones = n_clones
self.mutation_rate = mutation_rate
self.generations = generations
for _ in range(self.generations):
for i in range(self.n_clones):
clone_fitness = self._fitness(clone, X, y)
self.memory_cells[i] = clone
preds = []
for x in X:
pred = self.labels[np.argmin(distances)]
preds.append(pred)
return np.array(preds)
closest_label = self.labels[np.argmin(distances)]
return np.mean(closest_label == y)
model.fit(X_train.values, y_train.values)
# Make predictions
y_pred = model.predict(X_test.values)
# Evaluation
# Confusion Matrix
plt.title('Confusion Matrix')
plt.show()
# Visualize Result
plt.figure(figsize=(10, 5))
plt.plot(y_test.values, label='True')
plt.legend()
plt.show()
Conclusion: Through this practical, we have explored the application of artificial immune
pattern recognition for structural damage classification. By implementing bio-inspired
algorithms in Python, we demonstrated the effectiveness of AIS in identifying and classifying
structural damage patterns. This practical highlighted the potential of artificial immune systems
in enhancing structural health monitoring and improving the reliability of damage detection
processes.
Roll No.
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 08
Prerequisites:
Software Requirements:
• Jupyter Notebook
• Python 3.x
• Required Python libraries: DEAP, NumPy, Matplotlib (for visualization)
Hardware Requirements:
Key Concepts:
Mathematical Model:
• Fitness Function:
• Selection Probability: Based on fitness proportionate selection or tournament selection
methods.
• Crossover Rate (Pc): Defines the likelihood of performing crossover between parent
individuals.
• Mutation Rate (Pm): Determines the probability of applying random mutations to
offspring.
Applications:
Source Code –
import numpy as np
def eval_func(individual):
# DEAP setup
toolbox = base.Toolbox()
toolbox.register("evaluate", eval_func)
# Create population
population = toolbox.population(n=50)
# Genetic Algorithm
parameters generations = 20
ind.fitness.values = fit
best_fitness = best_ind.fitness.values[0]
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 09
Title: Implementation of Ant Colony Optimization for Solving the Traveling Salesman Problem
Using Python
Problem Statement: A salesman needs to visit a set of cities exactly once and return to the
original city. The task is to find the shortest possible route that the salesman can take to visit all
the cities and return to the starting city, using Ant Colony Optimization (ACO) techniques.
Prerequisites:
Software Requirements:
• Jupyter Notebook
• Python 3.x
• Required Python libraries: NumPy, Matplotlib, NetworkX (for visualization of paths)
Hardware Requirements:
Theory: Ant Colony Optimization (ACO) is a probabilistic technique inspired by the foraging
behavior of ants in nature. Ants find the shortest path between their colony and food sources by
depositing pheromones along their trails. Over time, shorter paths accumulate more pheromones,
attracting more ants and reinforcing the optimal route.
In the context of the Traveling Salesman Problem (TSP), ACO is used to simulate the behavior
of artificial ants that explore different routes between cities. These ants communicate indirectly
through pheromone trails, which guide the search process towards optimal or near-optimal
solutions.
Key Concepts:
1. Pheromone Trail (τ): A numerical value representing the desirability of a path between
two cities. Higher pheromone levels indicate preferred routes.
2. Heuristic Information (η): Represents the visibility or attractiveness of a path, often
inversely proportional to the distance between cities.
3. Probability Transition Rule: Determines the likelihood of an ant choosing a specific
path based on pheromone concentration and heuristic information.
4. Pheromone Update Rule: Involves evaporation (reducing pheromone intensity over
time) and deposition (adding pheromones based on the quality of the solution).
5. Exploration vs. Exploitation: Balances between exploring new paths and exploiting
known good routes to optimize the solution.
Applications:
Advantages of ACO:
Challenges:
Source Code –
import numpy as np
import random
city_coordinates = np.array([
])
distance_matrix = np.array([
])
num_ants = 10
num_iterations = 50
evaporation_rate = 0.5
pheromone_constant = 1.0
heuristic_constant = 1.0
num_cities = len(distance_matrix)
# ACO algorithm
ant_routes = []
visited_cities = [current_city]
route = [current_city]
probabilities = []
pheromone_value = pheromone[current_city][city]
visibility_value = visibility[current_city][city]
probabilities.append((city, probability))
selected_city = probabilities[0][0]
route.append(selected_city)
visited_cities.append(selected_city)
current_city = selected_city
ant_routes.append(route)
delta_pheromone[city_a][city_b] += 1 / distance_matrix[city_a][city_b]
delta_pheromone[city_b][city_a] += 1/distance_matrix[city_a][city_b]
best_route = ant_routes[best_route_index]
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
Roll No.
Class BE AI & DS
Date Of Completion
Assessment Marks
Assessor’s Sign
Assignment No. 10
Title: Art Creation Using Neural Style Transfer with Deep Learning
Problem Statement: Neural Style Transfer (NST) is a deep learning technique used to
combine the content of one image with the artistic style of another. This practical introduces the
concept of NST and demonstrates how it can be implemented using a pre-trained deep learning
model.
Prerequisites:
Software Requirements:
• Python 3.x
• TensorFlow or PyTorch (for implementing Neural Style Transfer)
• Jupyter Notebook (or any Python IDE)
• Libraries: NumPy, Matplotlib, Keras, OpenCV, etc.
Hardware Requirements:
Theory:
Neural Style Transfer (NST) is a technique in deep learning that allows the combination of the
content of one image with the artistic style of another. The aim of NST is to create a new image
that retains the structure and objects (content) of the source image, while adopting the visual
appearance, color patterns, textures, and artistic style of the style image.
The underlying concept of NST can be explained through two primary concepts: content and
style.
1. Content:
Content refers to the key structures and objects present in an image. In the context of
NST, the content of an image is typically related to the arrangement of objects and their
spatial relationships. For example, a portrait may contain content such as the shape of the
face, the location of eyes, nose, and mouth, and other objects present in the scene.
2. Style:
Style refers to the visual appearance, textures, colors, and patterns found in an image.
The style can be defined by elements like color schemes, textures, brush strokes, and
patterns. In art, style often characterizes the work of specific artists (e.g., Van Gogh’s
swirling brushstrokes or Picasso’s abstract shapes).
NST uses deep convolutional neural networks (CNNs) to separate the content and style of an
image. A pre-trained network, such as VGG-19, is employed to extract deep features from both
the content and style images.
1. ContentLoss:
To retain the content of the original image, the difference between the content features of
the generated image and the original content image is measured. This difference is
referred to as content loss, which is minimized during the optimization process.
2. StyleLoss:
To capture the style of the artistic image, a measure of the difference between the style
features of the generated image and the style image is calculated. This difference is
quantified using the Gram matrix, which represents the correlations between feature
maps in the neural network. The style loss measures how well the generated image
matches the style of the style image.
3. GramMatrix:
The Gram matrix is a method to capture the correlation between different channels
(feature maps) of the image. It is computed by multiplying the feature map by its
transpose. This matrix captures texture patterns, which are crucial for replicating an
image’s artistic style.
Loss Function:
The optimization in NST aims to minimize the total loss, which is a combination of the content
and style losses. This is done iteratively by adjusting the pixels of the generated image.
• Content Loss is calculated as the difference between the content representation of the
content image and the generated image.
• Style Loss is calculated as the difference between the style representation of the style
image and the generated image, using the Gram matrix.
• The total loss function combines these two losses with respective weights, allowing the
optimization process to balance content retention and style reproduction.
Optimization:
The optimization process uses gradient descent to minimize the total loss. By iteratively
adjusting the pixels of the generated image, the model gradually creates an image that has the
content of the original image and the style of the style image. The process typically uses an
optimization algorithm such as Adam or L-BFGS.
1. ArtisticRendering:
NST can be used to generate artistic representations of photographs by applying the style
of famous artists (e.g., Van Gogh, Picasso) to a regular image. This has widespread
applications in digital art and design.
2. PhotoEnhancement:
NST allows for the transformation of everyday photographs into visually engaging works
of art by transferring the style of selected artworks onto the images.
3. CreativeIndustries:
Artists and designers leverage NST to explore new creative possibilities by combining
different art styles with real-world photographs, offering novel ways to express creativity.
Source Code –
import tensorflow as tf
import numpy as np
rom tensorflow.keras.preprocessing
img = image.img_to_array(img)
img = vgg19.preprocess_input(img)
return img
def deprocess_img(img):
img = img.squeeze() img = img + [103.939, 116.779, 123.68] # Convert back to BGR
return img
content_path = r"C:\Users\saira\Downloads\Content.jpg"
style_path = r"C:\Users\saira\Downloads\style.jpg"
content_img = load_and_process_img(content_path)
style_img = load_and_process_img(style_path)
content_output = model.get_layer(content_layer).output
content_features = model(content_img)
style_features = model(style_img)
content_feature = content_features[0]
style_features = style_features[1:]
gram_style = gram_matrix(style)
gram_generated = gram_matrix(generated)
def gram_matrix(x):
channels = int(x.shape[-1])
return gram
def compute_total_variation_loss(generated):
return tf.reduce_mean(tf.image.total_variation(generated))
total_variation_loss = compute_total_variation_loss(generated_img)
return total_loss
with tf.GradientTape() as
tape: tape.watch(generated_img)
return grads
optimizer = tf.optimizers.Adam(learning_rate=0.01)
iterations = 200
for i in range(iterations):
if i % 100 == 0:
print(f"Iteration {i}")
img = deprocess_img(generated_img.numpy())
plt.imshow(img)
plt.show()
final_img = deprocess_img(generated_img.numpy())
plt.imshow(final_img)
plt.show()
Conclusion: Neural Style Transfer demonstrates the ability of deep learning models to perform
creative tasks by extracting content and style features from images and recombining them. This
practical not only deepens the understanding of CNNs but also highlights their potential in
applications beyond traditional image classification, such as artistic generation and creative
design.