0% found this document useful (0 votes)
13 views26 pages

DAA Final Manual (1)-2

The document outlines laboratory exercises for the AD3351 - Design and Analysis of Algorithms course at Agni College of Technology for the academic year 2023-2024. It includes various algorithms such as Strassen's Matrix Multiplication, Topological Sorting, Heap Sort, and Dynamic Programming techniques like Coin Changing, Warshall's, Floyd's algorithms, and the Knapsack Problem, along with their respective Python implementations. Each exercise concludes with the successful execution of the program and the expected output.
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)
13 views26 pages

DAA Final Manual (1)-2

The document outlines laboratory exercises for the AD3351 - Design and Analysis of Algorithms course at Agni College of Technology for the academic year 2023-2024. It includes various algorithms such as Strassen's Matrix Multiplication, Topological Sorting, Heap Sort, and Dynamic Programming techniques like Coin Changing, Warshall's, Floyd's algorithms, and the Knapsack Problem, along with their respective Python implementations. Each exercise concludes with the successful execution of the program and the expected output.
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/ 26

AGNI COLLEGE OF TECHNOLOGY

(Approved by AICTE & Affiliated to Anna University)

Thalambur, Chennai-600130

AD3351 – DESIGN AND ANALYSIS OF ALGORITHM


LABORATORY
DEPARTMENT OF ARTIFICIAL INTELLIGENCE AND
DATA SCIENCE
2023-2024
ACADEMIC YEAR 2022 –2023

ODD SEMESTER

Name of the Student:

Register No:

Year/Dept/Section:
2023-2024
Exp. Page No.
No
EX.NO. : 1
DIVIDE AND CONQURE – STRASSEN’S MATRIX MULTIPLICATION
DATE :

AIM
To do Divide and Conquer - Strassen's Matrix Multiplication

ALGORITHM

Step 1: Start the program.


Step 2: create a matrix A and B
Step 3: Divide matrix A and matrix B into 4 sub-matrices of size N/2 x N/2 as shown in the above diagram.

Step 4: Calculate the 7 matrix multiplications recursively.


Step 5: Compute the submatrices of C.
Step 6: Combine these submatrices into our new matrix C
Step 7: End the program

PROGRAM

import numpy as np
def strassen_algorithm(x, y):
if x.size == 1 or y.size == 1:
return x * y
n = x.shape[0]
if n % 2 == 1:
x = np.pad(x, (0, 1), mode='constant')
y = np.pad(y, (0, 1), mode='constant')
m = int(np.ceil(n / 2))
a = x[: m, : m]
b = x[: m, m:]
c = x[m:, : m]
d = x[m:, m:]
e = y[: m, : m]
f = y[: m, m:]
g = y[m:, : m]
h = y[m:, m:]
p1 = strassen_algorithm(a, f - h)
p2 = strassen_algorithm(a + b, h)
p3 = strassen_algorithm(c + d, e)
p4 = strassen_algorithm(d, g - e)
p5 = strassen_algorithm(a + d, e + h)
p6 = strassen_algorithm(b - d, g + h)
p7 = strassen_algorithm(a - c, e + f)
result = np.zeros((2 * m, 2 * m), dtype=np.int32)
result[: m, : m] = p5 + p4 - p2 + p6
result[: m, m:] = p1 + p2
result[m:, : m] = p3 + p4
result[m:, m:] = p1 + p5 - p3 - p7
return result[: n, : n]
#input of two matrix
x = np.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [2, 2, 2, 2]])
y = np.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [2, 2, 2, 2]])
print('Matrix multiplication result: ')
print(strassen_algorithm(x, y))

OUTPUT
Matrix multiplication result:
[[ 8 8 8 8]
[16 16 16 16]
[24 24 24 24]
[16 16 16 16]]

RESULT
The above program has been executed successfully and the required output is displayed
EX.NO. : 2
DATE :

AIM
To implement Decrease and Conquer - Topological Sorting

ALGORITHM

Step 1: Create a stack to store the nodes.


