Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
9 views16 pages

Week 7

Uploaded by

dorel23756
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)
9 views16 pages

Week 7

Uploaded by

dorel23756
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/ 16

Week 7

Aim: - Design and perform analysis (time and space complexity) for the following, all pairs
shortest path algorithm, which is also known as the Floyd-Warshall algorithm, to generate a
matrix representing the minimum distances between nodes in a weighted graph; for an
Optimal Binary Search Tree (OBST) that minimizes search cost; and for maximizing profits
by optimally filling a bag with given items based on weight and profit constraints.

Floyd-Warshall Algorithm:
Aim: Design and perform analysis (time and space complexity) to find the shortest paths
between all pairs of nodes in a weighted graph using the Floyd-Warshall algorithm.

Algorithm:

1. Initialize a distance matrix dist[][], where dist[i][j] represents the shortest distance
from node i to node j.
2. Set dist[i][i] = 0 for all nodes, and set dist[i][j] to the weight of the direct edge from i
to j, or ∞ if no direct edge exists.
3. Iterate through all intermediate nodes k:
o For each pair of nodes (i, j), update dist[i][j] as:

dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])

4. After n iterations, dist[i][j] contains the shortest distance between every pair of nodes.
Flowchart:
Program Implementation:
import java.util.Scanner;

public class FloydWarshall {


final static int INF = 99999;

public static void floydWarshall(int [][] graph, int n) {


long startTime = System.nanoTime();

int [] [] dist = new int[n][n];


for (int i = 0; i < n; i++)
System.arraycopy(graph[i], 0, dist[i], 0, n);

for (int k = 0; k < n; k++) {


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][k]! = INF && dist[k][j]! = INF
&& dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}

long endTime = System.nanoTime();


long duration = endTime - startTime;

System.out.println("\nShortest distance matrix:");


printSolution(dist, n);

System.out.println("\nExecution Time (nanoseconds): " + duration);

int spaceUsed = (2 * n * n * 4); // original graph + dist array, int = 4 bytes


System.out.println("Approximate Memory Used (bytes): " + spaceUsed);
}

static void printSolution(int [][] dist, int n) {


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][j] == INF)
System.out.print("INF ");
else
System.out.print(dist[i][j] + " ");
}
System.out.println();
}
}
public static void main (String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter number of vertices: ");
int n = sc.nextInt();

int[][] graph = new int[n][n];


System.out.println("Enter the adjacency matrix (use 99999 for INF):");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
graph[i][j] = sc.nextInt();
}
}

floydWarshall(graph, n);
sc.close();
}
}

Input:
Enter number of vertices: 4
Enter the adjacency matrix (use 99999 for INF):
0 3 99999 99999
2 0 99999 99999
99999 7 0 1
6 99999 99999 0

Output:
Shortest distance matrix:
0 3 INF INF
2 0 INF INF
9701
6 9 INF 0

Execution Time (nanoseconds): 45800


Approximate Memory Used (bytes): 128

Wrong input:
Enter number of vertices: 4
Enter the adjacency matrix (use 99999 for INF):
0 2 99999 3
99999 0 5 99999
1 99999 0 99999
99999 99999 99999 0

Output:
Shortest distance matrix:
0273
3056
1304
5430

Execution Time (nanoseconds): 99999999


Approximate Memory Used (bytes): 123456

Time Complexity Analysis

● The Floyd-Warshall algorithm runs three nested loops over n vertices, leading to a
time complexity of: T(n)= O(n^3)
● For a graph with n = 100 nodes, assuming each basic operation (comparison, addition,
assignment) takes 1 nanosecond (ns), the estimated runtime is:

1003=106 operations×1 ns=1 millisecond(106 ns)

● For n = 500, runtime scales as: 5003=125×106ns=125 milliseconds.

Space Complexity Analysis:

● The algorithm stores a distance matrix dist[n][n], requiring: O(n2)


● For n = 100, assuming each entry takes 4 bytes, the memory usage is:

1002×4=40,000 bytes=40

● For n = 500:

5002×4=1,000,000 bytes=1 MB
Optimal Binary Search Tree (OBST)
Aim: Design and perform analysis (time and space complexity) to
construct an OBST that minimizes search cost.
Algorithm:

1. Compute the frequency of each key in the given sorted list.


2. Construct a cost matrix cost[][], where cost[i][j] stores the
minimum cost of searching a subtree with root between i and j.
3. Use dynamic programming to find the minimum search cost using
the formula:
cost[i][j] = min (cost[i][k-1] + cost[k+1][j]
+ sum of frequencies)

4. The root that minimizes the cost is chosen as the root of the OBST.
FlowChart:
Program Implementation:
import java.util.Scanner;

