0% found this document useful (0 votes)
37 views13 pages

Presentation

The document discusses algorithms for solving various graph problems including matrix chain multiplication, matrix addition/subtraction, Strassen's matrix multiplication, knapsack problem, activity selection, Dijkstra's algorithm for shortest paths, and Floyd-Warshall algorithm for all pairs shortest paths. Code implementations are provided for each algorithm using C++. Test cases and sample outputs are also included to demonstrate the working of the algorithms.

Uploaded by

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

Presentation

The document discusses algorithms for solving various graph problems including matrix chain multiplication, matrix addition/subtraction, Strassen's matrix multiplication, knapsack problem, activity selection, Dijkstra's algorithm for shortest paths, and Floyd-Warshall algorithm for all pairs shortest paths. Code implementations are provided for each algorithm using C++. Test cases and sample outputs are also included to demonstrate the working of the algorithms.

Uploaded by

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

//5

#include <bits/stdc++.h>
using namespace std;

int matrixChainMultiplication(const vector<int>& dimensions) {


int n = dimensions.size() - 1;
vector<vector<int>> dp(n, vector<int>(n, 0));

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


for (int i = 0; i < n - l + 1; ++i) {
int j = i + l - 1;
dp[i][j] = INT_MAX;

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


int cost = dp[i][k] + dp[k + 1][j] + dimensions[i] * dimensions[k +
1] * dimensions[j + 1];
dp[i][j] = min(dp[i][j], cost);
}
}
}
return dp[0][n - 1];
}

int main() {

vector<int> dimensions = {10, 30, 5, 60};

int minMultiplications = matrixChainMultiplication(dimensions);

cout << "Minimum number of scalar multiplications: " << minMultiplications <<
endl;

return 0;
}

Minimum number of scalar multiplications: 4500

//6

#include <iostream>
#include <vector>

using namespace std;

vector<vector<int>> matrixAddition(const vector<vector<int>>& A, const


vector<vector<int>>& B) {
int n = A.size();
vector<vector<int>> result(n, vector<int>(n, 0));

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


for (int j = 0; j < n; ++j) {
result[i][j] = A[i][j] + B[i][j];
}
}

return result;
}

vector<vector<int>> matrixSubtraction(const vector<vector<int>>& A, const


vector<vector<int>>& B) {
int n = A.size();
vector<vector<int>> result(n, vector<int>(n, 0));

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


for (int j = 0; j < n; ++j) {
result[i][j] = A[i][j] - B[i][j];
}
}

return result;
}

vector<vector<int>> strassenMatrixMultiplication(const vector<vector<int>>& A,


const vector<vector<int>>& B) {
int n = A.size();

if (n <= 2) {

vector<vector<int>> result(n, vector<int>(n, 0));

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


for (int j = 0; j < n; ++j) {
for (int k = 0; k < n; ++k) {
result[i][j] += A[i][k] * B[k][j];
}
}
}

return result;
}

int mid = n / 2;
vector<vector<int>> A11(mid, vector<int>(mid));
vector<vector<int>> A12(mid, vector<int>(mid));
vector<vector<int>> A21(mid, vector<int>(mid));
vector<vector<int>> A22(mid, vector<int>(mid));
vector<vector<int>> B11(mid, vector<int>(mid));
vector<vector<int>> B12(mid, vector<int>(mid));
vector<vector<int>> B21(mid, vector<int>(mid));
vector<vector<int>> B22(mid, vector<int>(mid));

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


for (int j = 0; j < mid; ++j) {
A11[i][j] = A[i][j];
A12[i][j] = A[i][j + mid];
A21[i][j] = A[i + mid][j];
A22[i][j] = A[i + mid][j + mid];

B11[i][j] = B[i][j];
B12[i][j] = B[i][j + mid];
B21[i][j] = B[i + mid][j];
B22[i][j] = B[i + mid][j + mid];
}
}

vector<vector<int>> P1 = strassenMatrixMultiplication(A11,
matrixSubtraction(B12, B22));
vector<vector<int>> P2 = strassenMatrixMultiplication(matrixAddition(A11, A12),
B22);
vector<vector<int>> P3 = strassenMatrixMultiplication(matrixAddition(A21, A22),
B11);
vector<vector<int>> P4 = strassenMatrixMultiplication(A22,
matrixSubtraction(B21, B11));
vector<vector<int>> P5 = strassenMatrixMultiplication(matrixAddition(A11, A22),
matrixAddition(B11, B22));
vector<vector<int>> P6 = strassenMatrixMultiplication(matrixSubtraction(A12,
A22), matrixAddition(B21, B22));
vector<vector<int>> P7 = strassenMatrixMultiplication(matrixSubtraction(A11,
A21), matrixAddition(B11, B12));

