Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 17

Practical No.

5
Aim:  Demonstrate randomness by implementing QuickSort algorithm.
Program:
#include<iostream>
#include<cstdlib>
using namespace std;
void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int Partition(int a[], int low, int high){
int pivot, index, i;
index = low;
pivot = high;
for(i=low; i < high; i++) {
if(a[i] < a[pivot]) {
swap(&a[i], &a[index]);
index++;
}}
swap(&a[pivot], &a[index]);
return index;
}
int RandomPivotPartition(int a[], int low, int high){
int pvt, n, temp;
n = rand();
pvt = low + n%(high-low+1);
swap(&a[high], &a[pvt]);
return Partition(a, low, high);
}
int QuickSort(int a[], int low, int high){
int pindex;
if(low < high) {
pindex = RandomPivotPartition(a, low, high);
QuickSort(a, low, pindex-1);
QuickSort(a, pindex+1, high);
}
return 0;
}
int main(){
int n, i;
cout<<"\nEnter the number of data element to be sorted: ";
cin>>n;
cout<<endl;
int arr[n];
for(i = 0; i < n; i++) {
cout<<"Enter element "<<i+1<<": ";
cin>>arr[i];
}
QuickSort(arr, 0, n-1);
// Printing the sorted data.
cout<<"\nSorted Data ";
for (i = 0; i < n; i++)
cout<<"->"<<arr[i];

return 0;
}

Output:

Practical No. 6
Aim: Demonstrate randomness by implementing min-cut algorithm.
Program:
// Karger's algorithm to find Minimum Cut in an
// undirected, unweighted and connected graph.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// a structure to represent a unweighted edge in graph


struct Edge
{
int src, dest;
};

// a structure to represent a connected, undirected


// and unweighted graph as a collection of edges.
struct Graph
{
// V-> Number of vertices, E-> Number of edges
int V, E;

// graph is represented as an array of edges.


// Since the graph is undirected, the edge
// from src to dest is also edge from dest
// to src. Both are counted as 1 edge here.
Edge* edge;
};
// A structure to represent a subset for union-find
struct subset
{
int parent;
int rank;
};

// Function prototypes for union-find (These functions are defined


// after kargerMinCut() )
int find(struct subset subsets[], int i);
void Union(struct subset subsets[], int x, int y);

// A very basic implementation of Karger's randomized


// algorithm for finding the minimum cut. Please note
// that Karger's algorithm is a Monte Carlo Randomized algo
// and the cut returned by the algorithm may not be
// minimum always
int kargerMinCut(struct Graph* graph)
{
// Get data of given graph
int V = graph->V, E = graph->E;
Edge *edge = graph->edge;
// Allocate memory for creating V subsets.
struct subset *subsets = new subset[V];

// Create V subsets with single elements


for (int v = 0; v < V; ++v)
{
subsets[v].parent = v;
subsets[v].rank = 0;
}

// Initially there are V vertices in


// contracted graph
int vertices = V;

// Keep contracting vertices until there are


// 2 vertices.
while (vertices > 2)
{
// Pick a random edge
int i = rand() % E;

// Find vertices (or sets) of two corners


// of current edge
int subset1 = find(subsets, edge[i].src);
int subset2 = find(subsets, edge[i].dest);

// If two corners belong to same subset,


// then no point considering this edge
if (subset1 == subset2)
continue;

// Else contract the edge (or combine the


// corners of edge into one vertex)
else
{
printf("Contracting edge %d-%d\n",
edge[i].src, edge[i].dest);
vertices--;
Union(subsets, subset1, subset2);
}
}

// Now we have two vertices (or subsets) left in


// the contracted graph, so count the edges between
// two components and return the count.
int cutedges = 0;
for (int i=0; i<E; i++)
{
int subset1 = find(subsets, edge[i].src);
int subset2 = find(subsets, edge[i].dest);
if (subset1 != subset2)
cutedges++;
}

return cutedges;
}

// A utility function to find set of an element i


// (uses path compression technique)
int find(struct subset subsets[], int i)
{
// find root and make root as parent of i
// (path compression)
if (subsets[i].parent != i)
subsets[i].parent =
find(subsets, subsets[i].parent);

return subsets[i].parent;
}

// A function that does union of two sets of x and y


