You are on page 1of 6

Indian Institute of Information Technology Vadodara

Lab Assignment 8

CS661: Algorithms and DBMS Lab

1). Implement a weighted Graph and do the following.


a). Print Graph elements using Breadth First Search Walk.
b). Print Graph elements using Depth First Search Walk.
c). Find number of components in the Graph
d). Check whether there is a cycle in the Graph.
e). Find a minimum cost spanning tree of the Graph (use any algorithm).

Submitted By: Neha Pipada


(ID:202263003)

a). Print Graph elements using Breadth First Search Walk.


Solution:
graph = {
'5' : ['3','7'],
'3' : ['2', '4'],
'7' : ['8'],
'2' : [],
'4' : ['8'],
'8' : []
}
visited = [] # List for visited nodes.
queue = [] #Initialize a queue

def bfs(visited, graph, node): #function for BFS


visited.append(node)
queue.append(node)

while queue: # Creating loop to visit each node


m = queue.pop(0)
print (m, end = " ")

for neighbour in graph[m]:


if neighbour not in visited:
visited.append(neighbour)
queue.append(neighbour)

# Driver Code
print("Following is the Breadth-First Search")
bfs(visited, graph, '5')
Output:

b). Print Graph elements using Depth First Search Walk.


Solution:
# Using a Python dictionary to act as an adjacency list
graph = {
'5' : ['3','7'],
'3' : ['2', '4'],
'7' : ['8'],
'2' : [],
'4' : ['8'],
'8' : []
}

visited = set() # Set to keep track of visited nodes of graph.

def dfs(visited, graph, node): #function for dfs


if node not in visited:
print (node)
visited.add(node)
for neighbour in graph[node]:
dfs(visited, graph, neighbour)
print("Following is the Depth-First Search")
dfs(visited, graph, '5')

Output:

c). Find number of components in the Graph


Solution:
class Graph:

def __init__(self, V):

# No. of vertices
self.V = V

# Pointer to an array containing


# adjacency lists
self.adj = [[] for i in range(self.V)]
# Function to return the number of
# connected components in an undirected graph
def NumberOfconnectedComponents(self):

# Mark all the vertices as not visited


visited = [False for i in range(self.V)]

# To store the number of connected


# components
count = 0

for v in range(self.V):
if (visited[v] == False):
self.DFSUtil(v, visited)
count += 1

return count

def DFSUtil(self, v, visited):

# Mark the current node as visited


visited[v] = True

# Recur for all the vertices


# adjacent to this vertex
for i in self.adj[v]:
if (not visited[i]):
self.DFSUtil(i, visited)

# Add an undirected edge


def addEdge(self, v, w):

self.adj[v].append(w)
self.adj[w].append(v)
if __name__=='__main__':

g = Graph(5)
g.addEdge(1, 0)
g.addEdge(2, 3)
g.addEdge(3, 4)
print("Number Of connected Components")
print(g.NumberOfconnectedComponents())

Output:

d)Check whether there is a cycle in the Graph.

Solution:
class Graph:

def __init__(self, edges, a):


# Adjacency list representation
self.adjacencyList = [[] for _ in range(a)]

for (source, destination) in edges:


self.adjacencyList[source].append(destination)
self.adjacencyList[destination].append(source)

# Function for DFS_Traversal traversal


def DFS_Traversal(graph, v, visited, parent_node=-1):

# assign current node as


visited[v] = True

# loop for every edge (v, u)


for u in graph.adjacencyList[v]:

# if `u` is not visited


if not visited[u]:
if DFS_Traversal(graph, u, visited, v):
return True

# if `u` is visited, and `u` is not a parent_node


elif u != parent_node:
# found a back-edge
return True

# No back-edges were found


return False

if __name__ == '__main__':

# List of graph edges


edges = [
(0, 1), (0, 2), (2, 3), (2, 4), (3, 4)
]

# number of nodes in the graph


a=5

# construct graph
constructed_graph = Graph(edges, a)

# note the visited and unvisited nodes


visited = [False] * a

# perform DFS traversal from source_node


if DFS_Traversal(constructed_graph, 0, visited):
print('Cycle detected')
else:
print('Cycle not detected')

Output:
e)Find a minimum cost spanning tree of the Graph (use any algorithm).
class Graph:

def __init__(self, vertices):


self.V = vertices # No. of vertices
self.graph = []
# 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


# (truly uses path compression technique)
def find(self, parent, i):
if parent[i] != i:
# Reassignment of node's parent to root node as
# path compression requires
parent[i] = self.find(parent, parent[i])
return 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):

# Attach smaller rank tree under root of


# high rank tree (Union by Rank)
if rank[x] < rank[y]:
parent[x] = y
elif rank[x] > rank[y]:
parent[y] = x

# If ranks are same, then make one as root and increment its rank by one
else:
parent[y] = x
rank[x] += 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)
y = self.find(parent, v)

# If including this edge doesn't


# cause cycle, then include it in result
# and increment the index of 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)

if __name__ == '__main__':
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:

You might also like