0% found this document useful (0 votes)
7 views54 pages

unit-3 r23

Uploaded by

lakshmi prasanna
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)
7 views54 pages

unit-3 r23

Uploaded by

lakshmi prasanna
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/ 54

UNIT – III

Greedy Method: General Method, Job Sequencing with deadlines, Knapsack Problem, Minimum
cost spanning trees, Single Source Shortest Paths
Dynamic Programming: General Method, All pairs shortest paths, Single Source Shortest Paths–
General Weights (Bellman Ford Algorithm), Optimal Binary Search Trees, 0/1 Knapsack, String
Editing, Travelling Salesperson problem

Why should we choose a greedy algorithm?


 The greedy approach has a few characteristics that might make it suitable for optimization.
 One reason to choose a greedy algorithm is to achieve the most feasible solution
immediately.
 If we take the activity selection problem as a reference that is explained below. We can
observe that if more activities can be done before finishing the current activity, then these
activities can be performed within the same time.
 Another reason to choose this algorithm is to divide a problem recursively based on a
condition. This ensures that there is no need to combine all the solutions.
 While considering the activity selection problem, we achieve the “recursive division” step by
scanning a list of items only once and considering certain activities.
 Greedy choice property: Greedy Choice property tells us that we can obtain a globally
optimal solution by obtaining a solution that is either a locally optimal solution or a Greedy
solution.
 The choice made by a Greedy algorithm may depend on the earlier choices but will never
depend on the future.
 A Greedy choice is made one after another and this helps to reduce the given problem to a
smaller one.
Optimal substructure: A problem is said to exhibit an optimal substructure if and only if an
optimal solution to the problem also contains the optimal solutions to the sub problems. That
means we can solve sub problems and build up the solutions which could help us to solve
larger problems.
NOTE: Making locally optimal choices might not work always. Hence, from this point, it is
understandable that Greedy algorithms might not always give the best solutions.
Greedy Method:
Following are a few points about the greedy method.
 The first note point is that we have to find the best method/option out of many present ways.
 In this method, we will be deciding the output by focusing on the first stage. We don’t think about
the future.
 The greedy method may or may not give the best output.
A greedy Algorithm solves problems by making the choice that seems to be the best at that
particular moment. There are many optimization problems that can be determined using a
greedy algorithm. A greedy algorithm may provide a solution that is close to optimal to some
issues that might have no efficient solution. A greedy algorithm works if a problem has the
following two properties:
Examples:
Following are a few examples of Greedy algorithms
 Machine scheduling
 Fractional Knapsack Problem
 Minimum Spanning Tree
 Huffman Code
 Job Sequencing
 Activity Selection Problem
Components of Greedy Algorithm
Greedy algorithms consist of the following five components −
 A candidate set − A solution is created with the help of a candidate set.
 A selection function − It is used to choose the best candidate that is to be added to the solution.
 A feasibility function − A feasibility function is useful in determining whether a candidate can be
used to contribute to the solution or not.
 An objective function − This is used to assign a value to a solution or a partial solution.
 A solution function − A solution function is used to indicate whether a complete solution has been
reached or not.
Areas of Application
The greedy approach is used to solve many problems. Out of all the problems, here we have a
few of them as follows:
 One of the applications could be finding the shortest path between two vertices using Dijkstra’s
algorithm.
 Another is finding the minimal spanning tree in a graph using Prim’s /Kruskal’s algorithm