Step 2: Initialize visited an array of size N to keep the record of visited nodes.
Step 3: Run a loop from 0 to N
Step 4: if the node is not marked True in the visited array
Step 5: Call the recursive function for topological sort and perform the following steps.
Step 6: Mark the current node as True in the visited array.
Step 7: Run a loop on all the nodes which have a directed edge to the current node
Step 8: if the node is not marked True in the visited array:
Recursively call the topological sort function on the node and Push the current node in the
stack.
Step 9: Print all the elements in the stack.

PROGRAM

# Python program to print topological sorting of a DAG from


collections import defaultdict
# Class to represent a graph
class Graph:
def __init__(self, vertices):
self.graph = defaultdict(list) # dictionary containing adjacency List self.V = vertices #
No. of vertices
# function to add an edge to graph def
addEdge(self, u, v):
self.graph[u].append(v)
# A recursive function used by topologicalSort def
topologicalSortUtil(self, v, visited, stack):
# Mark the current node as visited.
visited[v] = True
# Recur for all the vertices adjacent to this vertex for i in
self.graph[v]:
if visited[i] == False: self.topologicalSortUtil(i, visited, stack)
# Push current vertex to stack which stores result
stack.append(v)
# The function to do Topological Sort. It uses recursive
# topologicalSortUtil()

def topologicalSort(self):
# Mark all the vertices as not visited visited
= [False]*self.V
stack = []
# Call the recursive helper function to store Topological
# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i, visited, stack)
# Print contents of the stack print(stack[::-1]) # return list
in reverse order
g = Graph(6)
g.addEdge(5, 2)
g.addEdge(5, 0)
g.addEdge(4, 0)
g.addEdge(4, 1)
g.addEdge(2, 3)
g.addEdge(3, 1)
print ("Topological Sort of the given graph")
g.topologicalSort()

OUTPUT
Topological Sort of the given graph
[5, 4, 2, 3, 1, 0]

RESULT
The above program has been executed successfully and the required output is displayed
EX.NO. : 3
DATE : TEANSFORM AND CONQUER – HEAP SORT

AIM
To write a python program to Transform and Conquer - Heap Sort

ALGORITHM

Step 1: First convert the array into a heap data structure using heapify,
Step 2: one by one delete the root node of the Max-heap and replace it with the last node in the heap
and then heapify the root of the heap.
Step 3: Repeat this process until the size of the heap is greater than 1.
Step 4: Build a max heap from the input data.
Step 5: At this point, the maximum element is stored at the root of the heap. Step 6: Replace it with
the last item of the heap followed by reducing the size of the heap by 1.
Step 7: Finally, heapify the root of the tree.
Step 8: Repeat step 2 while the size of the heap is greater than 1.

PROGRAM

def heapify(arr, n, i):


largest = i
l=2*i+1
r=2*i+2
if l < n and arr[i] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
(arr[i], arr[largest]) = (arr[largest], arr[i]) # swap
heapify(arr, n, largest)
def heapSort(arr):
n = len(arr)
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
for i in range(n - 1, 0, -1):
(arr[i], arr[0]) = (arr[0], arr[i]) # swap
heapify(arr, i, 0)
arr = [12, 11, 13, 5, 6, 7, ]
heapSort(arr)
n = len(arr)
print('Sorted array is')
for i in range(n):
print(arr[i])

OUTPUT
Sorted array is
5
6
7
11
12
13

RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 4 DYNAMIC PROGRAMMING – COIN CHANGING PROBLEM,
WARSHALL’S AND FLOYD’S ALAGRITHMS, KNAPSACK
DATE :
PROBLEM

AIM
To write a python program to implement Dynamic programming - Coin change Problem, Warshall's
and Floyd's algorithms, Knapsack Problem

ALGORITHM

Coinbase Problem
Step 1: Start the program.
Step 2: Create a 2-D vector to store the Overlapping Solutions
Step 3: Keep Track of the overlapping subproblems while Traversing the array of coins
Step 4: Recall them whenever needed
Step 5: End the program

Floyd's Warshall algorithm


