0% found this document useful (0 votes)
8 views11 pages

Mod 4 Notes DS

The document outlines the curriculum for a module on Graph Algorithms as part of a Computer Science and Engineering program at R. L. Jalappa Institute of Technology. It covers key algorithms such as Bellman-Ford, Johnson's Algorithm, and the Ford-Fulkerson method for maximum flow, along with their applications in finding shortest paths and maximum bipartite matching. Additionally, it discusses the representation of polynomials and the Fast Fourier Transform (FFT) for efficient computation.

Uploaded by

mamathacm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views11 pages

Mod 4 Notes DS

The document outlines the curriculum for a module on Graph Algorithms as part of a Computer Science and Engineering program at R. L. Jalappa Institute of Technology. It covers key algorithms such as Bellman-Ford, Johnson's Algorithm, and the Ford-Fulkerson method for maximum flow, along with their applications in finding shortest paths and maximum bipartite matching. Additionally, it discusses the representation of polynomials and the Fast Fourier Transform (FFT) for efficient computation.

Uploaded by

mamathacm
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

Sri Devaraj Urs Educational Trust (R.

)
R. L. JALAPPA INSTITUTE OF TECHNOLOGY
(Approved by AICTE, New Delhi, Affiliated to VTU, Belagavi & Accredited by NAAC “A” Grade)
Kodigehalli, Doddaballapur- 561 203
Department of CS&E - PG
Subject Code: MCS103
Subject Name: DATA STRUCTURES AND APPLICATIONS
Module Number: 04
Name of the Module: GRAPH ALGORITHMS Scheme:
2024 Prepared by: Dr. Mamatha C M
Professor

Institute Vision
To be a premier Institution by imparting quality Technical education, Professional Training and
Research.
Institute Mission
M1:To provide an outstanding Teaching, Learning and Research environment through Innovative
Practices in Quality Education.
M2: Develop Leaders with high level of Professionalism to have career in the Industry, Zeal for
Higher Education, focus on Entrepreneurial and Societal activities.
Department Vision- PG
To nurture students with advanced expertise and research-oriented skills in Computer Science and
Engineering, empowering them to drive technological innovation and thrive in an evolving global
landscape.
Department Mission- PG
M1: To foster advanced skills in specialized domains of Computer Science and Engineering, equipping
students with the necessary expertise to address contemporary challenges and meet the evolving
demands of the global industry.
M2: To promote cutting-edge research and technological innovation, while cultivating entrepreneurship
and consultancy skills that empower students to contribute to the technological needs of industries,
governments, and society.
PROGRAMME SPECIFIC OUTCOMES (PSOs)
PSO1: Students will have a knowledge of Advanced Software, Hardware, Network Models,
Algorithms
PSO2: Students will be able to develop applications in the areas related to Artificial Intelligence,
Machine Learning, Data Science and IoT for efficient design of computer-based systems.
PROGRAMME EDUCATIONAL OBJECTIVES (PEOs)
PEO1: Our Graduates will have prospective careers in the IT Industry.
PEO2: Our Graduates will exhibit a high level of Professionalism and Leadership skills in work
Environment.
PEO3: Our Graduates will pursue Research, and focus on Entrepreneurship.
Module-4
Graph Algorithms: Bellman - Ford Algorithm; Single source shortest paths in a DAG; Johnson’s Algorithm for
sparse graphs; Flow networks and Ford-Fulkerson method; Maximum bipartite matching. Polynomials and the FFT:
Representation of polynomials; The DFT and FFT; Efficient implementation of FFT.

Bellman - Ford Algorithm; Single source shortest paths in a DAG;


The Bellman-Ford Path algorithm computes the shortest path between nodes. In contrast to the Dijkstra
algorithm which works only for graphs with non-negative relationship weights, Bellman-Ford can also
handle graphs with negative weights provided that the source cannot reach any node involved in a negative
cycle.The Bellman-Ford algorithm can be used to find single-source shortest paths in a Directed Acyclic
Graph (DAG) by iterating through all edges in the graph a fixed number of times (V-1, where V is the
number of vertices), effectively calculating the shortest path from a single source vertex to all other
vertices, even if the graph contains negative edge weights; however, for a DAG, a simpler approach like a
topological sort with dynamic programming is usually more efficient due to the inherent ordering of
nodes.
Key points about using Bellman-Ford on a DAG:
 No negative cycles:
Since a DAG by definition cannot contain cycles, there is no need to worry about detecting negative weight
cycles when using Bellman-Ford on a DAG.
 Topological sort optimization:
For a DAG, you can achieve better efficiency by performing a topological sort on the vertices first, and
then iterating through the edges in the topological order, effectively visiting each node only once while
calculating the shortest path.
 Dynamic programming approach:
When using Bellman-Ford on a DAG, the algorithm essentially implements a dynamic programming
approach where the shortest path to a current node is calculated based on the shortest paths to its
predecessors in the topological ordering.

How it works:
1. Initialization:
Assign a large positive value to the distance of all vertices except the source vertex, which is set to 0.
2. Relaxation loop:
 Iterate through all edges in the graph (in topological order for a DAG).
 For each edge (u, v), check if relaxing the edge (i.e., updating the distance to v based on the distance to
u and the edge weight) can provide a shorter path.
 Repeat this relaxation step (V-1) times, where V is the number of vertices.

Why use Bellman-Ford on a DAG when a simpler approach exists?


Flexibility: Even though a topological sort with dynamic programming is usually preferred for DAGs,
Bellman-Ford can still be used if the code already implements it and you need a generic algorithm for both
DAGs and general directed graphs.
Algorithm: dagShortestPath
Input: (Graph G, Vertex source):
Output: Shotest path
// Step 1: Topological
ordering topOrder =
topologicalSort(G)

// Step 2: Initialize distances


dist = [infinity, infinity, ..., infinity]
dist[source] = 0

// Step 3: Process vertices in topological order


for each vertex u in topOrder:
// Step 4: Relaxation
for each vertex v adjacent to u:
if dist[u] + weight (u, v) < dist[v]:
dist[v] = dist[u] + weight (u, v)

Example

The first four edges that are checked in our graph are A->C, A->E, B->C, and C->A. These first four edge checks do
not lead to any updates of the shortest distances because the starting vertex of all these edges has an infinite distance.

After the edges from vertices A, B, and C are checked, the edges from D are checked. Since the starting point (vertex
D) has distance 0, the updated distances for A, B, and C are the edge weights going out from vertex D.
The next edges to be checked are the edges going out from vertex E, which leads to updated distances for vertices B
and C.

The Bellman-Ford algorithm have now checked all edges 1 time. The algorithm will check all edges 3 more times
before it is finished, because Bellman-Ford will check all edges as many times as there are vertices in the graph,
minus 1.
The algorithm starts checking all edges a second time, starting with checking the edges going out from vertex A.
Checking the edges A->C and A->E do not lead to updated distances.

The next edge to be checked is B->C, going out from vertex B. This leads to an updated distance from vertex D to C
of 5-4=1.
Checking the next edge C->A, leads to an updated distance 1-3=-2 for vertex A.

The check of edge C->A in round 2 of the Bellman-Ford algorithm is actually the last check that leads to
an updated distance for this specific graph. The algorithm will continue to check all edges 2 more times
without updating any distances.
Checking all edges V−1V−1 times in the Bellman-Ford algorithm may seem like a lot, but it is done this
many times to make sure that the shortest distances will always be found.
Time complexity: Topological sorting takes O (V E) time. The relaxation phase takes O(E) time because
each edge is processed once. Therefore, the total time complexity is O(V E).O(n2).
Disadvantage: this algorithm won’t work with negative edges with cycles. To overcome this disadvantage
implement Johnson’s Algorithm
Johnson’s Algorithm for sparse graphs;
The problem is to find the shortest paths between every pair of vertices in a given weighted directed Graph and
weights may be negative. Using Johnson’s algorithm, we can find all pair shortest paths in O(V2log V + VE)
time. Johnson’s algorithm uses both Dijkstra and Bellman-Ford as subroutines. If we apply Dijkstra’s Single Source
shortest path algorithm for every vertex, considering every vertex as the source, we can find all pair shortest paths in
O(V*VLogV) time.
But the problem with Dijkstra’s algorithm is, that it doesn’t work for negative weight edge. The idea of Johnson’s
algorithm is to re-weight all edges and make them all positive, then apply Dijkstra’s algorithm for every vertex.
How to transform a given graph into a graph with all non-negative weight edges?
The idea of Johnson’s algorithm is to assign a weight to every vertex. Let the weight assigned to vertex u be h[u].
We reweight edges using vertex weights. For example, for an edge (u, v) of weight w(u, v), the new weight becomes
w(u, v) + h[u] – h[v]. The great thing about this reweighting is, that all set of paths between any two vertices is
increased by the same amount and all negative weights become non-negative. Consider any path between two
vertices s and t, the weight of every path is increased by h[s] – h[t], and all h[] values of vertices on the path from s
to t cancel each other.
How do we calculate h[] values?
Bellman-Ford algorithm is used for this purpose. Following is the complete algorithm. A new vertex is added to the
graph and connected to all existing vertices. The shortest distance values from the new vertex to all existing vertices
are h[] values.
Algorithm:
 Let the given graph be G. Add a new vertex s to the graph, add edges from the new vertex to all vertices of G.