vector<vector<int>> C11 = matrixSubtraction(matrixAddition(matrixAddition(P5,


P4), P6), P2);
vector<vector<int>> C12 = matrixAddition(P1, P2);
vector<vector<int>> C21 = matrixAddition(P3, P4);
vector<vector<int>> C22 =
matrixSubtraction(matrixSubtraction(matrixAddition(P5, P1), P3), P7);

vector<vector<int>> result(n, vector<int>(n, 0));


for (int i = 0; i < mid; ++i) {
for (int j = 0; j < mid; ++j) {
result[i][j] = C11[i][j];
result[i][j + mid] = C12[i][j];
result[i + mid][j] = C21[i][j];
result[i + mid][j + mid] = C22[i][j];
}
}

return result;
}

int main() {

vector<vector<int>> A = {{1, 2}, {3, 4}};


vector<vector<int>> B = {{5, 6}, {7, 8}};

vector<vector<int>> result = strassenMatrixMultiplication(A, B);

// Display the result


cout << "Resultant Matrix:" << endl;
for (const auto& row : result) {
for (int element : row) {
cout << element << " ";
}
cout << endl;
}

return 0;
}

Resultant Matrix:
19 22
43 50

//7

#include <iostream>
#include <vector>

using namespace std;

int knapsack(const vector<int>& weights, const vector<int>& values, int capacity) {


int n = weights.size();
vector<vector<int>> dp(n + 1, vector<int>(capacity + 1, 0));

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


for (int w = 1; w <= capacity; ++w) {
if (weights[i - 1] <= w) {

dp[i][w] = max(values[i - 1] + dp[i - 1][w - weights[i - 1]], dp[i


- 1][w]);
} else {

dp[i][w] = dp[i - 1][w];


}
}
}

return dp[n][capacity];
}

int main() {

vector<int> weights = {2, 3, 4};


vector<int> values = {1, 2, 5};
int capacity = 5;

int maxValue = knapsack(weights, values, capacity);

cout << "Maximum value that can be obtained: " << maxValue << endl;

return 0;
}

Maximum value that can be obtained: 5

//8

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Activity {
int start;
int finish;
};
bool compareActivities(const Activity& a, const Activity& b) {
return a.finish < b.finish;
}
void activitySelection(const vector<Activity>& activities) {
int n = activities.size();
vector<Activity> sortedActivities = activities;
sort(sortedActivities.begin(), sortedActivities.end(), compareActivities);

cout << "Selected Activity: (" << sortedActivities[0].start << ", " <<
sortedActivities[0].finish << ")" << endl;
int prevFinishTime = sortedActivities[0].finish;
for (int i = 1; i < n; ++i) {
if (sortedActivities[i].start >= prevFinishTime) {
cout << "Selected Activity: (" << sortedActivities[i].start << ", "
<< sortedActivities[i].finish << ")" << endl;
prevFinishTime = sortedActivities[i].finish;
}
}
}
int main() {
vector<Activity> activities = {
{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}
};
cout << "Activities selected for maximum compatibility:" << endl;
activitySelection(activities);
return 0;
}

Activities selected for maximum compatibility:


Selected Activity: (1, 2)
Selected Activity: (3, 4)
Selected Activity: (5, 7)
Selected Activity: (8, 9)

//9

#include <iostream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;


struct Edge {
int destination;
int weight;
};
struct Vertex {
int vertex;
int distance;
};
struct CompareDist {
bool operator()(const Vertex& v1, const Vertex& v2) {
return v1.distance > v2.distance;
}
};
void dijkstra(const vector<vector<Edge>>& graph, int source) {
int numVertices = graph.size();
priority_queue<Vertex, vector<Vertex>, CompareDist> pq;
vector<int> distance(numVertices, INT_MAX);
distance[source] = 0;
pq.push({source, 0});
while (!pq.empty()) {
Vertex current = pq.top();
pq.pop();
int u = current.vertex;
int distU = current.distance;
for (const Edge& edge : graph[u]) {
int v = edge.destination;
int weightUV = edge.weight;
if (distU + weightUV < distance[v]) {
distance[v] = distU + weightUV;
pq.push({v, distance[v]});
}
}
}
cout << "Shortest distances from the source " << source << ":\n";
for (int i = 0; i < numVertices; ++i) {
cout << "Vertex " << i << ": ";
if (distance[i] == INT_MAX) {
cout << "INF";
} else {
cout << distance[i];
}
cout << endl;
}
}
int main() {
vector<vector<Edge>> graph = {
{{1, 4}, {7, 8}},
{{0, 4}, {2, 8}, {7, 11}},
{{1, 8}, {3, 7}, {8, 2}, {5, 4}},
{{2, 7}, {4, 9}, {5, 14}},
{{3, 9}, {5, 10}},
{{2, 4}, {3, 14}, {4, 10}, {6, 2}},
{{5, 2}, {7, 1}, {8, 6}},
{{0, 8}, {1, 11}, {6, 1}, {8, 7}},
{{2, 2}, {6, 6}, {7, 7}}
};
dijkstra(graph, 0);
return 0;
}