Step 1: Start the program.
Step 2: Initialize the solution matrix the same as the input graph matrix as a first step.
Step 3: Then update the solution matrix by considering all vertices as an intermediate vertex.
Step 4: The idea is to one by one pick all vertices and updates all shortest paths which include the
picked vertex as an intermediate vertex in the shortest path.
Step 5: When we pick vertex number k as an intermediate vertex, we already have considered
vertices {0, 1, 2, .. k-1} as intermediate vertices.
Step 6: For every pair (i, j) of the source and destination vertices respectively, there are two possible
cases.

Step 7: k is not an intermediate vertex in the shortest path from i to j. We keep the value of dist[i][j]
as it is.

Step 8: k is an intermediate vertex in the shortest path from i to j. We update the value of
dist[i][j] as dist[i][k] + dist[k][j] if dist[i][j] > dist[i][k] + dist[k][j]
Step 9: End the program
Knapsack Problem
Step 1: Start the program.

Step 2: The maximum value obtained from ‘N’ items is the max of the following two values.
Step 3: Maximum value obtained by N-1 items and W weight (excluding nth item)
Step 4: Value of nth item plus maximum value obtained by N-1 items and W minus the weight of
the Nth item (including Nth item)
Step 5: If the weight of the ‘Nth’ item is greater than ‘W’, then the Nth item cannot be included and
Case 1 is the only possibility.
Step 6: End the program

PROGRAM

Coin change Problem

def count(S, m, n):


table = [[0 for x in range(m)] for x in range(n+1)] for i
in range(m):
table[0][i] = 1
for i in range(1, n+1):
for j in range(m):
x = table[i - S[j]][j] if i-S[j] >= 0 else 0
y = table[i][j-1] if j >= 1 else 0
table[i][j] = x + y
return table[n][m-1]
arr = [1, 2, 3]
m = len(arr)
n=4
print(count(arr, m, n))

Warshall’s and Floyd‘s algorithms


nV = 4
INF = 999
def floyd(G):
dist = list(map(lambda p: list(map(lambda q: q, p)), G))
for r in range(nV):
for p in range(nV):
for q in range(nV):
dist[p][q] = min(dist[p][q], dist[p][r] + dist[r][q])
sol(dist)
def sol(dist):
for p in range(nV):
for q in range(nV):
if(dist[p][q] == INF):
print("INF", end=" ")
else:
print(dist[p][q], end=" ")
print(" ")
G = [[0, 5, INF, INF],
[50, 0, 15, 5],
[30, INF, 0, 15],
[15, INF, 5, 0]]
floyd(G)

Output
0 5 15 10
20 0 10 5
30 35 0 15
15 20 5 0

Knapsack problem

def knapSack(W, wt, val, n):


K = [[0 for x in range(W + 1)] for x in range(n + 1)]
for i in range(n + 1):
for w in range(W + 1):
if i == 0 or w == 0:
K[i][w] = 0
elif wt[i-1] <= w:
K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w])
else:
K[i][w] = K[i-1][w]

return K[n][W]
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))

OUTPUT:

220

RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 5
DATE : GREEDY TECHNIQUE – DIJKSTRA’S ALGORITHM, HUFFMAN
TREES, AND CODES

AIM
To write a python program to implement Greedy Technique - Dijkstra's algorithm, Huffman
Trees, and codes

ALGORITHM
Step 1: Create a set sptSet (shortest path tree set) that keeps track of vertices included in the shortest
path tree.

Step 2: Assign a distance value to all vertices in the input graph.


Initialize all distance values as INFINITE.

Step 3: Assign the distance value as 0 for the source vertex so that it is picked first.

Step 4: While sptSet doesn’t include all vertices

Step 5: Pick a vertex u that is not there in sptSet and has a minimum distance value.

Step 6: Include u to sptSet7.

Step 7: Update the distance value of all adjacent vertices of u. To update the distance values, iterate

through all adjacent vertices. For every adjacent vertex v, if the sum of a distance value of u

(from source) and weight of edge u-v, is less than the distance value of v, then update the