Let the modified graph be G’.
 Run the Bellman-Ford algorithm on G’ with s as the source. Let the distances calculated by Bellman-Ford be
h[0], h[1], .. h[V-1]. If we find a negative weight cycle, then return. Note that the negative weight cycle cannot
be created by new vertex s as there is no edge to s. All edges are from s.
 Reweight the edges of the original graph. For each edge (u, v), assign the new weight as “original weight + h[u]
– h[v]”.
 Remove the added vertex s and run Dijkstra’s algorithm for every vertex.

How does the transformation ensure non negative weight edges?

The following property is always true about h[] values as they are the shortest
distances. h[v] <= h[u] + w(u, v)
The property simply means that the shortest distance from s to v must be smaller than or equal to the shortest
distance from s to u plus the weight of the edge (u, v). The new weights are w(u, v) + h[u] – h[v]. The value of the
new weights must be greater than or equal to zero because of the inequality “h[v] <= h[u] + w(u, v)”.

Example: Let us consider the following graph.

We add a source s and add edges from s to all vertices of the original graph. In the following diagram s is 4.

We calculate the shortest distances from 4 to all other vertices using Bellman-Ford algorithm. The shortest distances
from 4 to 0, 1, 2 and 3 are 0, -5, -1 and 0 respectively, i.e., h[] = {0, -5, -1, 0}. Once we get these distances, we
remove the source vertex 4 and reweight the edges using following formula. w(u, v) = w(u, v) + h[u] – h[v].
Time Complexity: The main steps in the algorithm are Bellman-Ford Algorithm called once and Dijkstra called V
times. Time complexity of Bellman Ford is O(VE) and time complexity of Dijkstra is O(VLogV). So overall time
complexity is O(V2log V + VE).

Flow networks and Ford-Fulkerson method; Maximum bipartite matching.

The Ford-Fulkerson algorithm is a widely used algorithm to solve the maximum flow problem in a flow network.
The maximum flow problem involves determining the maximum amount of flow that can be sent from a source
vertex to a sink vertex in a directed weighted graph, subject to capacity constraints on the edges.
The algorithm works by iteratively finding an augmenting path, which is a path from the source to the sink in the
residual graph, i.e., the graph obtained by subtracting the current flow from the capacity of each edge. The algorithm
then increases the flow along this path by the maximum possible amount, which is the minimum capacity of the
edges along the path.
What? A matching in a Bipartite Graph is a set of the edges chosen in such a way that no two edges share an
endpoint. A maximum matching is a matching of maximum size (maximum number of edges). In a maximum
matching, if any edge is added to it, it is no longer a matching. There can be more than one maximum matchings for
a given Bipartite Graph.
Why ?
There are many real world problems that can be formed as Bipartite Matching. For example, consider the following
problem:
“There are M job applicants and N jobs. Each applicant has a subset of jobs that he/she is interested in. Each job
opening can only accept one applicant and a job applicant can be appointed for only one job. Find an assignment of
jobs to applicants in such that as many applicants as possible get jobs.”

How: We strongly recommend to read the following post first. “Ford-Fulkerson Algorithm for Maximum Flow
Problem”
Maximum Bipartite Matching and Max Flow Problem :
Maximum Bipartite Matching (MBP) problem can be solved by converting it into a flow network (See this video to
know how did we arrive this conclusion). Following are the steps.
1) Build a Flow Network : There must be a source and sink in a flow network. So we add a source and add edges
from source to all applicants. Similarly, add edges from all jobs to sink. The capacity of every edge is marked as 1
unit.

