DATE:
EX.NO:1.A) RECURSIVE ALGORITHM
AIM:
To implement the recursive algorithm for finding factorial of a number using python.
ALGORITHM:
STEP1: start the program.
STEP2: get the number.
STEP3: if number is equal to 1 return 1 other wise call recursively the factorial function.
STEP4: return the factorial value
STEP5: print the factorial as the output.
PROGRAM:
def factorial(x):
"""This is a recursive function to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * factorial(x-1))
num = 5
print("The factorial of", num, "is", factorial(num))
OUTPUT:
120
RESULT:
Thus the program for recursive has executed successfully.
DATE:
EX.NO: 1.B) NON RECURSIVE ALGORITHM
AIM:
To implement the Non-recursive algorithm using python.
ALGORITHM:
Step1. Read a number
Step2. Initialize fact as 1
Step3. If number is greater than 0, calculate factorial and decrement by 1.
Step4. Print the factorial value.
PROGRAM:
n=int(input("Enter number:"))
fact=1
while(n>0):
fact=fact*n
n=n-1
print("Factorial of the number is: ")
print(fact)
OUTPUT:
Enter number:6
Factorial of the number is:
720
RESULT:
Thus the program to implement non recursive has executed successfully.
DATE:
EX.NO:1.1.A) RECURSIVE ALGORITHM
AIM:
To implement the recursive algorithm for finding the sum of given numbers using python.
ALGORITHM:
STEP1: start the program.
STEP2: get the number.
STEP3: declare the variable to store the sum and set it to 0.
STEP4: repeat the process by adding every number in the list.
STEP5: range of (0,0+n).
STEP6: print the list and return the output.
PROGRAM:
def sum(numbers):
total = 0
for x in numbers:
total += x
return total
print(sum((8, 2, 3, 0, 7)))
OUTPUT:
20
RESULT:
Thus the program for recursive has executed successfully.
DATE:
EX.NO: 1.1 B) NON RECURSIVE ALGORITHM
AIM:
To implement the Non-recursive algorithm using python.
ALGORITHM:
Step1. Define graph (adjacency list) using python dictionary
Step2. Define one of the node as Source
Step3.Implement a method to accept the graph and source.
Step4.Print the DFS of a given graph using non recursive approach.
PROGRAM:
graph = {"A":["D","C","B"], "B":["E"], "C":["G","F"], "D":["H"], "E":["I"], "F":["J"]}
def dfs_non_recursive(graph, source):
if source is None or source not in graph:
return "Invalid input"
path = []
stack = [source]
while(len(stack) != 0):
s = stack.pop()
if s not in path:
path.append(s)
if s not in graph:
#leaf node
continue
for neighbor in graph[s]:
stack.append(neighbor)
return " ".join(path)
DFS_path = dfs_non_recursive(graph, "A")
print(DFS_path)
OUTPUT:
ABEICFJGDH
RESULT:
Thus the program to implement non recursive has executed successfully.
DATE:
EX.NO:2 DIVIDE AND CONQUER-STRASSEN’S MATRIX MULTIPLICATION
AIM:
To implement the strassen’s matrix multiplication using python.
ALGORITHM
Step1. Start the program.
Step2. Divide the matrices A and B into smaller submatrices of the size n/2xn/2.
Step3. Using the formula to carry out 2*2 matrix multiplication.
Step4. In this eight multiplications and four additions, subtractions are performed.
Step5. Combine the result of two matrices to find the final product or final matrix.
Step6. Stop the program.
PROGRAM:
import numpy as np
def split(matrix):
row,col=matrix.shape
row2,col2=row//2,col/2
return matrix[:row2,:col2],matrix[:row2,col2:],matrix[row2:,col2],matrix[row:,col2:]
def Strassen(x,y):
if lex(x)==1:
return x*y
a,b,c,d=split(x)
e,f,g,h=split(y)
p1=strassen(a,f-1)
p2=strassen(a+b,h)
p3=strassen(c+d,e)
p4=strassen(d,g-e)
p5=strassen(a+d,e+h)
p6=strassen(b-d,g+h)
p7=strassen(a-c,e+f)
c11=p5+p4-p2+p6
c12=p1+p2
c21=p3+p4
c22=p1+p5-p3-p7
c=np.vstack((np.hstack((c11,c12)),hp.hstack((c21,c22))))
return c
OUTPUT:
Array A =>
1 1 1 1
2 2 2 2
3 3 3 3
2 2 2 2
Array B =>
1 1 1 1
2 2 2 2
3 3 3 3
2 2 2 2
Result Array =>
8 8 8 8
16 16 16 16
24 24 24 24
16 16 16 16
RESULT:
Thus the program to implement the Strassens’s Matrix Multiplication has executed
successfully.
DATE:
EX.NO: 3.A) TOPOLOGICAL SORTING
AIM:
To implement the selection sort using python.
ALGORITHM:
Step1. Identify the node that has no in-degree (no incoming edges) and select that node as the
source node of the graph.
Step2. Delete the source node with zero in-degree and also delete all its outgoing edges from the
graph. Insert the deleted vertex in the result array.
Step3. Update the in-degree of the adjacent nodes after deleting the outgoing edges
Step4. Repeat step 1 to step 3 until the graph is empty.
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.insert(0,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 stack
print (stack)
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 ("Following is a Topological Sort of the given graph")
g.topologicalSort()
OUTPUT:
Following is a Topological Sort of the given graph
[5, 4, 2, 3, 1, 0]
RESULT:
Thus the program for the Topological Sort has executed successfully.
DATE:
EX.NO:4 TRANSFORM AND CONQUER -HEAP SORT
AIM:
To implement the Heapsort using python.
ALGORITHM:
Step1. Define a function heapify().
Step2. Pass three parameters array,a and b.
Step3. Find largest among root and children.
Step4. If the root is not the largest,swap it with the children.
Step5. Continue to heapify.
Step6. Define function Heap_Sort().
Step7. Pass array as parameters.
Step8. Build Max-heap and swap.
PROGRAM:
def heapify(arr, n, i):
largest = i # Initialize largest as root
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
# See if left child of root exists and is
# greater than root
if l < n and arr[i] < arr[l]:
largest = l
# See if right child of root exists and is
# greater than root
if r < n and arr[largest] < arr[r]:
largest = r
# Change root, if needed
if largest != i:
(arr[i], arr[largest]) = (arr[largest], arr[i]) # swap
# Heapify the root.
heapify(arr, n, largest)
# The main function to sort an array of given size
def heapSort(arr):
n = len(arr)
# Build a maxheap.
# Since last parent will be at ((n//2)-1) we can start at that location.
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# One by one extract elements
for i in range(n - 1, 0, -1):
(arr[i], arr[0]) = (arr[0], arr[i]) # swap
heapify(arr, i, 0)
# Driver code to test above
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:
Thus the program for the heap sort has executed successfully.
DATE:
EX.NO:5 A) DYNAMIC PROGRAMMING-COIN CHANGE PROBLEM
AIM:
To implement the coin change problem using python.
ALGORITHM:
Step1. Start the program.
Step2. Two choices for a coin of a particular denominator either to include or to exclude.
Step3. At coins[n-1], we can take as , any instances of that can ie , count(coins ,n, sum-coins
[n- i])then we can move to coins[n-2].
Step4. After moving to coins [n-2], we can’t move back and can’t make choices for coins [n-1]
ie, count (coins , n-1 , sum).
Step5. Find the total number of ways , to we will add these – possible choices. ie) count(coins ,
n ,sum-coins[n-1])+ count(coins , n-1 ,sum ).
Step6. Stop the program.
PROGRAM:
def count(S, target):
# if the total is 0, return 1
if target == 0:
return 1
# return 0 if total becomes negative
if target < 0:
return 0
# initialize the total number of ways to 0
result = 0
# do for each coin
for c in S:
# recur to see if total can be reached by including current coin `c`
result += count(S, target - c)
# return the total number of ways
return result
if __name__ == '__main__':
# `n` coins of given denominations
S = [1, 2, 3]
# total change required
target = 4
print('The total number of ways to get the desired change is', count(S, target))
OUTPUT:
The total number of ways to get the desired change is 7
RESULT:
Thus the program for coin change problem is executed successfully.
DATE:
EX.NO.5 B) DYNAMIC PROGRAMMING-WARSHALL’S AND FLOYD’S ALGORITHM
AIM:
To implement the Warshall’s and Floyd’s algoritm using python.
ALGORITHM:
Step1. Start the program.
Step2. Create a matrix A0 of dimension n*n where n is the number of vertices.
Step3. Now , create a matrix A1 using matrix A0 . The elements in the first column and the
first row left as the are (A[i][k]+A[k][j])if (A[i][j]>A[i][k]+A[k][j].
Step4. Similarly,A2 is created using A1 and similarly A3 and A4 is also created.
Step5. A4 gives the shortest path between each pair of vertices.
Step6. Stop the program.
PROGRAM:
# The number of vertices
nV = 4
INF = 999
# Algorithm implementation
def floyd_warshall(G):
distance = list(map(lambda i: list(map(lambda j: j, i)), G))
# Adding vertices individually
for k in range(nV):
for i in range(nV):
for j in range(nV):
distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j])
print_solution(distance)
# Printing the solution
def print_solution(distance):
for i in range(nV):
for j in range(nV):
if(distance[i][j] == INF):
print("INF", end=" ")
else:
print(distance[i][j], end=" ")
print(" ")
G = [[0, 3, INF, 5],
[2, 0, INF, 4],
[INF, 1, 0, INF],
[INF, INF, 2, 0]]
floyd_warshall(G)
OUTPUT:
0 3 7 5
2 0 6 4
3 1 0 5
5 3 2 0
RESULT:
Thus the program for Warshall’s and Floyd’s algorithm using python has executed
successfully.
DATE:
EX.NO.5 (C) DYNAMIC PROGRAMMING-KNAPSACK PROBLEM
AIM:
To implement the Knapsack problem using python.
ALGORITHM:
Step1. Start the program.
Step2. Maximum value obtained by n-1 items and W weight.
Step3. Vlaue of n th item plus maximum value obtained by n-1 items and W minus the weight of
n th item.
Step4. If the weight of ‘n th’ item is greater than ‘W’ then the n th item cannot be installed.
Step5. Stop the program.
PROGRAM:
def knapSack(W, wt, val, n):
K = [[0 for x in range(W + 1)] for x in range(n + 1)]
# Build table K[][] in bottom up manner
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]
# Driver program to test above function
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))
OUTPUT:
220
RESULT:
Thus the program for the Knapsack problem has executed successfully.
DATE:
EX.NO 6.A) GREEDY TECHNIQUES- DIJKSTRA’S ALGORITHM
AIM:
To implement Dijkstra’s algorithm using python.
ALGORITHM:
Step1. Initialize the distance from the source node S to all other nodes as infinite and to itself
as 0.
Step2. Insert the pair of node, distance for source i.e S, 0 in a DICTIONARY
Step3. While the DICTIONARY is not empty do
Step4. current_source_node = DICTIONARY . get_key (node)_with_smallest_value (dist)
Step5. Remove the key (current_source_node) from the DICTIONARY.
Step6. For every adjacent_node to the current_source_node do
Step7. If ( distance [ adjacent_node ] >
Step8. length_of_path_to_adjacent_node_from_current_source + distance
[ current_source_node ] )
Step9. distance[adjacent_node ] =length_of_path_to_adjacent_node_from_current_source
+distance[ current_source_node ]
Step10. Update the DICTIONARY with the new pair < adjacent_node,
distance [adjacent_node ] >
PROGRAM:
from collections import defaultdict
class Node_Distance :
def __init__(self, name : int, dist : int) :
self.name = name
self.dist = dist
class Graph :
def __init__ (self, node_count : int) :
self.adjlist = defaultdict(list)
self.node_count = node_count
def Add_Into_Adjlist (self, src : int, node_dist : Node_Distance(int,int)) :
self.adjlist[src].append(node_dist)
def Dijkstras_Shortest_Path (self, source : int) :
# Initialize the distance of all the nodes from the source node to infinity
distance = [999999999999] * self.node_count
# Distance of source node to itself is 0
distance[source] = 0
# Create a dictionary of { node, distance_from_source }
dict_node_length = {source: 0}
while dict_node_length :
# Get the key for the smallest value in the dictionary
# i.e Get the node with the shortest distance from the source
current_source_node = min(dict_node_length, key = lambda k: dict_node_length[k])
del dict_node_length[current_source_node]
for node_dist in self.adjlist[current_source_node] :
adjnode = node_dist.name
length_to_adjnode = node_dist.dist
# Edge relaxation
if distance[adjnode] > distance[current_source_node] + length_to_adjnode :
distance[adjnode] = distance[current_source_node] + length_to_adjnode
dict_node_length[adjnode] = distance[adjnode]
for i in range(self.node_count) :
print("Source Node ("+str(source)+") -> Destination Node(" + str(i) + ") : " + str(distance[i]))
def main() :
g = Graph(6)
# Node 0: <1,5> <2,1> <3,4>
g.Add_Into_Adjlist(0, Node_Distance(1, 5))
g.Add_Into_Adjlist(0, Node_Distance(2, 1))
g.Add_Into_Adjlist(0, Node_Distance(3, 4))
# Node 1: <0,5> <2,3> <4,8>
g.Add_Into_Adjlist(1, Node_Distance(0, 5))
g.Add_Into_Adjlist(1, Node_Distance(2, 3))
g.Add_Into_Adjlist(1, Node_Distance(4, 8))
# Node 2: <0,1> <1,3> <3,2> <4,1>
g.Add_Into_Adjlist(2, Node_Distance(0, 1))
g.Add_Into_Adjlist(2, Node_Distance(1, 3))
g.Add_Into_Adjlist(2, Node_Distance(3, 2))
g.Add_Into_Adjlist(2, Node_Distance(4, 1))
# Node 3: <0,4> <2,2> <4,2> <5,1>
g.Add_Into_Adjlist(3, Node_Distance(0, 4))
g.Add_Into_Adjlist(3, Node_Distance(2, 2))
g.Add_Into_Adjlist(3, Node_Distance(4, 2))
g.Add_Into_Adjlist(3, Node_Distance(5, 1))
# Node 4: <1,8> <2,1> <3,2> <5,3>
g.Add_Into_Adjlist(4, Node_Distance(1, 8))
g.Add_Into_Adjlist(4, Node_Distance(2, 1))
g.Add_Into_Adjlist(4, Node_Distance(3, 2))
g.Add_Into_Adjlist(4, Node_Distance(5, 3))
# Node 5: <3,1> <4,3>
g.Add_Into_Adjlist(5, Node_Distance(3, 1))
g.Add_Into_Adjlist(5, Node_Distance(4, 3))
g.Dijkstras_Shortest_Path(0)
print("\n")
g.Dijkstras_Shortest_Path(5)
if __name__ == "__main__" :
main()
OUTPUT:
Source Node (0) -> Destination Node(0) :0
Source Node (0) -> Destination Node(1) :4
Source Node (0) -> Destination Node(2) :1
Source Node (0) -> Destination Node(3) :3
Source Node (0) -> Destination Node(4) :2
Source Node (0) -> Destination Node(5) :4
Source Node (5) -> Destination Node(0) :4
Source Node (5) -> Destination Node(1) :6
Source Node (5) -> Destination Node(2) :3
Source Node (5) -> Destination Node(3) :1
Source Node (5) -> Destination Node(4) :3
Source Node (5) -> Destination Node(5) :0
RESULT: Thus the program to implement the dijkstra’s algorithm has been executed
successfully.
DATE:
EX.NO:6. B) HUFFMAN TREES AND CODES
AIM:
To implement the Huffmann trees and codes using python.
ALGORITHM:
Step1. Calculate the frequency of each character in the string.
Step2. Sort the characters in increasing order of the frequency.
Step3. Make each unique character as a leaf node.
Step4. Create an empty node. Assign the minimum frequency to the left child of empty node and
assign the second minimum frequency to the right child of empty node . Set the value of the
empty node as the sum of the above two minimum frequencies.
Step5. Remove these two minimum frequencies from list and add the sum into the list of frequencies.
Step6. Insert node into the tree.
Step7. Repeat steps 3 to 5 for all the characters.
Step8. For each non-leaf node, assign 0 to the left edge and 1 to the right edge.
PROGRAM:
# A Huffman Tree Node
import heapq
class node:
def __init__(self, freq, symbol, left=None, right=None):
# frequency of symbol
self.freq = freq
# symbol name (character)
self.symbol = symbol
# node left of current node
self.left = left
# node right of current node
self.right = right
# tree direction (0/1)
self.huff = ''
def __lt__(self, nxt):
return self.freq < nxt.freq
# utility function to print huffman
# codes for all symbols in the newly
# created Huffman tree
def printNodes(node, val=''):
# huffman code for current node
newVal = val + str(node.huff)
# if node is not an edge node
# then traverse inside it
if(node.left):
printNodes(node.left, newVal)
if(node.right):
printNodes(node.right, newVal)
# if node is edge node then
# display its huffman code
if(not node.left and not node.right):
print(f"{node.symbol} -> {newVal}")
# characters for huffman tree
chars = ['a', 'b', 'c', 'd', 'e', 'f']
# frequency of characters
freq = [ 5, 9, 12, 13, 16, 45]
# list containing unused nodes
nodes = []
# converting characters and frequencies
# into huffman tree nodes
for x in range(len(chars)):
heapq.heappush(nodes, node(freq[x], chars[x]))
while len(nodes) > 1:
# sort all the nodes in ascending order
# based on their frequency
left = heapq.heappop(nodes)
right = heapq.heappop(nodes)
# assign directional value to these nodes
left.huff = 0
right.huff = 1
# combine the 2 smallest nodes to create
# new node as their parent
newNode = node(left.freq+right.freq, left.symbol+right.symbol, left, right)
heapq.heappush(nodes, newNode)
# Huffman Tree is ready!
printNodes(nodes[0])
OUTPUT:
f -> 0
c -> 100
d -> 101
a -> 1100
b -> 1101
e -> 111
RESULT:
Thus the program to Huffman Trees and code using python has been implemented
successfully.
DATE:
EX.NO:7 ITERATIVE IMPROVEMENT-SIMPLEX METHOD
AIM:To implement Iterative improvement in simplex method using python.
ALGORITHM:
Step1.Standard form.
Step2.Determine stack variable.
Step3.Setting up the tableau.
Step4.Check optimality.
Step5.Identify pivot .
Step6.Create the new tableau.
Step7.Check optimality.
Step8. Identify new pivot variable.
Step9. rom simplex import simplex
PROGRAM:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,20,10000)
y1 = 11.0 + x
y2 = 27.0 - x
y3 = (90-2*x)/5.0
plt.plot(x,y1,label = r'$-x+y\leq11$')
plt.plot(x,y2,label = r'$x+y\leq27$')
plt.plot(x,y3,label = r'$2x+5y\leq90$')
#plt.xlim((0, 20))
#plt.ylim((0, 40))
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
y5 = np.minimum(y1, y2)
plt.fill_between(x, y3, y5, where=y3<y5, color='grey', alpha=0.5)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show()
OUTPUT:
RESULT:
Thus the program to implement simplex method using python has been executed
successfully.
DATE:
EX.NO.8 (A) BACKTRACKING -N QUEEN PROBLEM
AIM:
To implement the N – Queen problem using python.
ALGORITHM:
Step1. Start in the leftmost column
Step2. If all queens are placed, return true
Step3. Try all rows in the current column.
Step4. Do following for every tried row.
a. If the queen can be placed safely in this row then mark this [row, column] as part of the
solution and recursively check if placing, queen here leads to a solution.
b. If placing the queen in [row, column] leads to a solution then return true.
c. If placing queen doesn't lead to a solution then unmark this [row, column]
(Backtrack) and go to step (a) to try other rows.
d. If all rows have been tried and nothing worked,
e. return false to trigger backtracking.
PROGRAM:
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):
# Check this row on left side
for i in range(col):
if board[row][i] == 1:
return False
# Check upper diagonal on left side
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
# Check lower diagonal on left side
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):
# Place this queen in board[i][col]
board[i][col] = 1
# recur to place rest of the queens
if solveNQUtil(board, col + 1) == True:
return True
# If placing queen in board[i][col
# doesn't lead to a solution, then
# queen from board[i][col]
board[i][col] = 0
# if the queen can not be placed in any row in
# this column col then return false
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
# driver program to test above function
solveNQ()
OUTPUT:
0010
1000
0001
0100
RESULT;
Thus the program for N queen problem has executed successfully.
DATE:
EX.NO.8(B) BACKTRACKING -SUBSET SUM PROBLEM
AIM:
To implement subset sum problem using python.
ALGORITHM:
Step1. Start with an empty set.
Step2. Include the next element from list to set.
Step3. If the numbers in the set sum up to given target_sum, It is a solution set
Step4. If the set doesnot sum upto the target_sum or if we have reached the end of my_list, then
backtrack the set until we find a solution set.
Step5. If we get a feasible solution, go to step 2
Step6.If we have traversed all the elements and if no backtracking is possible, then stop without
solution.
PROGRAM:
def sum_of_subset(s,k,rem):
x[k]=1
if s+my_list[k]==target_sum:
list1=[]
for i in range (0,k+1):
if x[i]==1:
list1.append(my_list[i])
print( list1 )
elif s+my_list[k]+my_list[k+1]<=target_sum :
sum_of_subset(s+my_list[k],k+1,rem-my_list[k])
if s+rem-my_list[k]>=target_sum and s+my_list[k+1]<=target_sum :
x[k]=0
sum_of_subset(s,k+1,rem-my_list[k])
my_list=[]
n=int(input("Enter number of elements"))
total=0
for i in range (0,n):
ele=int(input())
my_list.append(ele)
total=total+ele
my_list.sort()
target_sum=int(input("Enter required Sum"))
x=[0]*(n+1)
sum_of_subset(0,0,total)
OUTPUT:
Enter number of elements4
3
2
1
6
Enter required Sum6
[1, 2, 3]
[6]
RESULT:
Thus the program for subset sum problem has executed successfully.
DATE:
EX.NO:9.A) BRANCH AND BOUND-ASSIGNMENT PROBLEM
AIM:
To implement the assignment problem using python.
ALGORITHM:
Step1. For each row of the matrix, find the smallest element and subtract it from every element
in its row.
Step2. Repeat the step 1 for all columns.
Step3. Cover all zeros in the matrix using the minimum number of horizontal and vertical lines.
Step4. Test for Optimality: If the minimum number of covering lines is N, an
optimal assignment is possible. Else if lines are lesser than N, an optimal assignment
is not found and must proceed to step 5.
Step5. Determine the smallest entry not covered by any line. Subtract this entry from
each uncovered row, and then add it to each covered column. Return to step 3
PROGRAM:
# Python program for the above approach
import dlib
# Function to find out the best
# assignment of people to jobs so that
# total cost of the assignment is minimized
def minCost(arr):
# Call the max_cost_assignment() function
# and store the assignment
assignment = dlib.max_cost_assignment(arr)
# Print the optimal cost
print(dlib.assignment_cost(arr, assignment))
# Driver Code
# Given 2D array
arr = dlib.matrix([[3, 5], [10, 1]])
# Function Call
minCost(arr)
OUTPUT:
4
RESULT:
Thus the program to implement the assignment problem using python has executed
successfully.
DATE:
EX.NO:9.B) BRANCH AND BOUND-TRAVELLING SALESMAN PROBLEM
AIM: To implement a program of travelling salesman problem in python
ALGORITHM:
Step1. Consider city 1 as the starting and ending point
Step2. Generate all (n-1) permutaties of cities
Step3. Calculate the cost of every permutation and keep track of the minimum cost permutation
Step4. Return the permutation with minimum cost and path.
PROGRAM:
import math
maxsize = float('inf')
def copyToFinal(curr_path):
final_path[:N + 1] = curr_path[:]
final_path[N] = curr_path[0]
def firstMin(adj, i):
min = maxsize
for k in range(N):
if adj[i][k] < min and i != k:
min = adj[i][k]
return min
def secondMin(adj, i):
first, second = maxsize, maxsize
for j in range(N):
if i == j:
continue
if adj[i][j] <= first:
second = first
first = adj[i][j]
elif(adj[i][j] <= second and
adj[i][j] != first):
second = adj[i][j]
return second
def TSPRec(adj, curr_bound, curr_weight,
level, curr_path, visited):
global final_res
# base case is when we have reached level N
# which means we have covered all the nodes once
if level == N:
# check if there is an edge from
# last vertex in path back to the first vertex
if adj[curr_path[level - 1]][curr_path[0]] != 0:
# curr_res has the total weight
# of the solution we got
curr_res = curr_weight + adj[curr_path[level - 1]]\
[curr_path[0]]
if curr_res < final_res:
copyToFinal(curr_path)
final_res = curr_res
return
# for any other level iterate for all vertices
# to build the search space tree recursively
for i in range(N):
# Consider next vertex if it is not same
# (diagonal entry in adjacency matrix and
# not visited already)
if (adj[curr_path[level-1]][i] != 0 and
visited[i] == False):
temp = curr_bound
curr_weight += adj[curr_path[level - 1]][i]
# different computation of curr_bound
# for level 2 from the other levels
if level == 1:
curr_bound -= ((firstMin(adj, curr_path[level - 1]) +
firstMin(adj, i)) / 2)
else:
curr_bound -= ((secondMin(adj, curr_path[level - 1])
firstMin(adj, i)) / 2)
# curr_bound + curr_weight is the actual lower bound
# for the node that we have arrived on.
# If current lower bound < final_res,
# we need to explore the node further
if curr_bound + curr_weight < final_res:
curr_path[level] = i
visited[i] = True
# call TSPRec for the next level
TSPRec(adj, curr_bound, curr_weight,
level + 1, curr_path, visited)
# Else we have to prune the node by resetting
# all changes to curr_weight and curr_bound
curr_weight -= adj[curr_path[level - 1]][i]
curr_bound = temp
# Also reset the visited array
visited = [False] * len(visited)
for j in range(level):
if curr_path[j] != -1:
visited[curr_path[j]] = True
# This function sets up final_path
def TSP(adj):
curr_bound = 0
curr_path = [-1] * (N + 1)
visited = [False] * N
# Compute initial bound
for i in range(N):
curr_bound += (firstMin(adj, i) +
secondMin(adj, i))
# Rounding off the lower bound to an integer
curr_bound = math.ceil(curr_bound / 2)
# We start at vertex 1 so the first vertex
# in curr_path[] is 0
visited[0] = True
curr_path[0] = 0
# Call to TSPRec for curr_weight
# equal to 0 and level 1
TSPRec(adj, curr_bound, 0, 1, curr_path, visited)
# Driver code
# Adjacency matrix for the given graph
adj = [[0, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 30, 0]]
N=4
# final_path[] stores the final solution
# i.e. the // path of the salesman.
final_path = [None] * (N + 1)
# visited[] keeps track of the already
# visited nodes in a particular path
visited = [False] * N
# Stores the final minimum weight
# of shortest tour.
final_res = maxsize
TSP(adj)
print("Minimum cost :", final_res)
print("Path Taken : ", end = ' ')
for i in range(N + 1):
print(final_path[i], end = ' ')
OUTPUT:
Minimum cost : 80
Path Taken : 0 1 3 2 0
RESULT:
Thus the program to implement the Travelling Salesman Program has executed successfully.