You are on page 1of 12

7.

Write a program to find minimum cost spanning tree using Prim’s algorithm

import sys # Library for INT_MAX

class Graph():

def __init__(self, vertices):


self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]

# A utility function to print the constructed MST stored in parent[]


def printMST(self, parent):
print ("Edge \tWeight")
for i in range(1, self.V):
print (parent[i], "-", i, "\t", self.graph[i][parent[i]])

# A utility function to find the vertex with


# minimum distance value, from the set of vertices
# not yet included in shortest path tree
def minKey(self, key, mstSet):

# Initialize min value


min = sys.maxsize

for v in range(self.V):
if key[v] < min and mstSet[v] == False:
min = key[v]
min_index = v

return min_index

# Function to construct and print MST for a graph


# represented using adjacency matrix representation
def primMST(self):

# Key values used to pick minimum weight edge in cut


key = [sys.maxsize] * self.V
parent = [None] * self.V # Array to store constructed MST
# Make key 0 so that this vertex is picked as first vertex
key[0] = 0
mstSet = [False] * self.V

parent[0] = -1 # First node is always the root of

for cout in range(self.V):

1
# Pick the minimum distance vertex from
# the set of vertices not yet processed.
# u is always equal to src in first iteration
u = self.minKey(key, mstSet)

# Put the minimum distance vertex in


# the shortest path tree
mstSet[u] = True

# Update dist value of the adjacent vertices


# of the picked vertex only if the current
# distance is greater than new distance and
# the vertex in not in the shortest path tree
for v in range(self.V):

# graph[u][v] is non zero only for adjacent vertices of m


# mstSet[v] is false for vertices not yet included in MST
# Update the key only if graph[u][v] is smaller than key[v]
if self.graph[u][v] > 0 and mstSet[v] == False and key[v] > self.graph[u][v]:
key[v] = self.graph[u][v]
parent[v] = u

self.printMST(parent)

g = Graph(5)
g.graph = [ [0, 2, 0, 6, 0],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]]

g.primMST();

Expected Output:
Edge Weight
0-1 2
1-2 3
0-3 6
1-4 5

2
8. Write a program to find minimum cost spanning tree using Kruskal’s algorithm

# Python program for Kruskal's algorithm to find


# Minimum Spanning Tree of a given connected,
# undirected and weighted graph

from collections import defaultdict


# Class to represent a graph
class Graph:
def __init__(self, vertices):
self.V = vertices # No. of vertices
self.graph = [] # default dictionary
# to store graph
# function to add an edge to graph
def addEdge(self, u, v, w):
self.graph.append([u, v, w])
# A utility function to find set of an element i
# (uses path compression technique)
def find(self, parent, i):
if parent[i] == i:
return i
return self.find(parent, parent[i])
# A function that does union of two sets of x and y
# (uses union by rank)
def union(self, parent, rank, x, y):
xroot = self.find(parent, x)
yroot = self.find(parent, y)
# Attach smaller rank tree under root of
# high rank tree (Union by Rank)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:

3
parent[yroot] = xroot
# If ranks are same, then make one as root
# and increment its rank by one
else:
parent[yroot] = xroot
rank[xroot] += 1
# The main function to construct MST using Kruskal's algorithm
def KruskalMST(self):
result = [ ] # This will store the resultant MST
# An index variable, used for sorted edges
i=0
# An index variable, used for result[ ]
e=0
# Step 1: Sort all the edges in
# non-decreasing order of their
# weight. If we are not allowed to change the
# given graph, we can create a copy of graph
self.graph = sorted(self.graph,
key=lambda item: item[2] )
parent = [ ]
rank = [ ]
# Create V subsets with single elements
for node in range(self.V):
parent.append(node)
rank.append(0)
# Number of edges to be taken is equal to V-1
while e < self.V - 1:
# Step 2: Pick the smallest edge and increment
# the index for next iteration
u, v, w = self.graph[i]
i=i+1
x = self.find(parent, u)

4
y = self.find(parent, v)
# If including this edge does't
# cause cycle, include it in result
# and increment the indexof result
# for next edge
if x != y:
e=e+1
result.append([u, v, w])
self.union(parent, rank, x, y)
# Else discard the edge
minimumCost = 0
print ("Edges in the constructed MST")
for u, v, weight in result:
minimumCost += weight
print("%d -- %d == %d" % (u, v, weight))
print("Minimum Spanning Tree" , minimumCost)
# Driver code
g = Graph(4)
g.addEdge(0, 1, 10)
g.addEdge(0, 2, 6)
g.addEdge(0, 3, 5)
g.addEdge(1, 3, 15)
g.addEdge(2, 3, 4)
# Function call
g.KruskalMST()
Output:
Following are the edges in the constructed MST
2 -- 3 == 4
0 -- 3 == 5
0 -- 1 == 10
Minimum Cost Spanning Tree: 19

5
9. Write a program to find a single source shortest path for a given graph.

# Python program for Dijkstra's single


# source shortest path algorithm. The program is
# for adjacency matrix representation of the graph
# Library for INT_MAX

import sys

class Graph():

def __init__(self, vertices):


self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]

def printSolution(self, dist):


print("Vertex \tDistance from Source")
for node in range(self.V):
print(node, "\t", dist[node])