2) Find the maximum flow: We use Ford-Fulkerson algorithm to find the maximum flow in the flow network built in
step 1. The maximum flow is actually the MBP we are looking for.
How to implement the above approach?
Let us first define input and output forms. Input is in the form of Edmonds matrix which is a 2D array
‘bpGraph[M][N]’ with M rows (for M job applicants) and N columns (for N jobs). The value bpGraph[i][j] is 1
if i’th applicant is interested in j’th job, otherwise 0.

Output is number maximum number of people that can get jobs.


A simple way to implement this is to create a matrix that represents adjacency matrix representation of a directed
graph with M+N+2 vertices. Call the fordFulkerson() for the matrix. This implementation requires O((M+N)*(M+N))
extra space.
Extra space can be reduced and code can be simplified using the fact that the graph is bipartite and capacity of every
edge is either 0 or 1. The idea is to use DFS traversal to find a job for an applicant (similar to augmenting path in
Ford-Fulkerson). We call bpm() for every applicant, bpm() is the DFS based function that tries all possibilities to
assign a job to the applicant.
In bpm(), we one by one try all jobs that an applicant ‘u’ is interested in until we find a job, or all jobs are tried
without luck. For every job we try, we do following.
If a job is not assigned to anybody, we simply assign it to the applicant and return true. If a job is assigned to
somebody else say x, then we recursively check whether x can be assigned some other job. To make sure that x
doesn’t get the same job again, we mark the job ‘v’ as seen before we make recursive call for x. If x can get other job,
we change the applicant for job ‘v’ and return true. We use an array maxR[0..N-1] that stores the applicants assigned
to different jobs.
If bmp() returns true, then it means that there is an augmenting path in flow network and 1 unit of flow is added to
the result in maxBPM().
Time Complexity: O(V*E)
The time complexity of the above algorithm is O(V*E) where V is the number of vertices in the graph and E is the
number of edges. The algorithm iterates over each vertex in the graph and then performs a DFS on the corresponding
edges to find the maximum bipartite matching.
Polynomials and the FFT:
Representation of polynomials;
A polynomial in the variable is a representation of a function
A Discrete Fourier Transform (DFT) is a mathematical operation that converts a discrete signal from the time
domain to the frequency domain, while a Fast Fourier Transform (FFT) is a highly efficient algorithm used to
compute the DFT, significantly reducing the number of calculations required, making it practical for large datasets in
applications like signal processing and image analysis.
Key points about DFT and

FFT: DFT:
Represents a signal's frequency components by calculating a set of complex numbers based on a specific formula.
Requires O(N^2) operations for N data points, making it computationally expensive for large datasets.
Directly applies the Fourier transform formula to discrete data.

FFT:
An algorithm that leverages the inherent symmetries in the DFT to significantly decrease the number of
computations needed.
Utilizes a divide-and-conquer strategy, breaking down the DFT calculation into smaller, more manageable sub-
problems.
Has a computational complexity of O(N log N), making it much faster than the direct DFT for large data sets.
Efficient implementation of FFT:
Cooley-Tukey Algorithm:
The most widely used FFT algorithm, which recursively splits the input data into even and odd indices, then
combines the results to calculate the DFT.

Radix-2 FFT:
A common variant of the Cooley-Tukey algorithm where the data is divided into groups of 2 at each stage, utilizing
"butterfly operations" to perform the necessary calculations efficiently.

Important factors for efficient FFT implementation:


Data arrangement:
Optimizing the order of input data to minimize the number of memory accesses and improve performance.
Complex multiplication optimization:
Implementing efficient methods for complex number multiplication, as this is a key operation in the FFT algorithm.
Hardware acceleration:
Utilizing specialized hardware like digital signal processors (DSPs) or GPUs to further improve FFT performance
for demanding applications.
Applications of FFT:
Spectral analysis: Analyzing the frequency components of signals in various fields like audio processing, vibration
analysis, and spectroscopy.
Digital signal processing: Filtering, convolution, and other signal processing tasks
Image processing: Applying filters in the frequency domain for image enhancement and noise reduction

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy