S.No. Name of The Program Date Signat Ur E: Index
S.No. Name of The Program Date Signat Ur E: Index
CODE:-
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int partition (int arr[], int low, int high)
{
int pivot = arr[high];
int i = low - 1;
for (int j = low; j <= high - 1; j++)
{
if (arr[j] < pivot)
{
i++;
swap (arr[i], arr[j]);
}
}
swap (arr[i + 1], arr[high]);
return i + 1;
}
void quickSort (int arr[], int low, int high)
{
if (low < high)
{
int pi = partition (arr,
low, high);
quickSort (arr, low, pi - 1);
quickSort (arr, pi + 1, high);
}
}
2
int main ()
{
srand (time (0));
int experiments = 5;
int start_n = 1000;
int step = 1000;
for (int exp = 0; exp < experiments; exp++)
{
int n = start_n + exp * step;
int arr[n];
for (int i = 0; i < n; i++)
{
arr[i] = rand () % 1000;
}
clock_t start = clock ();
quickSort (arr, 0, n - 1);
clock_t end = clock ();
double time_taken = double (end - start) / CLOCKS_PER_SEC;
cout << "Time taken to sort " << n << " elements: " << time_taken << " seconds" << endl;
}
return 0;
}
OUTPUT:-
3
Practical 2
AIM:- Using Open, implement a parallelized Merge Sort algorithm to sort a given set of elements and determine
the time required to sort the elements. Repeat the experiment for different values of n, the number of elements in
the list to be sorted and plot a graph of the time taken versus n. The elements can be read from a file or can be
generated using the random number generator.
CODE :-
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <chrono>
#include <omp.h>
using namespace std;
using namespace std::chrono;
void merge(vector<int>& arr, int l, int m, int r) {
int n1 = m - l + 1;
int n2 = r - m;
vector<int> L(n1), R(n2);
for (int i = 0; i < n1; i++)
L[i] = arr[l + i];
for (int j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
int i = 0, j = 0, k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
arr[k] = L[i];
4
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
void mergeSortParallel(vector<int>& arr, int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;
#pragma omp parallel sections
{
#pragma omp section
mergeSortParallel(arr, l, m);
#pragma omp section
mergeSortParallel(arr, m + 1, r);
}
merge(arr, l, m, r);
}
}
vector<int> generateRandomNumbers(int n) {
vector<int> numbers(n);
for (int i = 0; i < n; ++i) {
numbers[i] = rand() % 1000;
}
return numbers;
}
int main() {
ofstream outputFile("merge_sort_parallel_results.txt");
if (!outputFile.is_open()) {
cout << "Unable to open file!";
return 1;
5
}
vector<int> n_values = {1000, 5000, 10000, 20000, 50000};
for (int n : n_values) {
vector<int> arr = generateRandomNumbers(n);
auto start = high_resolution_clock::now();
mergeSortParallel(arr, 0, arr.size() - 1);
auto stop = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(stop - start);
outputFile << "n = " << n << ": " << duration.count() << " milliseconds" << endl;
}
outputFile.close();
cout << "Sorting completed and results saved to 'merge_sort_parallel_results.txt'." << endl;
return 0;
}
OUTPUT:-
6
Practical 3-A
AIM:- Obtain the Topological ordering of vertices in a given digraph.
CODE:-
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
class Graph {
int V;
vector<vector<int>> adj;
void topologicalSortUtil(int v, vector<bool>& visited, stack<int>& Stack) {
visited[v] = true;
for (int i : adj[v]) { if (!visited[i])
topologicalSortUtil(i, visited, Stack);
}
Stack.push(v);
}
public:
Graph(int V)
{
this->V = V;
adj.resize(V);
}
void addEdge(int v, int w) {
adj[v].push_back(w);
}
void topologicalSort() {
stack<int> Stack;
vector<bool> visited(V, false);
for (int i = 0; i < V; ++i)
{
if(!visited[i])
topologicalSortUtil(i, visited, Stack);
}
7
while (!Stack.empty())
{
cout << Stack.top() << " ";
Stack.pop();
}
}
};
int main() {
Graph g(6);
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);
cout << "Topological Sort of the given graph: ";
g.topologicalSort();
return 0;
}
Output:
8
Practical 3-B
AIM:- Compute the transitive closure of a given directed graph using Wars hall's algorithm.
CODE:-
#include <iostream>
#include <vector>
using namespace std;
class Graph {
int V;
vector<vector<int>> reach;
public:
Graph(int V) {
this->V = V;
reach.resize(V, vector<int>(V));
}
void addEdge(int v, int w) {
reach[v][w] = 1;
}
void transitiveClosure() {
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
reach[i][j] = reach[i][j] || (reach[i][k] && reach[k][j]);
}
}
}
cout << "Transitive closure matrix:\n";
for (int i = 0; i < V; i++)
{
for (int j = 0; j < V; j++)
{
cout << reach[i][j] << " ";
}
cout << endl;
}
9
}
};
int main()
{
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
g.transitiveClosure();
return 0;
}
OUTPUT:-
10
Practical 4
AIM:- Implement 0/1 Knapsack problem using Dynamic Programming.
CODE:-
#include <iostream>
#include <vector>
using namespace std;
int knapsack(int W, vector<int>& wt, vector<int>& val, int n)
{
vector <vector<int>> dp(n + 1, vector<int>(W + 1, 0));
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] = max(val[i - 1] + dp[i - 1][w - wt[i - 1]], dp[i - 1][w]);
else
dp[i][w] = dp[i - 1][w];
}
}
return dp[n][W];
}
int main() { vector<int> val = {60, 100, 120};
vector<int> wt = {10, 20, 30};
int W = 50;
int n = val.size();
int maxVal = knapsack(W, wt, val, n); cout << "Maximum value that can be obtained: " << maxVal << endl;
return 0;
}
OUTPUT:-
11
Practical 5
AIM:- From a given vertex in a weighted connected graph, find shortest paths to other vertices using Dijkstra’s
algorithm.
CODE:-
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
#define INF INT_MAX
struct Edge {
int to;
int weight;
Edge(int _to, int _weight) : to(_to), weight(_weight) {}
};
void Dijkstra(vector<vector<Edge>>& graph, int start, vector<int>& distance) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
distance.assign(graph.size(), INF);
distance[start] = 0;
pq.push({0, start});
while (!pq.empty()) {
int u = pq.top().second;
int dist = pq.top().first;
pq.pop();
if (dist > distance[u])
continue;
for (const Edge& edge : graph[u]) {
int v = edge.to;
int weight = edge.weight;
if (distance[v] > distance[u] + weight) {
distance[v] = distance[u] + weight;
pq.push({distance[v], v});
}
}
12
}
}
int main() {
int V, E;
cout << "Enter the number of vertices and edges: ";
cin >> V >> E;
vector<vector<Edge>> graph(V);
cout << "Enter the edges and weights in the format (from to weight):" << endl;
for (int i = 0; i < E; ++i) {
int from, to, weight;
cin >> from >> to >> weight;
graph[from].push_back(Edge(to, weight));
}
int start;
cout <<"Enter the starting vertex:";
cin >> start;
vector<int> distance(V);
Dijkstra(graph, start, distance);
cout << "Shortest distances from vertex " << start << " to all other vertices:" << endl;
for (int i = 0; i < V; ++i) {
if (distance[i] == INF)
cout << "Vertex " << i << ": INF" << endl;
else
cout << "Vertex " << i << ": " << distance[i] << endl;
}
return 0;
}
13
OUTPUT:-
14
Practical 6
AIM:- Find Minimum Cost Spanning Tree of a given undirected graph using Kristal’s algorithm.
CODE:-
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int source, destination, weight;
};
bool compareEdges(const Edge& e1, const Edge& e2) {
return e1.weight < e2.weight;
}
int find(int parent[], int vertex) {
if (parent[vertex] == -1)
return vertex;
return find(parent, parent[vertex]);
}
void Union(int parent[], int x, int y) {
int xSet = find(parent, x);
int ySet = find(parent, y);
parent[xSet] = ySet;
}
void KruskalMST(vector<Edge>& edges, int V) {
sort(edges.begin(), edges.end(), compareEdges);
int parent[V];
fill(parent, parent + V, -1);
vector<Edge> MST;
int edgeCount = 0;
int index = 0;
while (edgeCount < V - 1) {
Edge nextEdge = edges[index++];
int x = find(parent, nextEdge.source);
int y = find(parent, nextEdge.destination);
15
if (x != y) {
MST.push_back(nextEdge);
Union(parent, x, y);
edgeCount++;
}
}
cout << "Minimum Cost Spanning Tree:" << endl;
int totalWeight = 0;
for (Edge edge : MST) {
cout << edge.source << " - " << edge.destination << " : " << edge.weight << endl;
totalWeight += edge.weight;
}
cout << "Total Weight of MST: " << totalWeight << endl;
}
int main() {
int V, E;
cout << "Enter number of vertices and edges: ";
cin >> V >> E;
vector<Edge> edges(E);
cout << "Enter source, destination, and weight of each edge:" << endl;
for (int i = 0; i < E; ++i) {
cin >> edges[i].source >> edges[i].destination >> edges[i].weight;
}
KruskalMST(edges, V);
return 0;
}
OUTPUT:-
16
Practical 7-A
AIM:- Print all the nodes reachable from a given starting node in a digraph using BFS method.
CODE:-
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
void bfs(vector<vector<int>>& graph, int startNode) {
int n = graph.size();
vector<bool> visited(n, false);
queue<int> q;
visited[startNode] = true;
q.push(startNode);
while (!q.empty()) {
int currentNode = q.front();
q.pop();
cout << currentNode << " ";
for (int neighbor : graph[currentNode]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
}
int main() {
int n, m;
cout << "Enter number of nodes and edges: ";
cin >> n >> m;
vector<vector<int>> graph(n);
cout << "Enter the edges:\n";
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
17
graph[u].push_back(v);
graph[v].push_back(u); // Assuming undirected graph
}
int startNode;
cout << "Enter the starting node for BFS: ";
cin >> startNode;
cout << "Nodes reachable from " << startNode << " using BFS: ";
bfs(graph, startNode);
return 0;
}
OUTPUT:-
18
Practical 7-B
AIM:- Check whether a given graph is connected or not using DFS method.
CODE:-
#include <iostream>
#include <vector>
using namespace std;
void dfs(vector<vector<int>>& graph, vector<bool>& visited, int currentNode) {
visited[currentNode] = true;
for (int neighbor : graph[currentNode]) {
if (!visited[neighbor]) {
dfs(graph, visited, neighbor);
}
}
}
bool isConnected(vector<vector<int>>& graph) {
int n = graph.size();
vector<bool> visited(n, false);
dfs(graph, visited, 0);
for (bool v : visited) {
if (!v) return false;
}
return true;
}
int main() {
int n, m;
cout << "Enter number of nodes and edges: ";
cin >> n >> m;
vector<vector<int>> graph(n);
cout << "Enter the edges:\n";
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
19
}
if (isConnected(graph)) {
cout << "The graph is connected.\n";
} else {
cout << "The graph is not connected.\n";
}
return 0;
}
OUTPUT:-
20
Practical 8
AIM:- Find a subset of a given set S = {sl, s2,......,sn} of n positive integers whose sum is equal to a given
positive integer d. For example, if S= {1, 2, 5, 6, 8} and d = 9 there are two solutions {1, 2, 6} and {1, 83.A
suitable message is to be displayed if the given problem instance doesn't have a solution.
CODE:-
#include <iostream>
#include <vector>
using namespace std;
vector<int> subsetSum(vector<int>& S, int n, int d) {
vector<vector<bool>> dp(n + 1, vector<bool>(d + 1, false));
for (int i = 0; i <= n; ++i)
dp[i][0] = true;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= d; ++j) {
if (j < S[i - 1]) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - S[i - 1]];
}
}
}
if (!dp[n][d]) {
cout << "No solution exists.";
return {};
}
int i = n, j = d;
vector<int> subset;
while (i > 0 && j > 0) {
if (dp[i - 1][j]) {
--i;
} else {
subset.push_back(S[i - 1]);
j -= S[i - 1];
--i;
}
21
}
return subset;
}
int main() {
vector<int> S = {1, 2, 5, 6, 8};
int d = 9;
int n = S.size();
vector<int> result = subsetSum(S, n, d);
if (!result.empty()) {
cout << "Solution exists. Subset with sum " << d << " is: ";
for (int i = 0; i < result.size(); ++i) {
cout << result[i] << " ";
}
cout << endl;
}
return 0;
}
OUTPUT:-
22
Practical 9
AIM:- Use divide and conquers method to Recursively implement binary search.
CODE:-
#include <iostream>
#include <vector>
using namespace std;
int binarySearch(vector<int>& arr, int left, int right, int target) {
if (left > right) {
return -1;
}
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
return binarySearch(arr, left, mid - 1, target);
} else {
return binarySearch(arr, mid + 1, right, target);
}
}
int main() {
vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int target = 6;
int index = binarySearch(arr, 0, arr.size() - 1, target);
if (index != -1) {
cout << "Element found at index: " << index << endl;
} else {
cout << "Element not found" << endl;
}
return 0;
}
OUTPUT:-
23
Practical 10
AIM:- Find Minimum Cost Spanning Tree of a given undirected graph using Prim's algorithm.
CODE:-
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
struct Edge {
int to;
int weight;
Edge(int t, int w) : to(t), weight(w) {}
};
vector<Edge> primMST(vector<vector<Edge>>& graph, int start) {
int n = graph.size();
vector<bool> visited(n, false);
vector<Edge> mst;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
visited[start] = true;
for (Edge& e : graph[start]) {
pq.push({e.weight, e.to});
}
while (!pq.empty()) {
auto [weight, to] = pq.top();
pq.pop();
if (visited[to]) continue;
mst.push_back(Edge(to, weight));
visited[to] = true;
for (Edge& e : graph[to]) {
if (!visited[e.to]) {
pq.push({e.weight, e.to});
}
}
}
24
return mst;
}
int main() {
int n, m;
cout << "Enter the number of vertices and edges: ";
cin >> n >> m;
vector<vector<Edge>> graph(n);
cout << "Enter the edges in the format 'from to weight':" << endl;
for (int i = 0; i < m; ++i) {
int from, to, weight;
cin >> from >> to >> weight;
graph[from].push_back(Edge(to, weight));
graph[to].push_back(Edge(from, weight)); // Undirected graph
}
int startVertex;
cout << "Enter the starting vertex: ";
cin >> startVertex;
vector<Edge> mst = primMST(graph, startVertex);
cout << "Edges of Minimum Cost Spanning Tree:" << endl;
for (Edge& e : mst) {
cout << startVertex << " - " << e.to << " : " << e.weight << endl;
}
return 0;
}
OUTPUT:-
25