distance value of v.

PROGRAM

Dijkstra’s algorithm

num_of_vertex = 7
def minimumDistance(distance, visited):
_min = 1e11
min_index = 1e11
for i in range(num_of_vertex):
if not visited[i] and distance[i] & lt; = _min:
_min = distance[i]
min_index = i
return min_index
def printParentNode(parent, i):
if parent[i] == -1:
return
printParentNode(parent, parent[i])
print("{} ".format(i + 1), end = "")
def dijkstra(graph, src):
distance = list()
visited = list()
parent = list()
for i in range(num_of_vertex):
parent.append(-1)
distance.append(1e11)
visited.append(False)
distance[src] = 0
for i in range(num_of_vertex - 1):
U = minimumDistance(distance, visited)
visited[U] = True
for j in range(num_of_vertex):
curr_distance = distance[U] + graph[U][j]
if not visited[j] and graph[U][j] and curr_distance & lt; distance[j]:
parent[j] = U
distance[j] = curr_distance
print("Vertex\t\tDistance\tPath")
for i in range(num_of_vertex):
print("{}->{}\t\t{}\t\t{}
".format(src + 1, i + 1, distance[i], src + 1), end = "")
printParentNode(parent, i)
print("")

graph = [

[0, 1, 7, 6, 0, 0, 0],
[1, 0, 9, 0, 0, 3, 0],
[7, 9, 0, 0, 0, 0, 1],
[6, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 0, 0, 0],
[0, 3, 0, 0, 0, 0, 3],
[0, 0, 0, 0, 5, 3, 0]
]
dijkstra(graph, 0)

Output:
Vertex Distance Path
1->1 0 1
1->2 1 1 2
1->3 7 1 3
1->4 6 1 4
1->5 8 1 4 5
1->6 4 1 2 6
1->7 7 1 2 67

Huffman Trees and codes


from collections import Counter
class NodeTree(object):
def __init__(self, left=None, right=None):
self.left = left
self.right = right
def children(self):
return self.left, self.right
def __str__(self):
return self.left, self.right
def huffman_code_tree(node, binString=''):
if type(node) is str:
return {node: binString}
(l, r) = node.children()
d = dict()
d.update(huffman_code_tree(l, binString + '0'))
d.update(huffman_code_tree(r, binString + '1')) return d
def make_tree(nodes):

while len(nodes) > 1:


(key1, c1) = nodes[-1]
(key2, c2) = nodes[-2]
nodes = nodes[:-2]
node = NodeTree(key1, key2)
nodes.append((node, c1 + c2))
nodes = sorted(nodes, key=lambda x: x[1], reverse=True)
return nodes[0][0]
if __name__ == '__main__':
string = 'BCAADDDCCACACAC'
freq = dict(Counter(string))
freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)
node = make_tree(freq)
encoding = huffman_code_tree(node)
for i in encoding:
print(f'{i} : {encoding[i]}

RESULT
The above program has been executed successfully and the required output is displayed
EX.NO. : 6
DATE : ITERATIVE IMPROVEMENT – SIMPLEX METHOD

AIM
To write a program to implement Iterative improvement - Simplex Method.

ALGORITHM
Step 1: Start with the initial basis associated with the identity matrix.
Step 2: Calculate the relative profits.

For MAX problem-


If all the relative profits are less than or equal to 0, then the current basis is the optimal one. STOP.
Else continue to 3.

For MIN problem


If all the relative profits are greater than or equal to 0, then the current basis is the optimal one. STOP.
Else continue to 3.

Step 3: Find the column corresponding to max relative profit. Say column k has the max Rel. profit. So
xk will enter the basis.
Step 4: Perform a min ratio test to determine which variable will leave the basis.
min ratio test: XBr/y_{rk} = min\{XB_i/y_{ik}\}
The index of the min element i.e 'r' will determine the leaving variable.
The basic variable at index r will leave the basis.

Step 5: It's evident that the entered variable will not form an identity matrix, so we will have to perform
row operations to make it identity again.
Step 6: Find the pivot element. The element at index (r, k) will be the pivot element and row r will be the
pivot row.
Step 7:Divide the rth row by pivot to make it 1. And subtract c*(rth row) from other rows to make
them 0, where c is the coefficient required to make that row 0.
PROGRAM

import numpy as np
from fractions import Fraction # so that numbers are not displayed in decimal.

print("\n ****SiMplex Algorithm ****\n\n")


A = np.array([[1, 1, 0, 1], [2, 1, 1, 0]])
b = np.array([8, 10])
c = np.array([1, 1, 0, 0])
cb = np.array(c[3])
B = np.array([[3], [2]])
cb = np.vstack((cb, c[2]))
xb = np.transpose([b])
table = np.hstack((B, cb))
table = np.hstack((table, xb))
table = np.hstack((table, A))
table = np.array(table, dtype ='float')
MIN = 0
print("Table at itr = 0")
print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")
for row in table:
for el in row:
print(Fraction(str(el)).limit_denominator(100), end ='\t')
print()
print()
print("Simplex Working....")

reached = 0
itr = 1
unbounded = 0
alternate = 0

while reached == 0:

print("Iteration: ", end =' ')


print(itr)
print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")
for row in table:
for el in row:
print(Fraction(str(el)).limit_denominator(100), end ='\t')
print()
i=0
rel_prof = []
while i<len(A[0]):
rel_prof.append(c[i] - np.sum(table[:, 1]*table[:, 3 + i]))
i=i+1

print("rel profit: ", end =" ")


for profit in rel_prof:
print(Fraction(str(profit)).limit_denominator(100), end =", ")
print()
i=0

b_var = table[:, 0]
# checking for alternate solution
while i<len(A[0]):
j=0
present = 0
while j<len(b_var):
if int(b_var[j]) == i:
present = 1
break;
j+= 1
if present == 0:
if rel_prof[i] == 0:
alternate = 1
print("Case of Alternate found")
# print(i, end =" ")
i+= 1
print()
flag = 0
for profit in rel_prof:
if profit>0:
flag = 1
break
# if all relative profits <= 0 if
flag == 0:
print("All profits are <= 0, optimality reached")
reached = 1
break

k = rel_prof.index(max(rel_prof))
min = 99999
i = 0;
r = -1
while i<len(table):
if (table[:, 2][i]>0 and table[:, 3 + k][i]>0):
val = table[:, 2][i]/table[:, 3 + k][i]
if val<min:
min = val
r = i # leaving variable
i+= 1
if r == -1:
unbounded = 1
print("Case of Unbounded")
break

print("pivot element index:", end =' ')


print(np.array([r, 3 + k]))

pivot = table[r][3 + k]
print("pivot element: ", end =" ")
print(Fraction(pivot).limit_denominator(100))

table[r, 2:len(table[0])] = table[


r, 2:len(table[0])] / pivot

i=0
while i<len(table):
if i != r:
table[i, 2:len(table[0])] = table[i,
2:len(table[0])] - table[i][3 + k] *
table[r, 2:len(table[0])]
i += 1
table[r][0] = k
table[r][1] = c[k]

print()
print()
itr+= 1
print()

print("***************************************************************")
if unbounded == 1:
print("UNBOUNDED LPP")
exit()
if alternate == 1:
print("ALTERNATE Solution")

print("optimal table:")
print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")
for row in table:
for el in row:
print(Fraction(str(el)).limit_denominator(100), end ='\t')
print()
print()
print("value of Z at optimality: ", end =" ")

basis = []
i=0
sum = 0
while i<len(table):
sum += c[int(table[i][0])]*table[i][2]
temp = "x"+str(int(table[i][0])+1)
basis.append(temp)
i+= 1
if MIN == 1:
print(-Fraction(str(sum)).limit_denominator(100))
else:
print(Fraction(str(sum)).limit_denominator(100))
print("Final Basis: ", end =" ")
print(basis)

print("Simplex Finished...")
print()

RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 7
BACKTRACKING – N-QUEEN PROBLEM, SUBSET SUM PROBLEM
DATE :

AIM
To write a program to implement Backtracking - N-Queen problem, Subset Sum Problem

ALGORITHM
Step 1: Make a board, and make a space to collect all solution states.
Step 2: Start in the topmost row.
Step 3: Make a recursive function that takes the state of the board and the current row
number as its parameter.
Step 4: Fill a queen in a safe place and use this state of the board to advance to the next

recursive call, add 1 to the current row. Revert the state of the board after making

the call.

a) Safe function checks the current column, left top diagonal, and right top diagonal.
b) If no queen is present then fill else return false and stop exploring that state
and track back to the next possible solution state
Step 5: Keep calling the function till the current row is out of bounds.
Step 6: If the current row reaches the number of rows in the board then the board is filled.
Step 7: Store the state and return.