Shortest distances from the source 0:


Vertex 0: 0
Vertex 1: 4
Vertex 2: 12
Vertex 3: 19
Vertex 4: 21
Vertex 5: 11
Vertex 6: 9
Vertex 7: 8
Vertex 8: 14

//10

#include <iostream>
#include <vector>
using namespace std;
const int INF = 9999;
void floydWarshall(vector<vector<int>>& graph, int numVertices) {
for (int k = 0; k < numVertices; ++k) {
for (int i = 0; i < numVertices; ++i) {
for (int j = 0; j < numVertices; ++j) {
if (graph[i][k] + graph[k][j] < graph[i][j]) {
graph[i][j] = graph[i][k] + graph[k][j];
}
}
}
}
}
void printSolution(const vector<vector<int>>& dist, int numVertices) {
cout << "Shortest distances between vertices:\n";
for (int i = 0; i < numVertices; ++i) {
for (int j = 0; j < numVertices; ++j) {
if (dist[i][j] == INF) {
cout << "INF\t";
} else {
cout << dist[i][j] << "\t";
}
}
cout << endl;
}
}
int main() {
const int numVertices = 4;
vector<vector<int>> graph = {
{0, 3, INF, 5},
{2, 0, INF, 4},
{INF, 1, 0, INF},
{INF, INF, 2, 0}
};

// Perform Warshall's Algorithm


floydWarshall(graph, numVertices);

// Print the final shortest distances matrix


printSolution(graph, numVertices);

return 0;
}
Shortest distances between vertices:
03 7 5
2 0 6 4
3 1 0 5
5 3 2 0

//11

#include <iostream>
#include <vector>
using namespace std;
const int INF = 9999;
struct Edge {
int source;
int destination;
int weight;
};
void bellmanFord(vector<Edge>& edges, int numVertices, int source) {
vector<int> distance(numVertices, INF);
distance[source] = 0;
for (int i = 1; i < numVertices; ++i) {
for (const Edge& edge : edges) {
int u = edge.source;
int v = edge.destination;
int w = edge.weight;
if (distance[u] != INF && distance[u] + w < distance[v]) {
distance[v] = distance[u] + w;
}
}
}
for (const Edge& edge : edges) {
int u = edge.source;
int v = edge.destination;
int w = edge.weight;
if (distance[u] != INF && distance[u] + w < distance[v]) {
cout << "Graph contains a negative weight cycle." << endl;
return;
}
}
cout << "Shortest distances from the source " << source << ":\n";
for (int i = 0; i < numVertices; ++i) {
cout << "Vertex " << i << ": ";
if (distance[i] == INF) {
cout << "INF";
} else {
cout << distance[i];
}
cout << endl;
}
}

int main() {

vector<Edge> edges = {
{0, 1, -1},
{0, 2, 4},
{1, 2, 3},
{1, 3, 2},
{1, 4, 2},
{3, 1, 1},
{3, 2, 5},
{4, 3, -3}
};

const int numVertices = 5;


const int sourceVertex = 0;

// Perform Bellman-Ford's Algorithm


bellmanFord(edges, numVertices, sourceVertex);

return 0;
}

Shortest distances from the source 0:


Vertex 0: 0
Vertex 1: -1
Vertex 2: 2
Vertex 3: -2
Vertex 4: 1

//12

#include <iostream>
#include <string>
using namespace std;
void naiveStringMatching(const string& text, const string& pattern) {
int n = text.length();
int m = pattern.length();
for (int i = 0; i <= n - m; ++i) {
int j;
for (j = 0; j < m; ++j)
if (text[i + j] != pattern[j])
break;
if (j == m)
cout << "Pattern found at index " << i << endl;
}
}
int main() {
string text = "AABAACAADAABAAABAA";
string pattern = "AABA";
naiveStringMatching(text, pattern);
return 0;
}

Pattern found at index 0


Pattern found at index 9
Pattern found at index 13
//13

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

const int prime = 101;

void rabinKarpStringMatching(const string& text, const string& pattern) {


int n = text.length();
int m = pattern.length();
const int d = 256;
int h = 1;
for (int i = 0; i < m - 1; ++i) {
h = (h * d) % prime;
}
int patternHash = 0;
int textHash = 0;
for (int i = 0; i < m; ++i) {
patternHash = (d * patternHash + pattern[i]) % prime;
textHash = (d * textHash + text[i]) % prime;
}
for (int i = 0; i <= n - m; ++i) {
if (patternHash == textHash) {
int j;
for (j = 0; j < m; ++j) {
if (text[i + j] != pattern[j])
break;
}
if (j == m)
cout << "Pattern found at index " << i << endl;
}
if (i < n - m) {
textHash = (d * (textHash - text[i] * h) + text[i + m]) % prime;
if (textHash < 0)
textHash += prime;
}
}
}

int main() {
string text = "AABAACAADAABAAABAA";
string pattern = "AABA";
rabinKarpStringMatching(text, pattern);
return 0;
}

Pattern found at index 0


Pattern found at index 9
Pattern found at index 13

//14
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int dest;
int weight;
};
class Graph {
public:
int V;
vector<vector<Edge>> adjList;

Graph(int vertices) : V(vertices), adjList(vertices) {}


void addEdge(int src, int dest, int weight) {
Edge edge1 = {dest, weight};
Edge edge2 = {src, weight};
adjList[src].push_back(edge1);
adjList[dest].push_back(edge2);
}
void primMST() {
vector<int> key(V, INT_MAX);
vector<int> parent(V, -1);
vector<bool> inMST(V, false);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int,
int>>> pq;

// Start with the first vertex


int src = 0;
pq.push(make_pair(0, src));
key[src] = 0;
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();

inMST[u] = true;
for (const Edge &edge : adjList[u]) {
int v = edge.dest;
int weight = edge.weight;

if (!inMST[v] && weight < key[v]) {


key[v] = weight;
parent[v] = u;
pq.push(make_pair(key[v], v));
}
}
}
cout << "Edges in the Minimum Spanning Tree:\n";
for (int i = 1; i < V; ++i) {
cout << "Edge: " << parent[i] << " - " << i << " Weight: " << key[i]
<< "\n";
}
}
};

int main() {
Graph g(5);
g.addEdge(0, 1, 2);
g.addEdge(0, 3, 6);
g.addEdge(1, 2, 3);
g.addEdge(1, 3, 8);
g.addEdge(1, 4, 5);
g.addEdge(2, 4, 7);
g.addEdge(3, 4, 9);
g.primMST();

return 0;
}

Edges in the Minimum Spanning Tree:


Edge: 0 - 1 Weight: 2
Edge: 1 - 2 Weight: 3
Edge: 0 - 3 Weight: 6
Edge: 1 - 4 Weight: 5

//15

#include <bits/stdc++.h>
using namespace std;
struct Edge {
int src, dest, weight;
};
class DisjointSet {
public:
vector<int> parent, rank;
DisjointSet(int n) : parent(n), rank(n, 0) {
for (int i = 0; i < n; ++i)
parent[i] = i;
}
int find(int v) {
if (v != parent[v])
parent[v] = find(parent[v]);
return parent[v];
}
void unionSets(int root1, int root2) {
if (rank[root1] < rank[root2])
parent[root1] = root2;
else if (rank[root1] > rank[root2])
parent[root2] = root1;
else {
parent[root1] = root2;
rank[root2]++;
}
}
};
bool compareEdges(const Edge& e1, const Edge& e2) {
return e1.weight < e2.weight;
}
class Graph {
public:
int V;
vector<Edge> edges;
Graph(int vertices) : V(vertices) {}
void addEdge(int src, int dest, int weight) {
Edge edge = {src, dest, weight};
edges.push_back(edge);
}
void kruskalMST() {
sort(edges.begin(), edges.end(), compareEdges);
DisjointSet ds(V);
cout << "Edges in the Minimum Spanning Tree:\n";
for (const Edge& edge : edges) {
int root1 = ds.find(edge.src);
int root2 = ds.find(edge.dest);
if (root1 != root2) {
cout << "Edge: " << edge.src << " - " << edge.dest << " Weight: "
<< edge.weight << "\n";
ds.unionSets(root1, root2);
}
}
}
};
int main() {
Graph g(5);
g.addEdge(0, 1, 2);
g.addEdge(0, 3, 6);
g.addEdge(1, 2, 3);
g.addEdge(1, 3, 8);
g.addEdge(1, 4, 5);
g.addEdge(2, 4, 7);
g.addEdge(3, 4, 9);
g.kruskalMST();

return 0;
}

Edges in the Minimum Spanning Tree:


Edge: 0 - 1 Weight: 2
Edge: 1 - 2 Weight: 3
Edge: 1 - 4 Weight: 5
Edge: 0 - 3 Weight: 6

You might also like