Greedy Algorithm:
ALgorithm Greedy(A,n)
{
solution := 0; //Initializing the solution
for i:= 1 to n do
{
x := select(A);
if Feasible(solution,x) then
solution := Union(solution, x);
}
return solution;

Characteristics of Greedy approach


1. The greedy approach consists of an ordered list of resources(profit, cost, value, etc.)
2. The greedy approach takes the maximum of all the resources(max profit, max value, etc.)
3. For example, in the case of the fractional knapsack problem, the maximum value/weight is taken
first based on the available capacity.
Applications of Greedy Algorithms

1. To find an optimal solution (Activity selection, Fractional Knapsack, Job Sequencing, Huffman
Coding).
2. To find close to the optimal solution for NP-Hard problems like TSP.
Advantages and Disadvantages of Greedy Approach
Following are the various advantages and disadvantages of the greedy approach.
Advantages
 It is easy to implement.
 Has fewer time complexities.
 Can be used for the purpose of optimization or finding close to optimization in the case of NP-Hard
problems.
Disadvantages
 One disadvantage of this algorithm is that the local optimal solution may not always be globally
optimal.

Minimum Coin Change Problem


Given a set of coins and a value, we have to find the minimum number of coins which satisfies the
value.
Example
coins[] = {5,10,20,25}
value = 50

Possible Solutions
{coin * count}
{5 * 10} = 50 [10 coins]
{5 * 8 + 10 * 1} = 50 [9 coins] goes on.
{10 * 5} = 50 [5 coins]
{20 * 2 + 10 * 1} = 50 [3 coins]
{20 * 2 + 5 * 2} = 50 [4 coins]
{25 * 2} = 50 [2 coins]
etc etc

Best Solution
Two 25 rupees. Total coins two.
25 * 2 = 50

Minimum Coin Change Problem Algorithm


1. Get coin array and a value.
2. Make sure that the array is sorted.
3. Take coin[i] as much we can.
4. Increment the count.
5. If solution found,
break it.
6. Otherwise,
follow step 3 with the next coin. coin[i+1].
4. Finally, print the count.
Example
coin[] = {25,20,10,5}
value = 50
Take coin[0] twice. (25+25 = 50).
Total coins = 2 (25+25)
Example
coin[] = {25,20,10,5}
value = 70
Take coin[0] twice. (25+25 = 50).
If we take coin[0] one more time, the end result will exceed the given value. So, change the next coin.
Take coin[1] once. (50 + 20 = 70).
Total coins needed = 3 (25+25+20).
In this approach, we are not bothering about the overall result.
We just pick the best option in each step and hoping that it might produce the best overall result.
Hence, this method called as the greedy approach.
For Example:
Let us consider the example of the container loading problem.
In a container loading problem, a large ship is loaded with cargo. The cargo has containers of equal
sizes but different weights. The cargo capacity is of the ship is cp.
We need to load the containers in the ship in such a way that the ship has maximum containers.
For example, let us say there are a total of 4 containers with weights: w1=20, w2=60, w33=40, w4=25.
Let cp = 80. Then, to load maximum containers we will load container-1,3,4.
We will load the containers in the order of increasing weights so that maximum containers load inside
the ship. Here, the order of loading is container1→container4→container3.
Job Sequencing With Deadlines
Here is the process of Job sequencing in brief.

 Firstly, you are given a set of jobs.


 Each job has a set of defined deadlines and some profit associated with it.
 A job is profited only if that job is completed within the given deadline.
 Another point to note is that only one processor will be available for processing all the jobs.
 The processor will take one unit of time in order to complete a job.

The problem states-Approach to Solution


 A feasible solution is a subset of jobs such that each job of the subset is completed within the given
deadline.
 The value of a feasible solution is said to be the sum of the profit of all the jobs contained in that
subset.
 An optimal solution to the problem would be a feasible solution that gives the maximum profit.
Greedy Algorithm Approach-
We adopt the greedy algorithm in order to determine the selection of the next job to get an
optimal solution.
Below is the greedy algorithm that is always supposed to give an optimal solution to the job
sequencing problem.
Step-01:
 Sorting of all the given jobs in the decreasing order of their profit.
Step-02:
 Checking the value of the maximum deadline.
 Drawing a Gantt chart such that the maximum time on the Gantt chart is the value of the maximum
deadline.
Step-03:
 Picking up the jobs one after the other.
 Adding the jobs on the Gantt chart in such a way that they are as far as possible from 0. This
ensures that the job gets completed before the given deadline.
Algorithm for Job Sequencing with Deadline:
Algorithm: Job-Sequencing-With-Deadline (Dead, Job, n, k)
Dead(0) := Job(0) := 0
k := 1
Job(1) := 1 // means first job is selected
for i = 2 … n do
r := k
while Dead(Job(r)) > Dead(i) and Dead(Job(r)) ≠ r do
r := r – 1
if Dead(Job(r)) ≤ Dead(i) and Dead(i) > r then
for l = k … r + 1 by -1 do
Job(l + 1) := Job(l)
Job(r + 1) := i
k := k + 1

PROBLEM BASED ON JOB SEQUENCING WITH DEADLINES-We are given the jobs, their deadlines
and associated profits as shown-
Jobs J1 J2 J3 J4 J5 J6
Deadlines 5 3 3 2 4 2
Profits 201 181 191 301 121 101
Answer the following questions-
1. Write the optimal schedule that provides us the maximum profit.
2. Can we complete all the jobs in the optimal schedule?
3. What is the maximum earned profit?

Solution:
Step-01:
Firstly, we need to sort all the given jobs in decreasing order of their profit as follows.
Jobs J4 J1 J3 J2 J5 J6
Deadlines 2 5 3 3 4 2
Profits 300 200 190 180 120 100
Step-02:
For each step, we calculate the value of the maximum deadline.
Here, the value of the maximum deadline is 5.
So, we draw a Gantt chart as follows and assign it with a maximum time on the Gantt chart with
5 units as shown below.

Now,
 We will be considering each job one by one in the same order as they appear in the Step-01.
 We are then supposed to place the jobs on the Gantt chart as far as possible from 0.
Step-03:
 We now consider job4.
 Since the deadline for job4 is 2, we will be placing it in the first empty cell before deadline 2 as
follows.
Step-04:
 Now, we go with job1.
 Since the deadline for job1 is 5, we will be placing it in the first empty cell before deadline 5 as
shown below.

Step-05:
 We now consider job3.
 Since the deadline for job3 is 3, we will be placing it in the first empty cell before deadline 3 as
shown in the following figure.

Step-06:
 Next, we go with job2.
 Since the deadline for job2 is 3, we will be placing it in the first empty cell before deadline 3.
 Since the second cell and third cell are already filled, so we place job2 in the first cell as shown
below.

Step-07:
 Now, we consider job5.
 Since the deadline for job5 is 4, we will be placing it in the first empty cell before deadline 4 as
shown in the following figure.

Now,
 We can observe that the only job left is job6 whose deadline is 2.
 Since all the slots before deadline 2 are already occupied, job6 cannot be completed.
Now, the questions given above can be answered as follows:

Part-01:
The optimal schedule is-
Job2, Job4, Job3, Job5, Job1
In order to obtain the maximum profit this is the required order in which the jobs must be
completed.
Part-02:
 As we can observe, all jobs are not completed on the optimal schedule.
 This is because job6 was not completed within the given deadline.
Part-03:
Maximum earned profit = Sum of the profit of all the jobs from the optimal schedule
= Profit of job2 + Profit of job4 + Profit of job3 + Profit of job5 + Profit of job1
= 181 + 301 + 191 + 121 + 201
= 995 units

Analysis of the algorithm:


In the job sequencing with deadlines algorithm, we make use of two loops, one loop within another.
Hence, the complexity of this algorithm would be O(n2).
1.Knapsack Problem
When given a set of items, where each item has a weight and a value, we need to determine a
subset of items that are to be included in a collection in such a way that the total weight
aggregates up to be lower than or equal to a given limit and the total value could be as big as
possible.
The Knapsack problem is an instance of a Combinatorial Optimization problem. One general
approach to crack difficult problems is to identify the most restrictive constraint. For this, we
must ignore the others and solve a knapsack problem, and finally, we must somehow fit the
solution to satisfy the constraints that are ignored.
Applications
For multiple cases of resource allocation problems that have some specific constraints, the
problem can be solved in a way that is similar to the Knapsack problem. Following are a set of
examples.
 Finding the least wasteful way to cut down the basic materials
 portfolio optimization
 Cutting stock problems
Problem Scenario
Consider a problem scenario where a thief is robbing a store and his knapsack ( bag) can carry
a maximal weight of W. Consider that there are n items in the store and the weight of the i th
item is w i and its respective profit is pi.
What are all the items the thief should take?
Here, the main goal/objective of the thief is to maximize the profit anyhow. So, the items
should opt-in such a way that the items which are carried by the thief will fetch the maximum
profit.
Based on the nature of the items, Knapsack problems are classified into two categories

 Fractional Knapsack
 Knapsack
Fractional Knapsack
In this category, items can be broken into smaller pieces, and the thief can select fractions of
items.
According to the problem scenario,

 There are n items in the store


 Weight of ith item
 wi>0
 Profit for ith item
 pi>0 and
 The capacity of the Knapsack is W
 As the name suggests, in the Knapsack problem, items can be broken into smaller fragments.
So, the thief might only take a fraction or a part of xi of ith item.0⩽xi⩽1
 The ith item in the store contributes a weight of x i .w i to the total weight in the
knapsack(bag) and profit x i .p i to the Total Profit.
 Hence, the main objective of the algorithm is basically to maximize the value of ∑n=1n(x i .p i )
with respect to the given constraint,
∑n=1n(xi. wi)⩽W
 We already know that a solution that is said to be an optimal solution must fill the
knapsack(bag) exactly, if not, we could at least add a smaller fraction of one of the remaining
items. This will result in an increase in the overall profit.
Thus, an optimal solution to this problem can be obtained by,
∑n=1n(xi. wi)=W
 Now, we have to sort all those items based on their values of piwi, so that
pi+1wi+1 ≤ piwi
 Here, x is an array that is used to store the fraction of items.
Analysis
Suppose that we are provided with items that have already been sorted in the decreasing order
of piwi, then the time taken by the “while” will be O(n). So, the total time including that
includes even sorting will be O(n logn).
Example
Let us consider that the capacity of the knapsack(bag) W = 60 and the list of items are shown in
the following table −
Item A B C D
10 12
Profit 281 1 121 1
Weight 40 10 20 24
(pi/wi) 7 10 6 5

We can see that the provided items are not sorted based on the value of piwi, we perform
sorting. After sorting, the items are shown in the following table.
Item B A C D
12
Profit 101 281 121 1
Weight 10 40 20 24
(pi/wi) 10 7 6 5

Solution
 Once we sort all the items according to the pi/wi, we choose all of B as the weight of B is less
compared to that of the capacity of the knapsack.
 Further, we choose item A, as the available capacity of the knapsack is greater than the
weight of A.
 Now, we will choose C as the next item. Anyhow, the whole item cannot be chosen as the
remaining capacity of the knapsack is less than the weight of the chosen item – C.
Hence, a fraction of C (i.e. (60 − 50)/20) is chosen.
Now, we reach the stage where the capacity of the Knapsack is equal to the chosen items.
Hence, no more items can be selected.
The total weight of the chosen items is 40 + 10 + 20 * (10/20) = 60
And the total profit is 101 + 281 + 121 * (10/20) = 380 + 60 = 440units
This is the optimal solution. We cannot gain more profit compared to this by selecting any
different combination of items out of the provided items.

Algorithm:
Greedy-Fractional-Knapsack (w[1..n], p[1..n], W)
for i = 1 to n
do x[i] = 0
weight = 0
for i = 1 to n
if (weight + w[i]) ≤ W then,
x[i] = 1
weight = weight + w[i]
else
x[i] = (W - weight) / w[i]
weight = W
break
return x

2. Minimum-cost spanning Trees


What is spanning Tree?
A spanning tree is a subset of Graph G, which has all the vertices covered with minimum possible
number of edges. Hence, a spanning tree does not have cycles and it cannot be disconnected.
By this definition, we can draw a conclusion that every connected and undirected Graph G has at least
one spanning tree. A disconnected graph does not have any spanning tree, as it cannot be spanned to
all its vertices.
We found three spanning trees off one complete graph. A complete undirected graph can have
maximum nn-2 number of spanning trees, where n is the number of nodes. In the above addressed
example, n is 3, hence 33−2 = 3 spanning trees are possible.
Properties of Spanning Tree
 Spanning tree has n-1 edges, where n is the number of nodes (vertices).
 From a complete graph, by removing maximum e - n + 1 edges, we can construct a spanning
tree.

 A complete graph can have maximum nn-2 number of spanning trees.


Thus, we can conclude that spanning trees are a subset of connected Graph G and disconnected
graphs do not have spanning tree.
Minimum Spanning Tree (MST)
In a weighted graph, a minimum spanning tree is a spanning tree that has minimum weight than all
other spanning trees of the same graph. In real-world situations, this weight can be measured as
distance, congestion, traffic load or any arbitrary value denoted to the edges.
Minimum Spanning-Tree Algorithm
We shall learn about two most important spanning tree algorithms here −
 Kruskal's Algorithm
 Prim's Algorithm
Both are greedy
algorithms.
1. Prim’s Algorithm

 Prim’s Algorithm is a famous greedy algorithm.


 It is used for finding the Minimum Spanning Tree (MST) of a given graph.
 To apply Prim’s algorithm, the given graph must be weighted, connected and undirected.
Prim’s Algorithm Implementation-
The implementation of Prim’s Algorithm is explained in the following
steps- Step-01:
 Randomly choose any vertex.
 The vertex connecting to the edge having least weight is usually selected.
Step-02:
 Find all the edges that connect the tree to new vertices.
 Find the least weight edge among those edges and include it in the existing tree.
 If including that edge creates a cycle, then reject that edge and look for the next least weight
edge. Step-03:
 Keep repeating step-02 until all the vertices are included and Minimum Spanning Tree (MST)
is obtained.
Prim’s Algorithm Time Complexity-
Worst case time complexity of Prim’s Algorithm is-
 O(ElogV) using binary heap
 O(E + VlogV) using Fibonacci heap

Algorithm for Prim’s


Example: Construct the minimum spanning tree (MST) for the given graph using Prim’s
Algorithm-

Step-1:
 Randomly choose any vertex. ( Here vertex 1)
 The vertex connecting to the edge having least weight is usually selected.

Step-2: Now we are at node / Vertex 6, It has two adjacent edges, one is already selected, select second
one.

Step-3: Now we are at node 5, it has three edges connected, one is already selected, from reaming two
select minimum cost edge (that is having minimum weight) Such that no loops can be formed by adding
that vertex.
Step-4: Now we are at node 4, select the minimum cost edge from the edges connected to this node.
Such that no loops can be formed by adding that vertex.

Step-5: Now we are at node 3, since the minimum cost edge is already selected, so to reach node 2
we selected the edge which cost 16. Then the MST is

Step-6: Now we are at node 2, select minimum cost edge from the edges attached to this node. Such that
no loops can be formed by adding that vertex.

Since all the vertices have been included in the MST, so we


stop. Now, Cost of Minimum Spanning Tree
= Sum of all edge weights
= 10 + 25 + 22 + 12 + 16 + 14
= 99 units

Time Complexity: O(V2), If the input graph is represented using an adjacency list, then the time
complexity of Prim’s algorithm can be reduced to O(E log V) with the help of a binary heap. In this
implementation, we are always considering the spanning tree to start from the root of the graph
2. Kruskal’s Algorithm-

 Kruskal’s Algorithm is a famous greedy algorithm.


 It is used for finding the Minimum Spanning Tree (MST) of a given graph.
 To apply Kruskal’s algorithm, the given graph must be weighted, connected
and undirected. Kruskal’s Algorithm Implementation-
The implementation of Kruskal’s Algorithm is explained in the
following steps- Step-01: Sort all the edges from low weight to high
weight.
Step-02:
 Take the edge with the lowest weight and use it to connect the vertices of graph.
 If adding an edge creates a cycle, then reject that edge and go for the next least
weight edge.

Step-03:
Keep adding edges until all the vertices are connected and a Minimum Spanning Tree (MST) is
obtained.
Analysis: Where E is the number of edges in the graph and V is the number of vertices,
Kruskal's Algorithm can be shown to run in O (E log E) time, or simply, O (E log V) time,
all with simple data structures. These running times are equivalent because:

 E is at most V2 and log V2= 2 x log V is O (log V).


 If we ignore isolated vertices, which will each their components of the minimum
spanning tree, V ≤
2 E, so log V is O (log E).
Thus, the total time is
1. O (E log E) = O (E log V).
Single Source Shortest path-Dijkstra’s algorithm
Dijkstra’s algorithm or Dijkstra’s shortest path algorithm or single source shortest path algorithm is
used in identifying the shortest path from starting node to a destination node in a weighted graph.
Dijkstra’s algorithm is quite similar to Prim’s algorithm for minimum spanning trees. Dijkstra’s
shortest path algorithm works on a greedy approach, where the motive of the algorithm is to
choose the solution with minimum cost.

Hence, Dijkstra’s algorithm does the same. A subgraph is a part or subset of a graph that is
undirected and connected. The Dijkstra algorithm was published by a dutch scientist Edsger
Dijkstra in 1959.

What is Dijkstra’s Algorithm?

Dijkstra’s shortest path algorithm is similar to Prim’s algorithm for MST (Minimum Spanning
Tree). In this algorithm, the shortest path is generated from the starting node to a target node.
This algorithm also maintains two sets of vertices. One set comprises all the vertices included in
the shortest-path graph and another set comprises all the vertices that are not included in the
shortest-path graph yet.

In every next step of Dijkstra’s algorithm, we will select a vertex (from the set of non-included
vertices) which have the minimum distance from the source. This algorithm is different from the
minimum spanning tree because this might not include all the vertices.

Working of Dijkstra’s Algorithm

Dijkstra algorithm is applied on each step and follows the following steps:

Create a shortest path tree set; say U, this will keep a track of all the vertices included in the
graph. The vertex included in this set will have the minimum distance from the destination. So,
the minimum distance for each vertex is calculated and finalized accordingly. The set is empty at
the start.

 First, assign a distance value to all the nodes/vertices of the input graph.
 Initialize all vertices with an INFINITE(∞) distance value.
 Set the source vertex’s distance value to zero.
 While U (shortest path tree set) doesn’t include all the vertices.
 Choose a vertex u that is not present in U and has a minimum distance value.
Include u in U.
 Now, update the distance value of u in all the adjacent vertices.
 For updating the distance value, iterate this in all adjacent vertices.
 For each adjacent vertex v, if the weight of edge u-v and the sum of the distance value of
a is less than the distance value v, then update the distance value a.
 This algorithm can be derived to the main formula, which is
 if d(u) + c(u, v) < d(v)
d(v) = d(u) + c(u,v)
 This means if the sum of distance of u (source vertex) and the cost of going from u to
v(adjacent/ destination vertex(initialized as infinite)) is less than the distance value of v.
 Then, the distance of v becomes the sum of the distance of u (source vertex) and the cost
of going from u to v.

Example

Consider the following graph, and calculate the shortest path between A and all other vertices.

Solution: Initially, the cost of every vertex from A will be infinite or unknown, and the distance
value from A to A will be 0.

Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

Now, let’s find the distance between A and B.,

If( d(u) + c(u, v) < d(v)) ,THEN d(v)=d(u)+cost(A,B)

i.e. d(A) + cost (A, B)< d(B)

=0+7<∞ //True

So, d(B) = d(A) + cost (A, B) = 7

Now, updating the table

Source Destination

A B C D E F
∞ ∞ ∞ ∞ ∞

7 ∞ ∞ ∞ ∞

Now, let’s find the distance between A and C.

d(u) + c(u, v) < d(v)

i.e. d(A) + cost (A, C)< d(C)

=0+9<∞ //True

So, d(C) = d(A) + cost (A, C)

=9

Now, updating the table

Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ ∞

Now, let’s find the distance between A and F.

d(u) + c(u, v) < d(v)

i.e. d(A) + cost (A, F)< d(F)

= 0 + 14 < ∞ //True

So, d(F) = d(A) + cost (A, F)

= 14

Now, updating the table

Source Destination

A B C D E F
∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ 14

Now, the minimum cost between A and B is 7, which is minimum and no need to update that.

Now, let’s check cost of other adjacent node with respect to A via B.

Cost of reaching C from A via B is 17, which is more than previous cost. So we will not update
then.

Cost of reaching F via B, as there is no direct link so no changes will be done

Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ 14

(A,B) 7 9 ∞ ∞ 14

Now, let’s check the cost of reaching vertex D from A via B. The path will be A-B-D, and the cost is
22. Updating this on table, we will get

Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ 14

(A,B) 7 9 ∞ ∞ 14

7 9 22 ∞ 14

The minimum cost between A and B is fixed now which is 7, so now we will choose next
minimum cost which is 9. So now we will check the cost of adjacent node via B and C.

So, the cost of reaching D via C is 20 which is minimum then previous.

Also, the cost of reaching F via C is 11, which is also small then previous.
So, the updated table will be

Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ 14

(A, B) 7 9 ∞ ∞ 14

(A, B, C) 7 9 20 ∞ 11

Now, the minimum cost between A and C is fixed which is 9, hence will be choosing next
minimum which is 11 among 20, infinity and 11.

Now, we will check all the adjacent node with respect to A, B, C, F

There is a path A-C-F- E, whose cost is 20.

Checking all other nodes, to reach. No minimum cost found.

Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ 14

(A, B) 7 9 ∞ ∞ 14

(A, B, C) 7 9 20 ∞ 11

(A, B, C, F) 7 9 20 20 11

Now, 11 is also fixed, selecting any one of D and E because both are 20.

Let’s say selecting D and checking all the nodes with respect to (A, B, C, D, F), but we will get the
same values as the minimum one.

Hence the cost between source to destination can be represented as


Source Destination

A B C D E F

∞ ∞ ∞ ∞ ∞

7 9 ∞ ∞ 14

(A, B) 7 9 ∞ ∞ 14

(A, B, C) 7 9 20 ∞ 11

(A, B, C, F) 7 9 20 20 11

(A, B, C, F, D) 7 9 20 20 11

Pseudo Code
DIJKSTRA (G, w, s)
A(G, s) //Initialize-single source
S←Ø
Q ← V[G]
while Q ≠ Ø

S ← S ∪ (u)
do u ← EX-MIN (Q)//Find minimum distance value

for each vertex v є Adj[u]


do RELAX (u, v, w)

Complexity of Algorithm

 Dijkstra’s algorithm takes O (A log B) time to find the shortest path for any graph.
 Where A is the number of edges and B is the number of vertices.
 It requires O(B) space complexity.

Applications of Dijkstra’s Algorithm

 It is used in finding the shortest path.


 It is used in social networking applications
 Find air-route.
 Identifying locations on the map.
 In telephone network.

Dynamic Programming
Dynamic programming is a name, coined by Richard Bellman in 1955. Dynamic
programming, as greedy method, is a powerful algorithm design technique that can be
used when the solution to the problem may be viewed as the result of a sequence of
decisions. In the greedy method we make irrevocable decisions one at a time, using a
greedy criterion. However, in dynamic programming we examine the decision
sequence to see whether an optimal decision sequence contains optimal decision
subsequence.

When optimal decision sequences contain optimal decision subsequences, we can


establish recurrence equations, called dynamic-programming recurrence equations
that enable us to solve the problem in an efficient way.

Dynamic programming is based on the principle of optimality (also coined by


Bellman). The principle of optimality states that no matter whatever the initial state
and initial decision are, the remaining decision sequence must constitute an optimal
decision sequence with regard to the state resulting from the first decision. The
principle implies that an optimal decision sequence is comprised of optimal decision
subsequences. Since the principle of optimality may not hold for some formulations of
some problems, it is necessary to verify that it does hold for the problem being solved.
Dynamic programming cannot be applied when this principle does not hold.

The steps in a dynamic programming solution are:


Verify that the principle of optimality holds. Set up the dynamic-programming
recurrence equations. Solve the dynamic-programming recurrence equations for the
value of the optimal solution. Perform a trace back step in which the solution itself is
constructed.
In the Dynamic Programming,
1. We divide the large problem into multiple subproblems.
2. Solve the subproblem and store the result.
3. Using the subproblem result, we can build the solution for the large problem.
4. While solving the large problem, if the same subproblem occurs again, we can reuse
the already stored result rather than recomputing it again. This is also
called memoization.
Dynamic Programming Approaches
1. Bottom-Up approach
2. Top-Down approach

1. Bottom-Up approach
Start computing result for the subproblem. Using the subproblem result solve another
subproblem and finally solve the whole problem.
Example
Let's find the nth member of a Fibonacci series.
Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (Fibonacci(0) + Fibonacci(1))
Fibonacci(3) = 2 (Fibonacci(1) + Fibonacci(2))
We can solve the problem step by step.
1. Find Oth member
2. Find 1st member
3. Calculate the 2nd member using 0th and 1st member
4. Calculate the 3rd member using 1st and 2nd member
5. By doing this we can easily find the nth member.
Algorithm
1. set Fib[0] = 0
2. set Fib[1] = 1
3. From index 2 to n compute result using the below formula
Fib[index] = Fib[index - 1] + Fib[index - 2]
4. The final result will be stored in Fib[n].

2.Top-Down approach
Top-Down breaks the large problem into multiple subproblems.
if the subproblem solved already just reuse the answer.
Otherwise, Solve the subproblem and store the result.
Top-Down uses memoization to avoid recomputing the same subproblem again.
Let's solve the same Fibonacci problem using the top-down approach.
Top-Down starts breaking the problem unlike bottom-up.
Like,
If we want to compute Fibonacci(4), the top-down approach will do the following
Fibonacci(4) -> Go and compute Fibonacci(3) and Fibonacci(2) and return the results.
Fibonacci(3) -> Go and compute Fibonacci(2) and Fibonacci(1) and return the results.
Fibonacci(2) -> Go and compute Fibonacci(1) and Fibonacci(0) and return the results.
Finally, Fibonacci(1) will return 1 and Fibonacci(0) will return 0.
Fib(5)
/ \
Fib(3) Fib(4)
/ \ / \
Fib(2) Fib(1) Fib(3) Fib(2)
/ \ / \ / \
Fib(1) Fib(0) Fib(2) Fib(1) Fib(1) Fib(0)
We are computing the result of Fib(2) twice.
This can be avoided using memoization.

Algorithm
Fib(n)
If n == 0 || n == 1 return n;
Otherwise, compute subproblem results recursively.
return Fib(n-1) + Fib(n-2);

All pairs shortestpaths

In the all pairs shortest path problem, we are to find a shortest path
between every pair of vertices in a directed graph G. That is, for every
pair of vertices (i, j), we are to find a shortest path from i to j as well as
one from j to i. These two paths are the same when G is undirected.

When no edge has a negative length, the all-pairs shortest path problem
may be solved by using Dijkstra’s greedy single source algorithm n times,
once with each of the n vertices as the source vertex.

The all pairs shortest path problem is to determine a matrix A such that A
(i, j) is the length of a shortest path from i to j. The matrix A can be
obtained by solving n single- source problems using the algorithm
shortest Paths. Since each application of this procedure requires O (n2)
time, the matrix A can be obtained in O (n3)time.
The dynamic programming solution, called Floyd’s algorithm, runs in O
(n3) time. Floyd’s algorithm works even when the graph has negative
length edges (provided there are no negative length cycles).
The shortest i to j path in G, i ≠ j originates at vertex i and goes through
some intermediate vertices (possibly none) and terminates at vertex j. If k
is an intermediate vertex on this shortest path, then the subpaths from i to
k and from k to j must be shortest paths from i to k and k to j,
respectively. Otherwise, the i to j path is not of minimum length. So, the
principle of optimality holds. Let Ak (i, j) represent the length of a
shortest path from i to j going through no vertex of index greater than k,
we obtain:

Ak (i, j) = {min {min {Ak-1 (i, k) + Ak-1 (k, j)}, c (i,j)}


1<k<n

Algorithm All Paths (Cost, A,n)

// cost [1:n, 1:n] is the cost adjacency matrix of a graph which


// n vertices; A [I, j] is the cost of a shortest path from vertex
// i to vertex j. cost [i, i] = 0.0, for 1 <i <n.
{
for i := 1 to n do
for j:= 1 to n do
A [i, j] := cost [i,j]; // copy cost
into A for k := 1 to n do
for i := 1 to n do

for j := 1 to n do

A [i, j] := min (A [i, j], A [i, k] + A [k,j]);


}

Complexity Analysis: A Dynamic programming algorithm based on this


recurrence involves in calculating n+1 matrices, each of size n x n.
Therefore, the algorithm has a complexity of O(n3).

General formula: min {Ak-1 (i, k) + Ak-1 (k, j)},


c (i,j)} 1<k<n
Single Source Shortest Paths -Bellman Ford's Algorithm
It is similar to Dijkstra's algorithm but it can work with graphs in which edges can have
negative weights.

Why would one ever have edges with negative weights in real life?

Negative weight edges might seem useless at first but they can explain a lot of phenomena
like cashflow, the heat released/absorbed in a chemical reaction, etc.

For instance, if there are different ways to reach from one chemical A to another chemical B,
each method will have sub-reactions involving both heat dissipation and absorption.

If we want to find the set of reactions where minimum energy is required, then we will need
to be able to factor in the heat absorption as negative weights and heat dissipation as
positive weights.

Why do we need to be careful with negative weights?

Negative weight edges can create negative weight cycles i.e. a cycle that will reduce the total
path distance by coming back to the same point.
Neg
ative weight cycles can give an incorrect result when trying to find out the shortest path

Shortest path algorithms like Dijkstra's Algorithm that aren't able to detect such a cycle can
give an incorrect result because they can go through a negative weight cycle and reduce the
path length.

How Bellman Ford's algorithm works

Bellman Ford algorithm works by overestimating the length of the path from the starting
vertex to all other vertices. Then it iteratively relaxes those estimates by finding new paths
that are shorter than the previously overestimated paths.

By doing this repeatedly for all vertices, we can guarantee that the result is optimized.
Note: To relax the path, an edge(U, V), if distance(U) + edge_weight(U,V) < distance(V),
assign distance(V) = distance(U) + edge_weight(U,V).
Optimal Binary Search Tree:
As we know that in binary search tree, the nodes in the left subtree have lesser value than
the root node and the nodes in the right subtree have greater value than the root node.

We know the key values of each node in the tree, and we also know the frequencies of each
node in terms of searching means how much time is required to search a node. The
frequency and key-value determine the overall cost of searching a node. The cost of
searching is a very important factor in various applications. The overall cost of searching a
node should be less. The time required to search a node in BST is more than the balanced
binary search tree as a balanced binary search tree contains a lesser number of levels than
the BST. There is one way that can reduce the cost of a binary search tree is known as
an optimal binary search tree.

Let's understand through an example.

If the keys are 10, 20, 30, 40, 50, 60, 70


In the above tree, all the nodes on the left subtree are smaller than the value of the root node,
and all the nodes on the right subtree are larger than the value of the root node. The
maximum time required to search a node is equal to the minimum height of the tree, equal to
logn.

Now we will see how many binary search trees can be made from the given number of keys.

For example: 10, 20, 30 are the keys, and the following are the binary search trees that can
be made out from these keys.

The Formula for calculating the number of trees:

When we use the above formula, then it is found that total 5 number of trees can be created.

The cost required for searching an element depends on the comparisons to be made to
search an element. Now, we will calculate the average cost of time of the above binary search
trees.
In the above tree, total number of 3 comparisons can be made. The average number of
comparisons can be made as:

Advertisement

In the above tree, the average number of comparisons that can be made as:
In the above tree, the average number of comparisons that can be made as:

In the above tree, the total number of comparisons can be made as 3. Therefore, the average
number of comparisons that can be made as:
In the above tree, the total number of comparisons can be made as 3. Therefore, the average
number of comparisons that can be made as:

In the third case, the number of comparisons is less because the height of the tree is less, so
it's a balanced binary search tree.

Till now, we read about the height-balanced binary search tree. To find the optimal binary
search tree, we will determine the frequency of searching a key.

Let's assume that frequencies associated with the keys 10, 20, 30 are 3, 2, 5.

The above trees have different frequencies. The tree with the lowest frequency would be
considered the optimal binary search tree. The tree with the frequency 17 is the lowest, so it
would be considered as the optimal binary search tree.

Dynamic Approach

Consider the below table, which contains the keys and frequencies.
First, we will calculate the values where j-i is equal to zero.

When i=0, j=0, then j-i = 0

When i = 1, j=1, then j-i = 0

When i = 2, j=2, then j-i = 0

When i = 3, j=3, then j-i = 0

When i = 4, j=4, then j-i = 0

Therefore, c[0, 0] = 0, c[1 , 1] = 0, c[2,2] = 0, c[3,3] = 0, c[4,4] = 0

Now we will calculate the values where j-i equal to 1.

When j=1, i=0 then j-i = 1

When j=2, i=1 then j-i = 1

When j=3, i=2 then j-i = 1


When j=4, i=3 then j-i = 1

Now to calculate the cost, we will consider only the jth value.

The cost of c[0,1] is 4 (The key is 10, and the cost corresponding to key 10 is 4).

The cost of c[1,2] is 2 (The key is 20, and the cost corresponding to key 20 is 2).

When j=1, i=0 then j-i = 1

When j=2, i=1 then j-i = 1

When j=3, i=2 then j-i = 1

When j=4, i=3 then j-i = 1

Now to calculate the cost, we will consider only the jth value.

The cost of c[0,1] is 4 (The key is 10, and the cost corresponding to key 10 is 4).

The cost of c[1,2] is 2 (The key is 20, and the cost corresponding to key 20 is 2).

Advertisement

The cost of c[2,3] is 6 (The key is 30, and the cost corresponding to key 30 is 6)

The cost of c[3,4] is 3 (The key is 40, and the cost corresponding to key 40 is 3)

Now we will calculate the values where j-i = 2

When j=2, i=0 then j-i = 2

When j=3, i=1 then j-i = 2


When j=4, i=2 then j-i = 2

In this case, we will consider two keys.

o When i=0 and j=2, then keys 10 and 20. There are two possible trees that can be made
out from these two keys shown below:

In the first binary tree, cost would be: 4*1 + 2*2 = 8

In the second binary tree, cost would be: 4*2 + 2*1 = 10

The minimum cost is 8; therefore, c[0,2] = 8

o When i=1 and j=3, then keys 20 and 30. There are two possible trees that can be made
out from these two keys shown below:

In the first binary tree, cost would be: 1*2 + 2*6 = 14

In the second binary tree, cost would be: 1*6 + 2*2 = 10

The minimum cost is 10; therefore, c[1,3] = 10


o When i=2 and j=4, we will consider the keys at 3 and 4, i.e., 30 and 40. There are two
possible trees that can be made out from these two keys shown as below:

In the first binary tree, cost would be: 1*6 + 2*3 = 12

In the second binary tree, cost would be: 1*3 + 2*6 = 15

The minimum cost is 12, therefore, c[2,4] = 12

Now we will calculate the values when j-i = 3

When j=3, i=0 then j-i = 3

When j=4, i=1 then j-i = 3

o When i=0, j=3 then we will consider three keys, i.e., 10, 20, and 30.

The following are the trees that can be made if 10 is considered as a root node.
In the above tree, 10 is the root node, 20 is the right child of node 10, and 30 is the right child
of node 20.

Cost would be: 1*4 + 2*2 + 3*6 = 26

In the above tree, 10 is the root node, 30 is the right child of node 10, and 20 is the left child
of node 20.

Cost would be: 1*4 + 2*6 + 3*2 = 22

The following tree can be created if 20 is considered as the root node.


In the above tree, 20 is the root node, 30 is the right child of node 20, and 10 is the left child
of node 20.

Cost would be: 1*2 + 4*2 + 6*2 = 22

The following are the trees that can be created if 30 is considered as the root node.

In the above tree, 30 is the root node, 20 is the left child of node 30, and 10 is the left child of
node 20.

Cost would be: 1*6 + 2*2 + 3*4 = 22


In the above tree, 30 is the root node, 10 is the left child of node 30 and 20 is the right child
of node 10.

Cost would be: 1*6 + 2*4 + 3*2 = 20

Therefore, the minimum cost is 20 which is the 3rd root. So, c[0,3] is equal to 20.

o When i=1 and j=4 then we will consider the keys 20, 30, 40

c[1,4] = min{ c[1,1] + c[2,4], c[1,2] + c[3,4], c[1,3] + c[4,4] } + 11

= min{0+12, 2+3, 10+0}+ 11

= min{12, 5, 10} + 11

The minimum value is 5; therefore, c[1,4] = 5+11 = 16


o Now we will calculate the values when j-i = 4

When j=4 and i=0 then j-i = 4

In this case, we will consider four keys, i.e., 10, 20, 30 and 40. The frequencies of 10, 20, 30
and 40 are 4, 2, 6 and 3 respectively.

w[0, 4] = 4 + 2 + 6 + 3 = 15

If we consider 10 as the root node then

C[0, 4] = min {c[0,0] + c[1,4]}+ w[0,4]

= min {0 + 16} + 15= 31

If we consider 20 as the root node then

C[0,4] = min{c[0,1] + c[2,4]} + w[0,4]

= min{4 + 12} + 15

= 16 + 15 = 31

If we consider 30 as the root node then,

C[0,4] = min{c[0,2] + c[3,4]} +w[0,4]

= min {8 + 3} + 15

= 26

If we consider 40 as the root node then,


C[0,4] = min{c[0,3] + c[4,4]} + w[0,4]

= min{20 + 0} + 15

= 35

Advertisement

In the above cases, we have observed that 26 is the minimum cost; therefore, c[0,4] is equal
to 26.

The optimal binary tree can be created as:


General formula for calculating the minimum cost is:

C[i,j] = min{c[i, k-1] + c[k,j]} + w(i,j)


The traveling salesperson problem (TSP)
The travelling salesman problem asks the following question: "Given a list of cities and the
distances between each pair of cities, what is the shortest possible route that visits each city
exactly once and returns to the origin city? Example: A newspaper agent daily drops the
newspaper to the area assigned in such a manner that he has to cover all the houses in the
respective area with minimum travel cost. Compute the minimum travel cost. The area
assigned to the agent where he has to drop the newspaper is shown in fig:

Solution: The cost- adjacency matrix of graph G is as follows: costij =


The tour starts from area H1 and then select the minimum cost area reachable from H1.

Mark area H6 because it is the minimum cost area reachable from H1 and then select minimum cost area
reachable from H6.

Mark area H7 because it is the minimum cost area reachable from H6 and then select
minimum cost area reachable from H7.
Mark area H2 because it is the minimum cost area reachable from H2.
Mark area H4 and then select the minimum cost area reachable from H4 it is H1.So, using the
greedy strategy, we get the following. 4 3 2 4 3 2 1 6 H1 → H6 → H7 → H8 → H5 → H2 → H3 →
H4 → H1. Thus the minimum travel cost = 4 + 3 + 2 + 4 + 3 + 2 + 1 + 6 = 25

Time Complexity

The recursive equation is

Using the above recurrence relation, we can write a dynamic programming-based solution.
There are at most O(n*2n ) subproblems, and each one takes linear time to solve. The total
running time is therefore O(n2*2n ). The time complexity is much less than O(n!) but still
exponential. The space required is also exponential. So this approach is also infeasible even
for a slightly higher number of vertices. We will soon be discussing approximate algorithms
for the traveling salesman problem. The dynamic programming approach breaks the
problem into 2nn subproblems. Each subproblem takes n time resulting in a time complexity
of O(2n n2 ). Here n refers to the number of cities needed to be travelled too.

You might also like