Aec Lab-2
Aec Lab-2
EXPERIMENT-3
AIM: Develop a program and measure the running time for Quick Sort with Divide and Conquer
Description:
Quick Sort is a sorting algorithm based on the Divide and Conqueralgorithm that picks anelement
as a pivot and partitions the given array aroundthe picked pivot by placing the pivotin its correct
position in the sorted array.
The key process in quick Sortis a partition(). The target of partitions is to place the pivot (any
element can be chosen to be a pivot) at its correct position in the sorted array and put all smaller
elements to the left of the pivot, and all greater elements to the right of the pivot.Partition is
done recursively on each side of the pivot after the pivot is placed in its correct position and this
finally sorts the array.
Code:
int j;
Roll No 2 1 A 9 1 A 6 1 2 0
7
Output:
Roll No 2 1 A 9 1 A 6 1 2 0
8
Experiment 4 Date:
Aim: Develop a program and measure the running time for estimating minimum-cost
spanning Trees with Greedy Method
Description:
Spanning tree - A spanning tree is the subgraph of an undirected connected graph.
Minimum Spanning tree - Minimum spanning tree can be defined as the spanning tree in
which the sum of the weights of the edge is minimum. The weight of the spanning tree is the
sum of the weights given to the edges of the spanning tree.
Prim’s Algorithm :
Prim’s Algorithm is an approach to determine minimum cost spanning tree. In this case, we
start with single edge of graph and we add edges to it and finally we get minimum cost tree.
In this case, as well, we have n-1 edges when number of nodes in graph are n. We again and
again add edges to tree and tree is extended to create spanning tree, while in case of Kruskal’s
algorithm there may be more than one tree, which is finally connected through edge to create
spanning tree.
Program:
// Prim’s Algorithm
#include <stdio.h>
#include <stdlib.h>
#define INFINITY 9999
#define MAX 20
int G[MAX][MAX], spanning[MAX][MAX], n;
int prims();
int main() {
int i, j, total_cost;
printf("Enter no. of vertices: ");
scanf("%d", &n);
printf("\nEnter the adjacency matrix:\n");
for(i = 0; i< n; i++) {
for(j = 0; j < n; j++) {
scanf("%d", &G[i][j]);
}
}
total_cost = prims();
Roll No 2 1 A 9 1 A 6 1 2 0
9
Roll No 2 1 A 9 1 A 6 1 2 0
10
no_of_edges = n - 1;
while(no_of_edges> 0) {
min_distance = INFINITY;
for(i = 1; i< n; i++) {
if(visited[i] == 0 && distance[i] <min_distance) {
v = i;
min_distance = distance[i];
}
}
u = from[v];
spanning[u][v] = distance[v];
spanning[v][u] = distance[v];
no_of_edges--;
visited[v] = 1;
for(i = 1; i< n; i++) {
if(visited[i] == 0 && cost[i][v] < distance[i]) {
distance[i] = cost[i][v];
from[i] = v;
}
}
min_cost += cost[u][v];
}
return min_cost;
}
Roll No 2 1 A 9 1 A 6 1 2 0
11
Output:
Roll No 2 1 A 9 1 A 6 1 2 0
12
Kruskal's Algorithm :
Kruskal's Algorithm is used to find the minimum spanning tree for a connected weighted
graph. The main target of the algorithm is to find the subset of edges by using which we can
traverse every vertex of the graph. It follows the greedy approach that finds an optimum
solution at every stage instead of focusing on a global optimum.
The time complexity of Kruskal's algorithm is O(E logE) or O(V logV), where E is the no. of
edges, and V is the no. of vertices
Program:
// Kruskal's Algorithm
#include <stdio.h>
#define MAX 30
typedef struct edge
{
int u, v, w;
} edge;
typedef struct edgelist
{
edge data[MAX];
int n;
} edgelist;
edgelistelist;
int G[MAX][MAX], n;
edgelistspanlist;
void kruskal();
int find(int belongs[], int vertexno);
void union1(int belongs[], int c1, int c2);
void sort();
void print();
void main()
{
int i, j, total_cost;
printf("\nEnter number of vertices: ");
scanf("%d", &n);
Roll No 2 1 A 9 1 A 6 1 2 0
13
Roll No 2 1 A 9 1 A 6 1 2 0
14
spanlist.n = 0;
for (i = 0; i<elist.n; i++)
{
cno1 = find(belongs, elist.data[i].u);
cno2 = find(belongs, elist.data[i].v);
if (cno1 != cno2)
{
spanlist.data[spanlist.n] = elist.data[i];
spanlist.n = spanlist.n + 1;
union1(belongs, cno1, cno2);
}
}
}
int find(int belongs[], int vertexno)
{
return (belongs[vertexno]);
}
void union1(int belongs[], int c1, int c2)
{
int i;
for (i = 0; i< n; i++)
if (belongs[i] == c2)
belongs[i] = c1;
}
void sort()
{
int i, j;edge temp;
for (i = 1; i<elist.n; i++)
for (j = 0; j <elist.n - 1; j++)
if (elist.data[j].w>elist.data[j + 1].w)
{
Roll No 2 1 A 9 1 A 6 1 2 0
15
temp = elist.data[j];
elist.data[j] = elist.data[j + 1];
elist.data[j + 1] = temp;
}
}
void print()
{
int i, cost = 0;
for (i = 0; i<spanlist.n; i++)
{
printf("\n%d\t%d\t%d", spanlist.data[i].u, spanlist.data[i].v, spanlist.data[i].w);
cost = cost + spanlist.data[i].w;
}
printf("\n\nCost of the spanning tree = %d\n", cost);
}
Output :
Roll No 2 1 A 9 1 A 6 1 2 0
16
Experiment 5 Date:
Aim: Develop a program and measure the running time for estimating Single Source Shortest
Paths with Greedy Method.
Description:
Vertices: Vertices are the basic units of the graph used to represent real-life objects, persons,
or entities. Sometimes, vertices are also known as Nodes.
Edges: Edges are drawn or used to connect two vertices of the graph. Sometimes, edges are
also known as Arcs.
Dijkstra's Algorithm is a Graph algorithm that finds the shortest path from a source vertex to
all other vertices in the Graph (single source shortest path). It is a type of Greedy Algorithm
that only works on Weighted Graphs having positive weights. The time complexity of
Dijkstra's Algorithm is O(V2) with the help of the adjacency matrix representation of the
graph. This time complexity can be reduced to O((V + E) log V) with the help of an
adjacency list representation of the graph, where V is the number of vertices and E is the
number of edges in the graph.
Program:
#include <stdio.h>
#define INFINITY 9999
#define MAX 10
void dijkstra(int G[MAX][MAX], int n, int startnode);
int main() {
int G[MAX][MAX], i, j, n, u;
printf("Enter no. of vertices: ");
scanf("%d", &n);
printf("\nEnter the adjacency matrix:\n");
for (i = 0; i< n; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &G[i][j]);
}
}
printf("\nEnter the starting node: ");
scanf("%d", &u);
dijkstra(G, n, u);
return 0;
Roll No 2 1 A 9 1 A 6 1 2 0
17
}
void dijkstra(int G[MAX][MAX], int n, int startnode) {
int cost[MAX][MAX], distance[MAX], pred[MAX];
int visited[MAX], count, mindistance, nextnode, i, j;
for (i = 0; i< n; i++) {
for (j = 0; j < n; j++) {
if (G[i][j] == 0) {
cost[i][j] = INFINITY;
} else {
cost[i][j] = G[i][j];
}
}
}
for (i = 0; i< n; i++) {
distance[i] = cost[startnode][i];
pred[i] = startnode;
visited[i] = 0;
}
distance[startnode] = 0;
visited[startnode] = 1;
count = 1;
while (count < n - 1) {
mindistance = INFINITY;
for (i = 0; i< n; i++) {
if (distance[i] <mindistance&& !visited[i]) {
mindistance = distance[i];
nextnode = i;
}
}
visited[nextnode] = 1;
for (i = 0; i< n; i++) {
Roll No 2 1 A 9 1 A 6 1 2 0
18
if (!visited[i]) {
if (mindistance + cost[nextnode][i] < distance[i]) {
distance[i] = mindistance + cost[nextnode][i];
pred[i] = nextnode;
}
}
}
count++;
}
for (i = 0; i< n; i++) {
if (i != startnode) {
printf("\nDistance of node%d=%d ", i, distance[i]);
printf("\nPath=%d ", i);
j = i;
do {
j = pred[j];
printf("<-%d", j);
} while (j != startnode);
}
}
}
Output:
Roll No 2 1 A 9 1 A 6 1 2 0
19
Experiment 6 Date:
Aim: Develop a program and measure the running time for optimal Binary search trees with
Dynamic Programming.
Description:
An Optimal Binary Search Tree (OBST), also known as a Weighted Binary Search Tree, is
a binary search tree that minimizes the expected search cost. In a binary search tree, the
search cost is the number of comparisons required to search for a given key.
In an OBST, each node is assigned a weight that represents the probability of the key being
searched for. The sum of all the weights in the tree is 1.0. The expected search cost of a
node is the sum of the product of its depth and weight, and the expected search cost of its
children.
Program:
#include <stdio.h>
#include <limits.h>
int sum(int freq[], int i, int j);
int optCost(int freq[], int i, int j)
{
if (j <i)
return 0;
if (j == i)
return freq[i];
int fsum = sum(freq, i, j);
int min = INT_MAX;
int r;
for (r = i; r <= j; ++r)
{
int cost = optCost(freq, i, r-1) +
optCost(freq, r+1, j);
if (cost < min)
min = cost;
}
return min + fsum;
}
int optimalSearchTree(int keys[], int freq[], int n)
{
Roll No 2 1 A 9 1 A 6 1 2 0
20
Output:
Roll No 2 1 A 9 1 A 6 1 2 0
21
Experiment 7
Aim: Develop a program and measure the running time for identifying solution for traveling
salesperson problem with Dynamic Programming
Description:
Travelling Salesman Problem (TSP):
Given a set of cities and the distance between every pair of cities, the problem is to find the
shortest possible route that visits every city exactly once and returns to the starting point.
Note the difference between Hamiltonian Cycle and TSP. The Hamiltonian cycle problem is
to find if there exists a tour that visits every city exactly once. Here we know that
Hamiltonian Tour exists (because the graph is complete) and in fact, many such tours exist,
the problem is to find a minimum weight Hamiltonian Cycle.
Code:
#include <bits/stdc++.h>
using namespace std;
const int n = 4;
const int MAX = 1000000;
Roll No 2 1 A 9 1 A 6 1 2 0
22
Experiment 8
Aim: Develop a program and measure the running time for identifying solution for 8-Queens
problem with Backtracking
Description:
The eight queens problem is the problem of placing eight queens on an 8×8 chessboard such
that none of them attack one another (no two are in the same row, column, or diagonal). More
generally, the n queens problem places n queens on an n×n chessboard. There are different
solutions for the problem.
1. The algorithm starts by placing a queen on the first column, then it proceeds to the
next column and places a queen in the first safe row of that column.
2. If the algorithm reaches the 8th column and all queens are placed in a safe
position, it prints the board and returns true.
3. If the algorithm is unable to place a queen in a safe position in a certain column, it
backtracks to the previous column and tries a different row.
4. The “isSafe” function checks if it is safe to place a queen on a certain row and
column by checking if there are any queens in the same row, diagonal or anti-
diagonal.
Code:
#include <iostream>
#include <vector>
using namespace std;
const int N = 8;
Roll No 2 1 A 9 1 A 6 1 2 0
23
int main() {
vector<vector<int>>board(N, vector<int>(N, 0));
if (!solveNQueens(board, 0)) {
cout<< "No solution found";
}
return 0;
}
Output:
Roll No 2 1 A 9 1 A 6 1 2 0
24
Experiment 9 Date:
Aim: Develop a program and measure the running time for Graph Coloring with
Backtracking.
Description:
Assign colors one by one to different vertices, starting from vertex 0. Before assigning a
color, check for safety by considering already assigned colors to the adjacent vertices i.e
check if the adjacent vertices have the same color or not. If there is any color assignment
that does not violate the conditions, mark the color assignment as part of the solution. If no
assignment of color is possible then backtrack and return false.
Code:
#include <stdbool.h>
#include <stdio.h>
#define V 4
int i,c ;
void printSolution(int color[]);
bool isSafe(int v, bool graph[V][V], int color[], int c)
{
for ( i = 0; i< V; i++)
if (graph[v][i] && c == color[i])
return false;
return true;
}
bool graphColoringUtil(bool graph[V][V], int m, int color[],
int v)
{
if (v == V)
return true;
for ( c = 1; c <= m; c++) {
Roll No 2 1 A 9 1 A 6 1 2 0
25
color[v] = c;
if (graphColoringUtil(graph, m, color, v + 1)
== true)
return true;
color[v] = 0;
}
}
return false;
}
printSolution(color);
return true;
}
Roll No 2 1 A 9 1 A 6 1 2 0
26
int main()
{
bool graph[V][V] = {
{ 0, 1, 1, 1 },
{ 1, 0, 1, 0 },
{ 1, 1, 0, 1 },
{ 1, 0, 1, 0 },
};
int m = 3; // Number of colors
// Function call
graphColoring(graph, m);
return 0;
}
Output:
Roll No 2 1 A 9 1 A 6 1 2 0
27
Experiment 10
Aim: Develop a program and measure the running time to generate solution of Hamiltonian
Cycle problem with Backtracking.
Description:
If graph contains a Hamiltonian cycle, it is called Hamiltonian graph otherwise it
is non-Hamiltonian.
Finding a Hamiltonian Cycle in a graph is a well-known NP-complete problem,
which means that there’s no known efficient algorithm to solve it for all types of
graphs. However, it can be solved for small or specific types of graphs.
The Hamiltonian Cycle problem has practical applications in various fields, such
as logistics, network design, and computer science.
Code:
#include<stdio.h>
#define V 5
int i,v;
void printSolution(int path[]);
int isSafe(int v, int graph[V][V], int path[], int pos)
{
if (graph [ path[pos-1] ][ v ] == 0)
return 0;
return 1;
}
if (pos == V)
{
Roll No 2 1 A 9 1 A 6 1 2 0
28
return 0;
}
printSolution(path);
return 1;
}
Roll No 2 1 A 9 1 A 6 1 2 0
29
int main()
{
int graph1[V][V] = {{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 1},
{0, 1, 1, 1, 0},
};
hamCycle(graph1);
return 0;
}
Output:
Roll No 2 1 A 9 1 A 6 1 2 0