0% found this document useful (0 votes)
23 views33 pages

Daa Lab Manual

The document outlines various algorithms implemented in Python, including recursive and non-recursive methods for calculating factorials and sums, Strassen's matrix multiplication, topological sorting, heap sort, and dynamic programming solutions for coin change, Warshall's and Floyd's algorithms, and the knapsack problem. Each section provides the aim, algorithm steps, program code, output, and result indicating successful execution. Overall, it serves as a comprehensive guide to implementing fundamental algorithms using Python.

Uploaded by

ramya gnanam
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)
23 views33 pages

Daa Lab Manual

The document outlines various algorithms implemented in Python, including recursive and non-recursive methods for calculating factorials and sums, Strassen's matrix multiplication, topological sorting, heap sort, and dynamic programming solutions for coin change, Warshall's and Floyd's algorithms, and the knapsack problem. Each section provides the aim, algorithm steps, program code, output, and result indicating successful execution. Overall, it serves as a comprehensive guide to implementing fundamental algorithms using Python.

Uploaded by

ramya gnanam
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/ 33

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 ] &gt;
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 &lt; adjacent_node,
distance [adjacent_node ] &gt;

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.

You might also like