# A utility function to find the vertex with


# minimum distance value, from the set of vertices
# not yet included in shortest path tree
def minDistance(self, dist, sptSet):

# Initialize minimum distance for next node


min = sys.maxsize

# Search not nearest vertex not in the


# shortest path tree
for u in range(self.V):
if dist[u] < min and sptSet[u] == False:
min = dist[u]
min_index = u

return min_index

# Function that implements Dijkstra's single source


# shortest path algorithm for a graph represented
# using adjacency matrix representation
def dijkstra(self, src):

dist = [sys.maxsize] * self.V


dist[src] = 0
sptSet = [False] * self.V

for cout in range(self.V):

# Pick the minimum distance vertex from


# the set of vertices not yet processed.

6
# x is always equal to src in first iteration
x = self.minDistance(dist, sptSet)

# Put the minimum distance vertex in the


# shortest path tree
sptSet[x] = True

# Update dist value of the adjacent vertices


# of the picked vertex only if the current
# distance is greater than new distance and
# the vertex in not in the shortest path tree
for y in range(self.V):
if self.graph[x][y] > 0 and sptSet[y] == False and \
dist[y] > dist[x] + self.graph[x][y]:
dist[y] = dist[x] + self.graph[x][y]

self.printSolution(dist)

# Driver program
g = Graph(9)
g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],
[4, 0, 8, 0, 0, 0, 0, 11, 0],
[0, 8, 0, 7, 0, 4, 0, 0, 2],
[0, 0, 7, 0, 9, 14, 0, 0, 0],
[0, 0, 0, 9, 0, 10, 0, 0, 0],
[0, 0, 4, 14, 10, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 2, 0, 1, 6],
[8, 11, 0, 0, 0, 0, 1, 0, 7],
[0, 0, 2, 0, 0, 0, 6, 7, 0]
];

g.dijkstra(0);

Output:

Vertex Distance from Source


0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14

7
10. Write a program to find the solution for job sequencing with deadlines problems

# Program to find the maximum profit job sequence from a given array of
jobs with deadlines and profits function to schedule the jobs take 2
arguments array and no of jobs to schedule
def printJobScheduling(arr, t):
# length of array
n = len(arr)
# Sort all jobs according to
# decreasing order of profit
for i in range(n):
for j in range(n - 1 - i):
if arr[j][2] < arr[j + 1][2]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
# To keep track of free time slots
result = [False] * t
# To store result (Sequence of jobs)
job = ['-1'] * t
# Iterate through all given jobs
for i in range(len(arr)):
# Find a free slot for this job
# (Note that we start from the
# last possible slot)
for j in range(min(t - 1, arr[i][1] - 1), -1, -1):
# Free slot found
if result[j] is False:
result[j] = True
job[j] = arr[i][0]
break
# print the sequence
print(job)
# Driver COde
arr = [['a', 2, 100], # Job Array
['b', 1, 19],
['c', 2, 27],
['d', 1, 25],
['e', 3, 15]]
print("Following is maximum profit sequence of jobs")
# Function Call
printJobScheduling(arr, 3)

Output:

Following is maximum profit sequence of jobs


cae

8
12. Write a program to solve Sum of subsets problem for a given set of distinct numbers using
backtracking.

from collections import deque

# Recursive function to print all distinct subsets of `S`.


# `S` ——> input set
# `i` ——> index of next element in set `S` to be processed
# `out` ——> list to store elements of a subset

def printPowerSet(S, i, out=deque()):

# if all elements are processed, print the current subset


if i < 0:
print(list(out))
return

# include the current element in the current subset and recur


out.append(S[i])
printPowerSet(S, i - 1, out)

# backtrack: exclude the current element from the current subset


out.pop()

# remove adjacent duplicate elements


while i > 0 and S[i] == S[i - 1]:
i=i-1

# exclude the current element from the current subset and recur
printPowerSet(S, i - 1, out)

# Wrapper over `printPowerSet()` function


def findPowerSet(S):

# sort the set


S.sort()

# print the power set


printPowerSet(S, len(S) - 1)

if __name__ == '__main__':
S = [1, 3, 1]
findPowerSet(S)

Output:
[3, 1, 1]
[3, 1]

9
[3]
[1, 1]
[1]
[]

13. Implement N Queen's problem using Back Tracking

# Python3 program to solve N Queen Problem using backtracking


global N
N =4

def printSolution(board):
for i in range(N):
for j in range(N):
print (board[i][j], end = " ")
print()

# A utility function to check if a queen can


# be placed on board[row][col]. Note that this
# function is called when "col" queens are
# already placed in columns from 0 to col -1.
# So we need to check only left side for
# attacking queens
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):

10
# base case: If all queens are placed
# then return true
if col >= N:
return True

# Consider this column and try placing


# this queen in all rows one by one
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

# This function solves the N Queen problem using Backtracking. It


mainly uses solveNQUtil() to solve the problem. It returns false if
queens cannot be placed, otherwise return true and placement of
queens in the form of 1s. note that there may be more than one
# solutions, this function prints one of the feasible solutions.

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 Code
solveNQ()

Output: The 1 values indicate placements of queens

11
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0

12

You might also like