PROGRAM
N-Queen problem

global N
N=4
def printSolution(board):
for i in range(N):
for j in range(N):
print (board[i][j],end=' ')
print()
def isSafe(board, row, col):
for i in range(col):
if board[row][i] == 1:
return False

for i, j in zip(range(row, -1, -1), range(col, -1, -1)):


if board[i][j] == 1:
return False

for i, j in zip(range(row, N, 1), range(col, -1, -1)):


if board[i][j] == 1:
return False

return True

def solveNQUtil(board, col):

if col >= N:
return True

for i in range(N):

if isSafe(board, i, col):
board[i][col] = 1

if solveNQUtil(board, col + 1) == True:


return True

board[i][col] = 0

return False

def solveNQ():
board = [ [0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]

if solveNQUtil(board, 0) == False:
print ("Solution does not exist")
return False

printSolution(board)
return True

solveNQ()

OUTPUT
0010
1000
0001
0100
Subset problem

def isSubsetSum(set, n, sum):

if (sum == 0):
return True
if (n == 0):
return False

if (set[n - 1] > sum):


return isSubsetSum(set, n - 1, sum)
return isSubsetSum(
set, n-1, sum) or isSubsetSum(
set, n-1, sum-set[n-1])
set = [3, 34, 4, 12, 5, 2]
sum = 9
n = len(set)
if (isSubsetSum(set, n, sum) == True):
print("Found a subset with given sum")
else:
print("No subset with given sum")

OUTPUT

Found a subset with given sum

RESULT
The above program has been executed successfully and the required output is displayed.
EX.NO. : 8 BRANCH AND BOND – ASSIGNMENT PROBLEM, TRAVELING
DATE : SALESMAN PROBLEM

AIM
To write a python program to implement Branch and Bound - Assignment problem, Traveling
Salesman Problem

ALGORITHM

Step 1: In the Branch and Bound method, for the current node in the tree, we compute a bound on
the best possible solution that we can get if we down this node.
Step 2: If the bound on the best possible solution itself is worse than the current best (best computed
so far)
Step 3: Then we ignore the subtree rooted with the node.
Step 4: Note that the cost through a node includes two costs.
Step 5: Cost of reaching the node from the root (When we reach a node, we have this cost
computed)
Step 6: Cost of reaching an answer from the current node to a leaf (We compute a bound on this
cost to decide whether to ignore subtree with this node or not).

PROGRAM
from sys import maxsize
from itertools import permutations
V=4

def travellingSalesmanProblem(graph, s):


vertex = []
for i in range(V):
if i != s:
vertex.append(i)

min_path = maxsize
next_permutation=permutations(vertex)
for i in next_permutation:
current_pathweight = 0
k=s
for j in i:
current_pathweight += graph[k][j]
k=j
current_pathweight += graph[k][s]
min_path = min(min_path, current_pathweight)
return min_path
if __name__ == "__main__":
graph = [[0, 10, 15, 20], [10, 0, 35, 25],
[15, 35, 0, 30], [20, 25, 30, 0]]
s=0
print(travellingSalesmanProblem(graph, s))

OUTPUT

The minimum cost is: 80

RESULT
The above program has been executed successfully and the required output is displayed.

You might also like