Unit-4 (1)
Unit-4 (1)
Tech
Course Code: AIML303/AIDS303/IOT303
Course Name: Design & Analysis of Algorithms
Unit-4
By:
Dr. Monika Bansal
Breadth First Search
Breadth First Search
Breadth First Search
Breadth First Search
Breadth First Search
Breadth First Search
Time and Space Complexity
The depth-first search (DFS) algorithm starts with the initial node of graph G
and goes deeper until we find the goal node or the node with no children.
The step by step process to implement the DFS traversal is given as follows -
1. First, create a stack with the total number of vertices in the graph.
2. Now, choose any vertex as the starting point of traversal, and push that
vertex into the stack.
3. After that, push a non-visited vertex (adjacent to the vertex on the top of the
stack) to the top of the stack.
4. Now, repeat steps 3 and 4 until no vertices are left to visit from the vertex on
the stack's top.
5. If no vertex is left, go back and pop a vertex from the stack.
6. Repeat steps 2, 3, and 4 until the stack is empty.
DFS
DFS
STACK: H
Step 2 - POP the top element from the stack, i.e., H, and print it. Now, PUSH
all the neighbors of H onto the stack hat are in ready state.
Print: H
STACK: A
DFS
Step 3 - POP the top element from the stack, i.e., A, and print it. Now, PUSH
all the neighbors of A onto the stack
Print: A
STACK: B, D
Step 4 - POP the top element from the stack, i.e., D, and print it. Now, PUSH
all the neighbors of D onto the stack
Print: D
STACK: B, F
DFS
Step 5 - POP the top element from the stack, i.e., F, and print it. Now, PUSH
all the neighbors of F onto the stack
Print: F
STACK: B
Step 6 - POP the top element from the stack, i.e., B, and print it. Now, PUSH
all the neighbors of B onto the stack
DFS
Step 5 - POP the top element from the stack, i.e., F, and print it. Now, PUSH
all the neighbors of F onto the stack
Print: F
STACK: B
Step 6 - POP the top element from the stack, i.e., B, and print it. Now, PUSH
all the neighbors of B onto the stack
Print: B
STACK: C
DFS
Step 7 - POP the top element from the stack, i.e., C, and print it. Now, PUSH
all the neighbors of C onto the stack
Print: C
STACK: E, G
Step 8 - POP the top element from the stack, i.e., G and PUSH all the
neighbors of G onto the stack
Print: G
STACK: E
DFS
Step 9 - POP the top element from the stack, i.e., E and PUSH all the
neighbors of E onto the stack
Print: E
STACK:
Now, all the graph nodes have been traversed, and the stack is empty.
Time and Space Complexity of DFS
1. Detecting cycle in a graph: A graph has a cycle if and only if we see a back
edge during DFS. So we can run DFS for the graph and check for back edges.
2. Path Finding: We can specialize the DFS algorithm to find a path between
two given vertices u and z.
3. Topological Sorting: Topological Sorting is mainly used for scheduling jobs from the
given dependencies among jobs. In computer science, applications of this type arise in
instruction scheduling, ordering of formula cell evaluation when recomputing formula
values in spreadsheets, logic synthesis, determining the order of compilation tasks to
perform in makefiles, data serialization, and resolving symbol dependencies in linkers.
4. To test if a graph is bipartite: We can augment either BFS or DFS when we first
discover a new vertex, color it opposite its parents, and for each other edge, check it
doesn’t link two vertices of the same color. The first vertex in any connected component
can be red or black.
6. Solving puzzles with only one solution: such as mazes. (DFS can be adapted
to find all solutions to a maze by only including nodes on the current path in the
visited set.).
7. Web crawlers: Depth-first search can be used in the implementation of web
crawlers to explore the links on a website.
8. Maze generation: Depth-first search can be used to generate random mazes.
9. Model checking: Depth-first search can be used in model checking, which is
the process of checking that a model of a system meets a certain set of
properties.
10. Backtracking: Depth-first search can be used in backtracking algorithms.
Bipartite Graph
Two vertices of the same set will be connected, which contradicts the
Bipartite definition saying there are two sets of vertices and no vertex will be
connected with any other vertex of the same set.
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Bipartite Graph
Not a Bipartite Graph
Not a Bipartite Graph
Not a Bipartite Graph
Not a Bipartite Graph
Not a Bipartite Graph
Not a Bipartite Graph
Not a Bipartite Graph
Time and Space Complexity
We are traversing through all the nodes and edges. So time complexity will
be O(V + E) where V = vertices or node, E = edges.
We use a coloured array, queue, and an adjacency list for the graph. So the
space complexity will be O(V) + O(V) + O(V + E).
Graph Coloring
Time Complexity: O(M^V), where M is the total colours needed and V is the
total vertices
Space Complexity: O(V), as extra space is used for colouring vertices.
Approach 2: Backtracking
In this approach, the idea is to color a vertex and while coloring any adjacent
vertex, choose a different color. Similarly, color every possible vertex
following the restrictions, till any further vertex is left coloring. In any case, if
all adjacent vertices for a given vertex are colored, then backtrack and
change color.
Approach 2: Backtracking
Approach 2: Backtracking
Algorithm
• Consider a color and check if it is valid i.e. from the given vertex check
whether its adjacent vertices have been coloured with the same color.
• If true, pick a different colour, else continue colouring the vertices.
• If no other color is left un-used, then backtrack.
Time Complexity: O(M^V), in the worst case.
Space Complexity: O(V), as extra space is used for colouring vertices.
What is Hamiltonian Cycle?
Algorithm
• Create an empty path array and add vertex 0 to it.
• Start adding other vertices by checking if they have been added
previously or not.
• We can check this by creating a visiting array to check if the vertex
has already been visited or is adjacent to the previously added
vertex.
• If any such vertex is found, add it to the path array and backtrack
from there.
• If no such vertex is found we return False.
Hamiltonian Cycle using Backtracking Algorithm
Step 1:
Tour is
started
from vertex
1. There is
no path
from 5 to 1.
So it’s the
dead-end
state
Hamiltonian Cycle using Backtracking Algorithm
Step 2:
Backtrack to the
node from where
the new path
can be explored,
that is 3 here
Hamiltonian Cycle using Backtracking Algorithm
Step 3: New
path also leads
to a dead end so
backtrack and
explore all
possible paths
Hamiltonian Cycle using Backtracking Algorithm
Step 4: Next
path is also
leading to a
dead-end so
keep
backtracking
until we get
some node that
can generate a
new path, i.e
.vertex 2 here
Hamiltonian Cycle using Backtracking Algorithm
Step 5: One
path leads to
Hamiltonian
cycle, next leads
to a dead end so
backtrack and
explore all
possible paths at
each vertex
Hamiltonian Cycle using Backtracking Algorithm
Example 1:
Input: set[] = {4, 16, 5, 23, 12}, sum = 9
Output = true
Subset {4, 5} has the sum equal to 9.
Sum of Subsets Problem
Example 2:
Input: set[] = {2, 3, 5, 6, 8, 10}, sum = 10
Output = true
There are three possible subsets that have the sum equal to 10.
Subset1: {5, 2, 3}
Subset2: {2, 8}
Subset3: {10}
Sum of Subsets Problem
• Recursion/Backtracking
• Dynamic programming
Sum of Subsets Problem