// (uses union by rank)
void Union(struct subset subsets[], int x, int y)
{
int xroot = find(subsets, x);
int yroot = find(subsets, y);

// Attach smaller rank tree under root of high


// rank tree (Union by Rank)
if (subsets[xroot].rank < subsets[yroot].rank)
subsets[xroot].parent = yroot;
else if (subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;

// If ranks are same, then make one as root and


// increment its rank by one
else
{
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

// Creates a graph with V vertices and E edges


struct Graph* createGraph(int V, int E)
{
Graph* graph = new Graph;
graph->V = V;
graph->E = E;
graph->edge = new Edge[E];
return graph;
}

// Driver program to test above functions


int main()
{
/* Let us create following unweighted graph
0------1
|\|
|\|
| \|
2------3 */
int V = 4; // Number of vertices in graph
int E = 5; // Number of edges in graph
struct Graph* graph = createGraph(V, E);

// add edge 0-1


graph->edge[0].src = 0;
graph->edge[0].dest = 1;
// add edge 0-2
graph->edge[1].src = 0;
graph->edge[1].dest = 2;

// add edge 0-3


graph->edge[2].src = 0;
graph->edge[2].dest = 3;

// add edge 1-3


graph->edge[3].src = 1;
graph->edge[3].dest = 3;

// add edge 2-3


graph->edge[4].src = 2;
graph->edge[4].dest = 3;

// Use a different seed value for every run.


srand(time(NULL));

printf("\nCut found by Karger's randomized algo is %d\n",


kargerMinCut(graph));

return 0;
}
Output:

Practical No. 7
Aim: Demonstrate with a program the Markov property and stationary Markov
chain.
Program:
#include <bits/stdc++.h>
using namespace std;
#define float_vec vector<float>
//to multiply two given matrix
vector<float_vec > multiply(vector<float_vec > A, vector<float_vec > B, int N) {
vector<float_vec > C(N, float_vec(N, 0));
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k)
C[i][j] += A[i][k] * B[k][j];
return C;
}
//to calculate power of matrix
vector<float_vec > matrix_power(vector<float_vec > M, int p, int n) {
vector<float_vec > A(n, float_vec(n, 0));
for (int i = 0; i < n; ++i)
A[i][i] = 1;
while (p) {
if (p % 2)
A = multiply(A, M, n);
M = multiply(M, M, n);
p /= 2;
}
return A;
}
//to calculate probability of reaching from initial to final
float calc_prob(vector<float_vec > M, int N, int F, int S, int T) {
vector<float_vec > matrix_t = matrix_power(M, T, N);
return matrix_t[F - 1][S - 1];
}
int main() {
vector<float_vec > G{
{ 0, 0.08, 0, 0, 0, 0 },
{ 0.33, 0, 0, 0, 0, 0.62 },
{ 0, 0.06, 0, 0, 0, 0 },
{ 0.77, 0, 0.63, 0, 0, 0 },
{ 0, 0, 0, 0.65, 0, 0.38 },
{ 0, 0.85, 0.37, 0.35, 1.0, 0 }
};
//number of available states
int N = 6;
int S = 4, F = 2, T = 100;
cout << "Probability of reaching: " << F << " in time " << T << " after starting
from: " << S << " is " << calc_prob(G, N, F, S, T);
return 0;
}
Output:
Practical No. 8
Aim: Implementing the forward algorithm with Hidden Markov Model, Stationary
Distribution and transition matrix.
Program:

import pandas as pd
import numpy as np
data = pd.read_csv("data_python.csv")
V = data['Visible'].values
# Transition Probabilities
a = np.array(((0.54, 0.46), (0.49, 0.51)))
# Emission Probabilities
b = np.array(((0.16, 0.26, 0.58), (0.25, 0.28, 0.47)))

# Equal Probabilities for the initial distribution


initial_distribution = np.array((0.5, 0.5))

def forward(V, a, b, initial_distribution):


alpha = np.zeros((V.shape[0], a.shape[0]))
alpha[0, :] = initial_distribution * b[:, V[0]]

for t in range(1, V.shape[0]):


for j in range(a.shape[0]):
# Matrix Computation Steps
# ((1x2) . (1x2)) * (1)
# (1) * (1)
alpha[t, j] = alpha[t - 1].dot(a[:, j]) * b[j, V[t]]

return alpha
alpha = forward(V, a, b, initial_distribution)
print(alpha)
Output:

You might also like