public class OBST {


public static int optimalSearchTree(int[] keys, int[] freq, int n) {
long startTime = System.nanoTime();

int[][] cost = new int[n][n];


for (int i = 0; i < n; i++)
cost[i][i] = freq[i];

for (int len = 2; len <= n; len++) {


for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
cost[i][j] = Integer.MAX_VALUE;

for (int r = i; r <= j; r++) {


int c = ((r > i) ? cost[i][r - 1] : 0)
+ ((r < j) ? cost[r + 1][j] : 0)
+ sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}

long endTime = System.nanoTime();


long duration = endTime - startTime;

System.out.println("\nExecution Time (nanoseconds): " + duration);

int spaceUsed = (n * n * 4) + (n * 4) * 2;
System.out.println("Approximate Memory Used (bytes): " +
spaceUsed);

return cost[0][n - 1];


}

static int sum(int[] freq, int i, int j) {


int s = 0;
for (int k = i; k <= j; k++)
s += freq[k];
return s;
}

public static void main(String[] args) {


Scanner sc = new Scanner(System.in);

System.out.print("Enter number of keys: ");


int n = sc.nextInt();

int[] keys = new int[n];


int[] freq = new int[n];

System.out.println("Enter keys:");
for (int i = 0; i < n; i++) {
keys[i] = sc.nextInt();
}

System.out.println("Enter corresponding frequencies:");


for (int i = 0; i < n; i++) {
freq[i] = sc.nextInt();
}

int result = optimalSearchTree(keys, freq, n);


System.out.println("Optimal Cost: " + result);

sc.close();
}
}

Input:
Enter number of keys: 4
Enter keys:
10 20 30 40
Enter corresponding frequencies:
4263

Output:
Execution Time (nanoseconds): 51800
Approximate Memory Used (bytes): 112
Optimal Cost: 26

Wrong Input:
Enter number of keys: 5
Enter keys:
5 10 15 20 25
Enter corresponding frequencies:
73526

Output:
Execution Time (nanoseconds): 42666
Approximate Memory Used (bytes): 144
Optimal Cost: 42

Time Complexity Analysis:

● The OBST algorithm uses dynamic programming to find the


minimal search cost. It involves three nested loops over n keys,
resulting in: T(n)=O(n3)
● For n = 50, assuming each operation takes 1 ns, the estimated
execution time is:

503=125,000 ns=125

● For n = 100:

1003 = 1,000,000 ns = 1 millisecond


Space Complexity Analysis:

● OBST maintains a cost[n][n] table, requiring: O(n2)


● For n = 50:

502×4 = 10,000 bytes = 10 KB

● For n = 100:

1002×4 = 40,000 bytes = 40 KB


0/1 Knapsack Algorithm (Profit Maximization)
Aim: Design and perform analysis (time and space complexity) to
maximize profit by optimally filling a bag with given items.
Algorithm:

1. Input the number of items (n) and the maximum weight capacity (W)
of the knapsack.
2. Input the weight and value of each item.
3. Create a 2D array dp[n+1][W+1] where dp[i][j] represents
the maximum value that can be obtained using the first i items and a
knapsack capacity of j.
4. Iterate through all items and capacities:
o If the item's weight is less than or equal to the current capacity,
choose the maximum of either:
▪ Including the item (dp[i-1][j - weight[i]] +
value[i])
▪ Excluding the item (dp[i-1][j])
o Otherwise, exclude the item.
5. The final answer is stored in dp[n][W].
6. Display the maximum profit and the items included.
Flowchart:
Program Implementation:
import java.util.Scanner;

public class Knapsack {

static int knapsack(int W, int[] wt, int[] val, int n) {


long startTime = System.nanoTime();

int[][] dp = new int[n + 1][W + 1];

for (int i = 0; i <= n; i++) {


for (int w = 0; w <= W; w++) {
if (i == 0 || w == 0)
dp[i][w] = 0;
else if (wt[i - 1] <= w)
dp[i][w] = Math.max(val[i - 1] + dp[i - 1][w - wt[i - 1]], dp[i -
1][w]);
else
dp[i][w] = dp[i - 1][w];
}
}

long endTime = System.nanoTime();


long duration = endTime - startTime;

System.out.println("\nExecution Time (nanoseconds): " + duration);

int spaceUsed = ((n + 1) * (W + 1) * 4) + (n * 4 * 2) + 4;


System.out.println("Approximate Memory Used (bytes): " +
spaceUsed);

return dp[n][W];
}

public static void main(String[] args) {


Scanner sc = new Scanner(System.in);

System.out.print("Enter number of items: ");


int n = sc.nextInt();
int[] val = new int[n];
int[] wt = new int[n];

System.out.println("Enter values:");
for (int i = 0; i < n; i++) {
val[i] = sc.nextInt();
}

System.out.println("Enter weights:");
for (int i = 0; i < n; i++) {
wt[i] = sc.nextInt();
}

System.out.print("Enter maximum weight capacity: ");


int W = sc.nextInt();

int result = knapsack(W, wt, val, n);


System.out.println("Maximum Profit: " + result);

sc.close();
}
}

Input:
Enter number of items: 3
Enter values:
60 100 120
Enter weights:
10 20 30
Enter maximum weight capacity: 50

Output:
Execution Time (nanoseconds): 43400
Approximate Memory Used (bytes): 816
Maximum Profit: 220

Wrong Input:
Enter number of items: 4
Enter values:
20 40 50 100
Enter weights:
5 10 15 30
Enter maximum weight capacity: 40

Output:
Execution Time (nanoseconds): 56000
Approximate Memory Used (bytes): 1240
Maximum Profit: 160

Time Complexity Analysis

● The dynamic programming solution to the 0/1 Knapsack problem


has a time complexity of: T(n,W)=O(nW)
● For n = 50 items and a weight limit W = 1000, the number of
operations is:

50×1000 = 50,000 ns = 50 µs

● For n = 100, W = 2000:

100×2000 = 200,000 ns = 200 µs


Space Complexity Analysis

● The algorithm requires a dp[n][W] table, leading to: O(nW)


● For n = 50, W = 1000, assuming each entry takes 4 bytes:

50×1000×4=200,000 bytes=200 KB

● For n = 100, W = 2000:

100×2000×4=800,000 bytes=800 KB

You might also like