Quantcast
Channel: Algorithm – The Crazy Programmer
Viewing all 56 articles
Browse latest View live

Hill Cipher in C and C++ (Encryption and Decryption)

$
0
0

Here you get encryption and decryption program for hill cipher in C and C++.

What is Hill Cipher?

In cryptography (field related to encryption-decryption) hill cipher is a polygraphic cipher based on linear algebra. Invented by Lester S. Hill in 1929 and thus got it’s name. It was the first cipher that was able to operate on 3 symbols at once.

Also Read: Caesar Cipher in C and C++ [Encryption & Decryption]

Encryption: The given message string and key string is represented in the form of matrix. Then key and message matrix are multiplied. Finally modulo 26 is taken for each element of matrix obtained by multiplication. The key matrix that we take here should be invertible, otherwise decryption will not be possible.

Decryption: The encrypted message matrix is multiplied by the inverse of key matrix and finally its modulo 26 is taken to get the original message.

To learn more about hill cipher you can visit following link.

https://en.wikipedia.org/wiki/Hill_cipher

Hill Cipher Program in C

#include<stdio.h>
#include<math.h>

float encrypt[3][1], decrypt[3][1], a[3][3], b[3][3], mes[3][1], c[3][3];

void encryption();	//encrypts the message
void decryption();	//decrypts the message
void getKeyMessage();	//gets key and message from user
void inverse();		//finds inverse of key matrix

void main() {
	getKeyMessage();
	encryption();
	decryption();
}

void encryption() {
	int i, j, k;
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 1; j++)
			for(k = 0; k < 3; k++)
				encrypt[i][j] = encrypt[i][j] + a[i][k] * mes[k][j];
	
	printf("\nEncrypted string is: ");
	for(i = 0; i < 3; i++)
		printf("%c", (char)(fmod(encrypt[i][0], 26) + 97));

}

void decryption() {
	int i, j, k;
	
	inverse();
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 1; j++)
			for(k = 0; k < 3; k++)
				decrypt[i][j] = decrypt[i][j] + b[i][k] * encrypt[k][j];
	
	printf("\nDecrypted string is: ");
	for(i = 0; i < 3; i++)
		printf("%c", (char)(fmod(decrypt[i][0], 26) + 97));
	
	printf("\n");
}

void getKeyMessage() {
	int i, j;
	char msg[3];

	printf("Enter 3x3 matrix for key (It should be inversible):\n");
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 3; j++) {
			scanf("%f", &a[i][j]);
			c[i][j] = a[i][j];
		}
	
	printf("\nEnter a 3 letter string: ");
	scanf("%s", msg);
	
	for(i = 0; i < 3; i++)
		mes[i][0] = msg[i] - 97;
}

void inverse() {
	int i, j, k;
	float p, q;
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 3; j++) {
			if(i == j)
				b[i][j]=1;
			else
				b[i][j]=0;
		}
		
	for(k = 0; k < 3; k++) {
		for(i = 0; i < 3; i++) {
			p = c[i][k];
			q = c[k][k];
				
			for(j = 0; j < 3; j++) {
				if(i != k) {
					c[i][j] = c[i][j]*q - p*c[k][j];
					b[i][j] = b[i][j]*q - p*b[k][j];
				}
			}
		}
	}
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 3; j++)
			b[i][j] = b[i][j] / c[i][i];
	
	printf("\n\nInverse Matrix is:\n");
	for(i = 0; i < 3; i++) {
		for(j = 0; j < 3; j++)
			printf("%d ", b[i][j]);
		
		printf("\n");
	}
}

Hill Cipher Program in C++

#include<iostream>
#include<math.h>

using namespace std;

float encrypt[3][1], decrypt[3][1], a[3][3], b[3][3], mes[3][1], c[3][3];

void encryption();	//encrypts the message
void decryption();	//decrypts the message
void getKeyMessage();	//gets key and message from user
void inverse();		//finds inverse of key matrix

int main() {
	getKeyMessage();
	encryption();
	decryption();
}

void encryption() {
	int i, j, k;
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 1; j++)
			for(k = 0; k < 3; k++)
				encrypt[i][j] = encrypt[i][j] + a[i][k] * mes[k][j];
	
	cout<<"\nEncrypted string is: ";
	for(i = 0; i < 3; i++)
		cout<<(char)(fmod(encrypt[i][0], 26) + 97);
}

void decryption() {
	int i, j, k;
	
	inverse();
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 1; j++)
			for(k = 0; k < 3; k++)
				decrypt[i][j] = decrypt[i][j] + b[i][k] * encrypt[k][j];
	
	cout<<"\nDecrypted string is: ";
	for(i = 0; i < 3; i++)
		cout<<(char)(fmod(decrypt[i][0], 26) + 97);
	
	cout<<"\n";
}

void getKeyMessage() {
	int i, j;
	char msg[3];

	cout<<"Enter 3x3 matrix for key (It should be inversible):\n";
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 3; j++) {
			scanf("%f", &a[i][j]);
			c[i][j] = a[i][j];
		}
	
	cout<<"\nEnter a 3 letter string: ";
	cin>>msg;
	
	for(i = 0; i < 3; i++)
		mes[i][0] = msg[i] - 97;
}

void inverse() {
	int i, j, k;
	float p, q;
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 3; j++) {
			if(i == j)
				b[i][j]=1;
			else
				b[i][j]=0;
		}
		
	for(k = 0; k < 3; k++) {
		for(i = 0; i < 3; i++) {
			p = c[i][k];
			q = c[k][k];
				
			for(j = 0; j < 3; j++) {
				if(i != k) {
					c[i][j] = c[i][j]*q - p*c[k][j];
					b[i][j] = b[i][j]*q - p*b[k][j];
				}
			}
		}
	}
	
	for(i = 0; i < 3; i++)
		for(j = 0; j < 3; j++)
			b[i][j] = b[i][j] / c[i][i];
	
	cout<<"\n\nInverse Matrix is:\n";
	for(i = 0; i < 3; i++) {
		for(j = 0; j < 3; j++)
			cout<<b[i][j]<<" ";
		
		cout<<"\n";
	}
}

Output

Hill Cipher in C and C++ (Encryption and Decryption)

Comment below if you have any queries related to above program for hill cipher in C and C++.

The post Hill Cipher in C and C++ (Encryption and Decryption) appeared first on The Crazy Programmer.


Hamming Code in C and C++

$
0
0

Here you will get program for hamming code in C and C++.

Hamming code is a popular error detection and error correction method in data communication. Hamming code can only detect 2 bit error and correct a single bit error which means it is unable to correct burst errors if may occur while transmission of data.

Also Read: Checksum Program in C and C++

Hamming code uses redundant bits (extra bits) which are calculated according to the below formula:-

2r ≥ m+r+1

Where r is the number of redundant bits required and m is the number of data bits.

R is calculated by putting r = 1, 2, 3 … until the above equation becomes true.

R1 bit is appended at position 20

R2 bit is appended at position 21

R3 bit is appended at position 22 and so on.

These redundant bits are then added to the original data for the calculation of error at receiver’s end.

At receiver’s end with the help of even parity (generally) the erroneous bit position is identified and since data is in binary we take complement of the erroneous bit position to correct received data.

Respective index parity is calculated for r1, r2, r3, r4 and so on.

Hamming Code in C and C++

Image Source

Advantages of Hamming Code

  1. Easy to encode and decode data at both sender and receiver end.
  2. Easy to implement.

Disadvantages of Hamming Code

  1. Cannot correct burst errors.
  2. Redundant bits are also sent with the data therefore it requires more bandwidth to send the data.

Program for Hamming Code in C

#include<stdio.h>

void main() {
    int data[10];
    int dataatrec[10],c,c1,c2,c3,i;

    printf("Enter 4 bits of data one by one\n");
    scanf("%d",&data[0]);
    scanf("%d",&data[1]);
    scanf("%d",&data[2]);
    scanf("%d",&data[4]);

    //Calculation of even parity
    data[6]=data[0]^data[2]^data[4];
	data[5]=data[0]^data[1]^data[4];
	data[3]=data[0]^data[1]^data[2];

	printf("\nEncoded data is\n");
	for(i=0;i<7;i++)
        printf("%d",data[i]);

    printf("\n\nEnter received data bits one by one\n");
    for(i=0;i<7;i++)
        scanf("%d",&dataatrec[i]);

    c1=dataatrec[6]^dataatrec[4]^dataatrec[2]^dataatrec[0];
	c2=dataatrec[5]^dataatrec[4]^dataatrec[1]^dataatrec[0];
	c3=dataatrec[3]^dataatrec[2]^dataatrec[1]^dataatrec[0];
	c=c3*4+c2*2+c1 ;

    if(c==0) {
		printf("\nNo error while transmission of data\n");
    }
	else {
		printf("\nError on position %d",c);
    	
		printf("\nData sent : ");
        for(i=0;i<7;i++)
        	printf("%d",data[i]);
        
		printf("\nData received : ");
        for(i=0;i<7;i++)
        	printf("%d",dataatrec[i]);
		
		printf("\nCorrect message is\n");

		//if errorneous bit is 0 we complement it else vice versa
		if(dataatrec[7-c]==0)
			dataatrec[7-c]=1;
        else
			dataatrec[7-c]=0;
		
		for (i=0;i<7;i++) {
			printf("%d",dataatrec[i]);
		}
	}
}

Program for Hamming Code in C++

#include<iostream>

using namespace std;

int main() {
    int data[10];
    int dataatrec[10],c,c1,c2,c3,i;

    cout<<"Enter 4 bits of data one by one\n";
    cin>>data[0];
    cin>>data[1];
    cin>>data[2];
    cin>>data[4];

    //Calculation of even parity
    data[6]=data[0]^data[2]^data[4];
	data[5]=data[0]^data[1]^data[4];
	data[3]=data[0]^data[1]^data[2];

	cout<<"\nEncoded data is\n";
	for(i=0;i<7;i++)
        cout<<data[i];
    
	cout<<"\n\nEnter received data bits one by one\n";
    for(i=0;i<7;i++)
        cin>>dataatrec[i];

    c1=dataatrec[6]^dataatrec[4]^dataatrec[2]^dataatrec[0];
	c2=dataatrec[5]^dataatrec[4]^dataatrec[1]^dataatrec[0];
	c3=dataatrec[3]^dataatrec[2]^dataatrec[1]^dataatrec[0];
	c=c3*4+c2*2+c1 ;

    if(c==0) {
		cout<<"\nNo error while transmission of data\n";
    }
	else {
		cout<<"\nError on position "<<c;
		
		cout<<"\nData sent : ";
		for(i=0;i<7;i++)
        	cout<<data[i];
        
		cout<<"\nData received : ";
        for(i=0;i<7;i++)
        	cout<<dataatrec[i];
        
		cout<<"\nCorrect message is\n";
        
		//if errorneous bit is 0 we complement it else vice versa
		if(dataatrec[7-c]==0)
			dataatrec[7-c]=1;
        else
		 	dataatrec[7-c]=0;
		for (i=0;i<7;i++) {
			cout<<dataatrec[i];
		}
	}
	
	return 0;
}

Output

Enter 4 bits of data one by one
1
0
1
0

Encoded data is
1010010

Enter received data bits one by one
1
0
1
0
0
1
0

No error while transmission of data

Code Source: http://scanftree.com/programs/c/implementation-of-hamming-code/

This article is submitted by Rahul Maheshwari. You can connect with him on facebook.

Comment below if you have any queries related to above hamming code program in C and C++.

The post Hamming Code in C and C++ appeared first on The Crazy Programmer.

Difference between Preemptive and Non-Preemptive Scheduling in OS

$
0
0

Here you will learn about difference between preemptive and non-preemptive scheduling in os.

Preemptive Scheduling

Preemptive Scheduling means once a process started its execution, the currently running process can be paused for a short period of time to handle some other process of higher priority, it means we can preempt the control of CPU from one process to another if required.

A computer system implementing this supports multi-tasking as it gives the user impression that the user can work on multiple processes.

It is practical because if some process of higher priority is encountered then the current process can be paused to handle that process.

Examples:- SRTF, Priority, Round Robin, etc.

Non-Preemptive Scheduling

Non-Preemptive Scheduling means once a process starts its execution or the CPU is processing a specific process it cannot be halted or in other words we cannot preempt (take control) the CPU to some other process.

A computer system implementing this cannot support the execution of process in a multi task fashion. It executes all the processes in a sequential manner.

It is not practical as all processes are not of same priority and are not always known to the system in advance.

Examples:- FCFS, SJF, Priority, etc.

Difference between Preemptive and Non-Preemptive Scheduling in OS

Image Source

Difference between Preemptive and Non-Preemptive Scheduling in OS

Preemptive Scheduling Non-Preemptive Scheduling
Processor can be preempted to execute a different process in the middle of execution of any current process. Once Processor starts to execute a process it must finish it before executing the other. It cannot be paused in middle.
CPU utilization is more compared to Non-Preemptive Scheduling. CPU utilization is less compared to Preemptive Scheduling.
Waiting time and Response time is less. Waiting time and Response time is more.
The preemptive scheduling is prioritized. The highest priority process should always be the process that is currently utilized. When a process enters the state of running, the state of that process is not deleted from the scheduler until it finishes its service time.
If a high priority process frequently arrives in the ready queue, low priority process may starve. If a process with long burst time is running CPU, then another process with less CPU burst time may starve.
Preemptive scheduling is flexible. Non-preemptive scheduling is rigid.
Ex:- SRTF, Priority, Round Robin, etc. Ex:- FCFS, SJF, Priority, etc.

This article is submitted by Rahul Maheshwari. You can connect with him on facebook.

Comment below if you have any queries related to above tutorial for difference between preemptive and non-preemptive scheduling in os.

The post Difference between Preemptive and Non-Preemptive Scheduling in OS appeared first on The Crazy Programmer.

RSA Algorithm in C and C++ (Encryption and Decryption)

$
0
0

Here you will learn about RSA algorithm in C and C++.

RSA Algorithm is used to encrypt and decrypt data in modern computer systems and other electronic devices. RSA algorithm is an asymmetric cryptographic algorithm as it creates 2 different keys for the purpose of encryption and decryption. It is public key cryptography as one of the keys involved is made public. RSA stands for Ron Rivest, Adi Shamir and Leonard Adleman who first publicly described it in 1978.

RSA makes use of prime numbers (arbitrary large numbers) to function. The public key is made available publicly (means to everyone) and only the person having the private key with them can decrypt the original message.

RSA Algorithm Block Diagram

Image Source

Working of RSA Algorithm

RSA involves use of public and private key for its operation. The keys are generated using the following steps:-

  1. Two prime numbers are selected as p and q
  2. n = pq which is the modulus of both the keys.
  3. Calculate totient = (p-1)(q-1)
  4. Choose e such that e > 1 and coprime to totient which means gcd (e, totient) must be equal to 1, e is the public key
  5. Choose d such that it satisfies the equation de = 1 + k (totient), d is the private key not known to everyone.
  6. Cipher text is calculated using the equation c = m^e mod n where m is the message.
  7. With the help of c and d we decrypt message using equation m = c^d mod n where d is the private key.

Note: If we take the two prime numbers very large it enhances security but requires implementation of Exponentiation by squaring algorithm and square and multiply algorithm for effective encryption and decryption. For simplicity the program is designed with relatively small prime numbers.

Below is the implementation of this algorithm in C and C++.

Program for RSA Algorithm in C

//Program for RSA asymmetric cryptographic algorithm
//for demonstration values are relatively small compared to practical application

#include<stdio.h>
#include<math.h>

//to find gcd
int gcd(int a, int h)
{
    int temp;
    while(1)
    {
        temp = a%h;
        if(temp==0)
        return h;
        a = h;
        h = temp;
    }
}

int main()
{
    //2 random prime numbers
    double p = 3;
    double q = 7;
    double n=p*q;
    double count;
    double totient = (p-1)*(q-1);

    //public key
    //e stands for encrypt
    double e=2;

    //for checking co-prime which satisfies e>1
    while(e<totient){
    count = gcd(e,totient);
    if(count==1)
        break;
    else
        e++;
    }

    //private key
    //d stands for decrypt
    double d;

    //k can be any arbitrary value
    double k = 2;

    //choosing d such that it satisfies d*e = 1 + k * totient
    d = (1 + (k*totient))/e;
    double msg = 12;
    double c = pow(msg,e);
    double m = pow(c,d);
    c=fmod(c,n);
    m=fmod(m,n);

    printf("Message data = %lf",msg);
    printf("\np = %lf",p);
    printf("\nq = %lf",q);
    printf("\nn = pq = %lf",n);
    printf("\ntotient = %lf",totient);
    printf("\ne = %lf",e);
    printf("\nd = %lf",d);
    printf("\nEncrypted data = %lf",c);
    printf("\nOriginal Message Sent = %lf",m);

    return 0;
}

Program for RSA Algorithm in C++

//Program for RSA asymmetric cryptographic algorithm
//for demonstration values are relatively small compared to practical application

#include<iostream>
#include<math.h>

using namespace std;

//to find gcd
int gcd(int a, int h)
{
    int temp;
    while(1)
    {
        temp = a%h;
        if(temp==0)
        return h;
        a = h;
        h = temp;
    }
}

int main()
{
    //2 random prime numbers
    double p = 3;
    double q = 7;
    double n=p*q;
    double count;
    double totient = (p-1)*(q-1);

    //public key
    //e stands for encrypt
    double e=2;

    //for checking co-prime which satisfies e>1
    while(e<totient){
    count = gcd(e,totient);
    if(count==1)
        break;
    else
        e++;
    }

    //private key
    //d stands for decrypt
    double d;

    //k can be any arbitrary value
    double k = 2;

    //choosing d such that it satisfies d*e = 1 + k * totient
    d = (1 + (k*totient))/e;
    double msg = 12;
    double c = pow(msg,e);
    double m = pow(c,d);
    c=fmod(c,n);
    m=fmod(m,n);

    cout<<"Message data = "<<msg;
    cout<<"\n"<<"p = "<<p;
    cout<<"\n"<<"q = "<<q;
    cout<<"\n"<<"n = pq = "<<n;
    cout<<"\n"<<"totient = "<<totient;
    cout<<"\n"<<"e = "<<e;
    cout<<"\n"<<"d = "<<d;
    cout<<"\n"<<"Encrypted data = "<<c;
    cout<<"\n"<<"Original Message sent = "<<m;

    return 0;
}

Output

RSA Algorithm in C and C++ (Encryption and Decryption)

This article is submitted by Rahul Maheshwari. You can connect with him on facebook.

Comment below if you have any queries related to above program for rsa algorithm in C and C++.

The post RSA Algorithm in C and C++ (Encryption and Decryption) appeared first on The Crazy Programmer.

Bisection Method in C and C++

$
0
0

In this tutorial you will get program for bisection method in C and C++.

To find a root very accurately Bisection Method is used in Mathematics. Bisection method algorithm is very easy to program and it always converges which means it always finds root.

Bisection Method repeatedly bisects an interval and then selects a subinterval in which root lies. It is a very simple and robust method but slower than other methods.

It is also called Interval halving, binary search method and dichotomy method.

Bisection Method calculates the root by first calculating the mid point of the given interval end points.

Bisection Method in C and C++

Image Source

Bisection Method Procedure

The input for the method is a continuous function f, an interval [a, b], and the function values f(a) and f(b). The function values are of opposite sign (there is at least one zero crossing within the interval). Each iteration performs these steps:

1. Calculate the midpoint c = (a + b)/2

2. Calculate the function value at the midpoint, function(c).

3. If convergence is satisfactory (that is, a – c is sufficiently small, or f(c) is sufficiently small), return c and stop iterating.

4. Examine the sign of f(c) and replace either (a, f(a)) or (b, f(b)) with (c, f(c)) so that there is a zero crossing within the new interval.

Pros and Cons

Advantage of the bisection method is that it is guaranteed to be converged and very easy to implement.

Disadvantage of bisection method is that it cannot detect multiple roots and is slower compared to other methods of calculating the roots.

Program for Bisection Method in C

#include<stdio.h>

//function used is x^3-2x^2+3
double func(double x)
{
    return x*x*x - 2*x*x + 3;
}

double e=0.01;
double c;

void bisection(double a,double b)
{
    if(func(a) * func(b) >= 0)
    {
        printf("Incorrect a and b");
        return;
    }

    c = a;

    while ((b-a) >= e)
    {
        c = (a+b)/2;
        if (func(c) == 0.0){
            printf("Root = %lf\n",c);
            break;
        }
        else if (func(c)*func(a) < 0){
                printf("Root = %lf\n",c);
                b = c;
        }
        else{
                printf("Root = %lf\n",c);
                a = c;
        }
    }
}

int main()
{
    double a,b;
    a=-10;
    b=20;

    printf("The function used is x^3-2x^2+3\n");
    printf("a = %lf\n",a);
    printf("b = %lf\n",b);
    bisection(a,b);
    printf("\n");
    printf("Accurate Root calculated is = %lf\n",c);

    return 0;
}

Output

a = -10.000000
b = 20.000000
Root = 5.000000
Root = -2.500000
Root = 1.250000
Root = -0.625000
Root = -1.562500
Root = -1.093750
Root = -0.859375
Root = -0.976563
Root = -1.035156
Root = -1.005859
Root = -0.991211
Root = -0.998535

Accurate Root calculated is = -0.998535

Program for Bisection Method in C++

#include<iostream>

using namespace std;

//function used is x^3-2x^2+3
double func(double x)
{
    return x*x*x - 2*x*x + 3;
}

double e=0.01;
double c;

void bisection(double a,double b)
{
    if(func(a) * func(b) >= 0)
    {
        cout<<"Incorrect a and b";
        return;
    }

    c = a;

    while ((b-a) >= e)
    {
        c = (a+b)/2;
        if (func(c) == 0.0){
            cout << "Root = " << c<<endl;
            break;
        }
        else if (func(c)*func(a) < 0){
                cout << "Root = " << c<<endl;
                b = c;
        }
        else{
                cout << "Root = " << c<<endl;
                a = c;
        }
    }
}

int main()
{
    double a,b;
    a=-10;
    b=20;

    cout<<"The function used is x^3-2x^2+3\n";
    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
    bisection(a,b);
    cout<<"\n";
    cout<<"Accurate Root calculated is = "<<c<<endl;

    return 0;
}

This article is submitted by Rahul Maheshwari. You can connect with him on facebook.

Comment below if you have any queries regarding above program for bisection method in C and C++.

The post Bisection Method in C and C++ appeared first on The Crazy Programmer.

Sliding Window Protocol Program in C and C++

$
0
0

Here you will get sliding window protocol program in C.

In computer networks sliding window protocol is a method to transmit data on a network. Sliding window protocol is applied on the Data Link Layer of OSI model. At data link layer data is in the form of frames. In Networking, Window simply means a buffer which has data frames that needs to be transmitted.

Both sender and receiver agrees on some window size. If window size=w then after sending w frames sender waits for the acknowledgement (ack) of the first frame.

As soon as sender receives the acknowledgement of a frame it is replaced by the next frames to be transmitted by the sender. If receiver sends a collective or cumulative acknowledgement to sender then it understands that more than one frames are properly received, for eg:- if ack of frame 3 is received it understands that frame 1 and frame 2 are received properly.

Sliding Window Protocol

Image Source

In sliding window protocol the receiver has to have some memory to compensate any loss in transmission or if the frames are received unordered.

Efficiency of Sliding Window Protocol

η = (W*tx)/(tx+2tp)

W = Window Size

tx = Transmission time

tp = Propagation delay

Sliding window works in full duplex mode

It is of two types:-

1. Selective Repeat: Sender transmits only that frame which is erroneous or is lost.

2. Go back n: Sender transmits all frames present in the window that occurs after the error bit including error bit also.

Sliding Window Protocol Program in C

Below is the simulation of sliding window protocol in C.

#include<stdio.h>

int main()
{
    int w,i,f,frames[50];

    printf("Enter window size: ");
    scanf("%d",&w);

    printf("\nEnter number of frames to transmit: ");
    scanf("%d",&f);

    printf("\nEnter %d frames: ",f);

    for(i=1;i<=f;i++)
        scanf("%d",&frames[i]);

    printf("\nWith sliding window protocol the frames will be sent in the following manner (assuming no corruption of frames)\n\n");
    printf("After sending %d frames at each stage sender waits for acknowledgement sent by the receiver\n\n",w);

    for(i=1;i<=f;i++)
    {
        if(i%w==0)
        {
            printf("%d\n",frames[i]);
            printf("Acknowledgement of above frames sent is received by sender\n\n");
        }
        else
            printf("%d ",frames[i]);
    }

    if(f%w!=0)
        printf("\nAcknowledgement of above frames sent is received by sender\n");

    return 0;
}

Output

Enter window size: 3

Enter number of frames to transmit: 5

Enter 5 frames: 12 5 89 4 6

With sliding window protocol the frames will be sent in the following manner (assuming no corruption of frames)

After sending 3 frames at each stage sender waits for acknowledgement sent by the receiver

12 5 89
Acknowledgement of above frames sent is received by sender

4 6
Acknowledgement of above frames sent is received by sender

Sliding Window Protocol Program in C++

Below is the simulation of sliding window protocol in C++.

#include<iostream>

using namespace std;

int main()
{
    int w,i,f,frames[50];

    cout<<"Enter window size: ";
    cin>>w;

    cout<<"\nEnter number of frames to transmit: ";
    cin>>f;

    cout<<"\nEnter "<<f<<" frames: ";

    for(i=1;i<=f;i++)
        cin>>frames[i];

    cout<<"\nWith sliding window protocol the frames will be sent in the following manner (assuming no corruption of frames)\n\n";
    cout<<"After sending "<<w<<" frames at each stage sender waits for acknowledgement sent by the receiver\n\n";

    for(i=1;i<=f;i++)
    {
        if(i%w==0)
        {
            cout<<frames[i]<<"\n";
            cout<<"Acknowledgement of above frames sent is received by sender\n\n";
        }
        else
            cout<<frames[i]<<" ";
    }

    if(f%w!=0)
        cout<<"\nAcknowledgement of above frames sent is received by sender\n";

    return 0;
}

Comment below if you have any queries regarding above program.

The post Sliding Window Protocol Program in C and C++ appeared first on The Crazy Programmer.

Analysis of Algorithms

$
0
0

In this tutorial you will learn about analysis of algorithms.

Before learning analysis of algorithms lets quickly take a look on what is an algorithm and why we require it.

What is an Algorithm?

An algorithm is the step by step unambiguous procedure to solve a given problem.

For example steps for making Tea or Coffee can be considered as an algorithm.

So for solving a problem we require an algorithm.

Analysis of Algorithms

Design and Analysis of Algorithms

Image Source

There can be several algorithms for solving one problem. So analysis of algorithms is required to find the correctness (algorithm should give solution of problem in finite number of steps) and efficiency (time and memory it takes) of an algorithm.

For example: To go from city A to B there can be several ways like by bus, train, flight, etc.  Depending upon the availability and convenience we choose the one that suits best for us.

Similarly in computer science we use analysis of algorithms to choose the algorithm which is most efficient in terms of running time and space required.

Running Time Analysis

It is the process of determining how processing time of an algorithm increase as the input size increase.

Input size is the number of elements in the input. There can be different types of inputs depending upon the problem type. Below are some common types of inputs.

  • Size of an array.
  • Number of elements in matrix.
  • Vertices and edges in a graph.

Types of Analysis

To analyze an algorithm we need to know for which input the algorithm takes less time and for which input it takes long time.

In terms of running time there can be three cases mentioned below.

Worst Case: It defines the input for which the algorithm takes longest time (slowest time) to complete.

Best Case: It defines the input for which the algorithm takes least time (fastest time) to complete.

Average Case: Run the algorithm using different random inputs and then find total running time by finding average of all running times.

Comment below if have any queries regarding above tutorial.

The post Analysis of Algorithms appeared first on The Crazy Programmer.

Travelling Salesman Problem in C and C++

$
0
0

Here you will learn about Travelling Salesman Problem (TSP) with example and also get a program that implements Travelling Salesman Problem in C and C++.

Let say there are some villages (1, 2, 3, 4, 5). To work with worst case let assume each villages connected with every other villages. And there is a Salesman living in village 1 and he has to sell his things in all villages by travelling and he has to come back to own village 1.

He has to travel each village exactly once, because it is waste of time and energy that revisiting same village. This is same as visiting each node exactly once, which is Hamiltonian Circuit. But our problem is bigger than Hamiltonian cycle because this is not only just finding Hamiltonian path, but also we have to find shortest path.

Finally the problem is we have to visit each vertex exactly once with minimum edge cost in a graph.

Brute Force Approach takes O (nn) time, because we have to check (n-1)! paths (i.e all permutations) and have to find minimum among them.

The correct approach for this problem is solving using Dynamic Programming.

Dynamic Programming can be applied only if main problem can be divided into sub-problems. Let’s check that.

Travelling Salesman Problem (TSP) Using Dynamic Programming

Example Problem

Travelling Salesman Problem (TSP)

Above we can see a complete directed graph and cost matrix which includes distance between each village. We can observe that cost matrix is symmetric that means distance between village 2 to 3 is same as distance between village 3 to 2.

Here problem is travelling salesman wants to find out his tour with minimum cost.

Say it is T (1,{2,3,4}), means, initially he is at village 1 and then he can go to any of {2,3,4}. From there to reach non-visited vertices (villages) becomes a new problem. Here we can observe that main problem spitted into sub-problem, this is property of dynamic programming.

Note: While calculating below right side values calculated in bottom-up manner. Red color values taken from below calculations.

T ( 1, {2,3,4} ) = minimum of

= { (1,2) + T (2,  {3,4} )     4+6=10

= { (1,3)  + T (3, {2,4} )     1+3=4

= { (1,4) + T (4, {2,3} )     3+3=6

Here minimum of above 3 paths is answer but we know only values of (1,2) , (1,3) , (1,4) remaining thing which is T ( 2, {3,4} ) …are new problems now. First we have to solve those and substitute here.

T (2, {3,4} )   = minimum of

=  { (2,3) + T (3, {4} )     2+5=7

= { (2,4) + T {4, {3} )     1+5=6

T (3, {2,4} )   = minimum of

=  { (3,2) + T (2, {4} )     2+1=3

= { (3,4) + T {4, {2} )     5+1=6

T (4, {2,3} )   = minimum of

=  { (4,2) + T (2, {3} )     1+2=3

= { (4,3) + T {3, {2} )     5+2=7

T ( 3, {4} ) =  (3,4) + T (4, {} )     5+0=5

T ( 4, {3} ) =  (4,3) + T (3, {} )     5+0=5

T ( 2, {4} ) =  (2,4) + T (4, {} )     1+0=1

T ( 4, {2} ) =  (4,2) + T (2, {} )     1+0 = 1

T ( 2, {3} ) =  (2,3) + T (3, {} )     2+0 = 2

T ( 3, {2} ) =  (3,2) + T (2, {} )     2+0=2

Here T ( 4, {} ) is reaching base condition in recursion, which returns 0 (zero ) distance.

This is where we can find final answer,

T ( 1, {2,3,4} ) = minimum of

= { (1,2) + T (2,  {3,4} )     4+6=10 in this path we have to add +1 because this path ends with 3. From there we have to reach 1 so 3->1 distance 1 will be added total distance is 10+1=11

= { (1,3)  + T (3, {2,4} )     1+3=4 in this path we have to add +3 because this path ends with 3. From there we have to reach 1 so 4->1 distance 3 will be added total distance is 4+3=7

= { (1,4) + T (4, {2,3} )     3+3=6 in this path we have to add +1 because this path ends with 3. From there we have to reach 1 so 3->1 distance 1 will be added total distance is 6+1=7

Minimum distance is 7 which includes path 1->3->2->4->1.

After solving example problem we can easily write recursive equation.

Recursive Equation

T (i , s) = min ( ( i , j) + T ( j , S – { j }) ) ;  S!= Ø   ; j € S ;

S is set that contains non visited vertices

=  ( i, 1 ) ;  S=Ø, This is base condition for this recursive equation.

Here,

T (i, S) means We are travelling from a vertex “i” and have to visit set of non-visited vertices  “S” and have to go back to vertex 1 (let we started from vertex 1).

( i, j ) means cost of path from node i  to node j

If we observe the first recursive equation from a node we are finding cost to all other nodes (i,j) and from that node to remaining using recursion ( T (j , {S-j}))

But it is not guarantee that every vertex is connected to other vertex then we take that cost as infinity. After that we are taking minimum among all so the path which is not connected get infinity in calculation and won’t be consider.

If S is empty that means we visited all nodes, we take distance from that last visited node to node 1 (first node). Because after visiting all he has to go back to initial node.

Time Complexity

Since we are solving this using Dynamic Programming, we know that Dynamic Programming approach contains sub-problems.

Here after reaching ith node finding remaining minimum distance to that ith node is a sub-problem.

If we solve recursive equation we will get total (n-1) 2(n-2)  sub-problems, which is O (n2n).

Each sub-problem will take  O (n) time (finding path to remaining (n-1) nodes).

Therefore total time complexity is O (n2n) * O (n) = O (n22n)

Space complexity is also number of sub-problems which is O (n2n)

Program for Travelling Salesman Problem in C

#include<stdio.h>

int ary[10][10],completed[10],n,cost=0;

void takeInput()
{
	int i,j;

	printf("Enter the number of villages: ");
	scanf("%d",&n);

	printf("\nEnter the Cost Matrix\n");

	for(i=0;i < n;i++)
	{
		printf("\nEnter Elements of Row: %d\n",i+1);

		for( j=0;j < n;j++)
			scanf("%d",&ary[i][j]);

		completed[i]=0;
	}

	printf("\n\nThe cost list is:");

	for( i=0;i < n;i++)
	{
		printf("\n");

		for(j=0;j < n;j++)
			printf("\t%d",ary[i][j]);
	}
}

void mincost(int city)
{
	int i,ncity;

	completed[city]=1;

	printf("%d--->",city+1);
	ncity=least(city);

	if(ncity==999)
	{
		ncity=0;
		printf("%d",ncity+1);
		cost+=ary[city][ncity];

		return;
	}

	mincost(ncity);
}

int least(int c)
{
	int i,nc=999;
	int min=999,kmin;

	for(i=0;i < n;i++)
	{
		if((ary[c][i]!=0)&&(completed[i]==0))
			if(ary[c][i]+ary[i][c] < min)
			{
				min=ary[i][0]+ary[c][i];
				kmin=ary[c][i];
				nc=i;
			}
	}

	if(min!=999)
		cost+=kmin;

	return nc;
}

int main()
{
	takeInput();

	printf("\n\nThe Path is:\n");
	mincost(0); //passing 0 because starting vertex

	printf("\n\nMinimum cost is %d\n ",cost);

	return 0;
}

Output

Enter the number of villages: 4

Enter the Cost Matrix

Enter Elements of Row: 1
0 4 1 3

Enter Elements of Row: 2
4 0 2 1

Enter Elements of Row: 3
1 2 0 5

Enter Elements of Row: 4
3 1 5 0
The cost list is:
0 4 1 3
4 0 2 1
1 2 0 5
3 1 5 0

The Path is:
1—>3—>2—>4—>1

Minimum cost is 7

Program for Travelling Salesman Problem in C++

#include<iostream>

using namespace std;

int ary[10][10],completed[10],n,cost=0;

void takeInput()
{
	int i,j;

	cout<<"Enter the number of villages: ";
	cin>>n;

	cout<<"\nEnter the Cost Matrix\n";

	for(i=0;i < n;i++)
	{
		cout<<"\nEnter Elements of Row: "<<i+1<<"\n";

		for( j=0;j < n;j++)
			cin>>ary[i][j];

		completed[i]=0;
	}

	cout<<"\n\nThe cost list is:";

	for( i=0;i < n;i++)
	{
		cout<<"\n";

		for(j=0;j < n;j++)
			cout<<"\t"<<ary[i][j];
	}
}

int least(int c)
{
	int i,nc=999;
	int min=999,kmin;

	for(i=0;i < n;i++)
	{
		if((ary[c][i]!=0)&&(completed[i]==0))
			if(ary[c][i]+ary[i][c] < min)
			{
				min=ary[i][0]+ary[c][i];
				kmin=ary[c][i];
				nc=i;
			}
	}

	if(min!=999)
		cost+=kmin;

	return nc;
}

void mincost(int city)
{
	int i,ncity;

	completed[city]=1;

	cout<<city+1<<"--->";
	ncity=least(city);

	if(ncity==999)
	{
		ncity=0;
		cout<<ncity+1;
		cost+=ary[city][ncity];

		return;
	}

	mincost(ncity);
}

int main()
{
	takeInput();

	cout<<"\n\nThe Path is:\n";
	mincost(0); //passing 0 because starting vertex

	cout<<"\n\nMinimum cost is "<<cost;

	return 0;
}

Comment below if you found any information incorrect or have doubts regarding Travelling Salesman Problem algorithm.

The post Travelling Salesman Problem in C and C++ appeared first on The Crazy Programmer.


Matrix Chain Multiplication in C and C++

$
0
0

Here you will learn about Matrix Chain Multiplication with example and also get a program that implements matrix chain multiplication in C and C++.

Before going to main problem first remember some basis.

We know that, to multiply two matrices it is condition that, number of columns in first matrix should be equal to number of rows in second matrix. Let say there are two matrices A and B with dimensions A (2 x 3) and B (3 x 2).

Let’s see an example.

Matrix Chain Multiplication

Above we can see resultant matrix is (2 x 2) matrix i.e. it contains total 4 elements. To calculate each element we did 3 multiplications (which is equal to number of columns in first matrix and number of rows in second matrix). So totally for 4 elements 4*3 = 12 multiplications are required.

In generalized way matrices A (P x Q) and B(Q x R) will result matrix (P x R) which contains P * R elements. To calculate each element need “Q” number of multiplications. Total multiplications needed are P * Q * R

Let’s  try to multiply more than two matrices.

If 3 matrices A, B ,C we can find the final result in two ways (AB)C or A(BC). We get same result in any way since matrix multiplication satisfies associativity property.

Let A (1 x 2 ), B (2 x 3 ), C ( 3 x 2 ). If we follow first way, i.e. (AB)C way.

To calculate (AB) we need 1*2*3 = 6 multiplications. Now resultant AB get dimensions 1 x 3 this multiplied with C need 1*3*2 = 6 multiplications. Total 6+6 = 12 multiplications needed.

If we follow second way, i.e. A(BC) way.

To calculate (BC) we need 2*3*2 = 12 multiplications. Now resultant BC get dimensions 2 x 3. A multiplied with this result need 1*2*3 = 6. Total 12+6 = 18 multiplications needed.

Here we can observe that based on the way we parenthesize the matrices total number of multiplications are changing.

If 4 matrices A, B, C, D we can find final result in 5 ways A(B(CD)) or A((BC)(D)) or (AB)(CD) 4. ((AB)C)D  or (A(BC))D. In this case also each way requires different number of multiplications.

General formula to find number of ways we can find solution is  (2n)! / [ (n+1)! n! ]. After parenthesizing these many ways each way requires different number of multiplications for final result. When dimensions are large (200 x 250 like this) with more number of matrices, then finding the parenthesizing way which requires minimum number of multiplications need will gives less time complexity.

So Matrix Chain Multiplication problem aim is not to find the final result of multiplication, it is finding how to parenthesize matrices so that, requires minimum number of multiplications.

Efficient way of solving this is using dynamic programming

Matrix Chain Multiplication Using Dynamic Programming

Let we have “n” number of matrices A1, A2, A3 ……… An and dimensions are d0 x d1, d1 x d2, d2 x d3 …………. dn-1 x dn  (i.e Dimension of Matrix Ai is di-1 x di

Solving a chain of matrix that,  Ai  Ai+1  Ai+2  Ai+3 ……. Aj = (Ai  Ai+1  Ai+2  Ai+3 ……. Ak ) (Ak+1  Ak+2 ……. Aj ) + di-1 dk dj where i <= k < j.

For more understanding check below example.

Here total i to j matrices, Matrix i to k and Matrix k+1 to j should be solved in recursive way and finally these two matrices multiplied and these dimensions di-1 dk dj (number of multiplications needed) added. The variable k is changed i to j.

Recursive Equation

Note: M[i, j] indicates that if we split from matrix i to matrix j then minimum number of scalar multiplications required.

M [ i , j ] = { 0 ; when i=j ; [means it is a single matrix . If there is only one matrix no need to multiply  with any other. So 0 (zero) multiplications required.]

= { min { M[ i, k ] + M[k+1, j  ] + di-1 dk dj } where i <= k< j

Example Problem

Given problem: A1 (10 x 100), A2 (100 x 20), A3(20 x 5), A4 (5 x 80)

To store results, in dynamic programming we create a table

1,1=0 2,2=0 3,3=0 4,4=0
1,2=20000 2,3=10000 3,4=8000
1,3=15000 2,4=50000
1,4=19000

This table filled using below calculations.

Here cell 2,3 stores the minimum number of scalar multiplications required to.

Using above recursive equation we can fill entire first row with all 0’s (zeros) because i=j (i.e. split happened at only one matrix which requires zero multiplications)

Table [1,2] = 10*100*20 = 20000

Table [2,3] = 100*20*5 = 10000

Table [3,4] = 20*5*80 = 8000

Table [1,3] = minimum of

= { (1,1) + (2,3) + 10* 100*5  = 0+10000+5000 = 15000

= { (1,2) + (3,3) + 10*20*5 = 20000+0+1000 = 21000

Therefore Table[1,3] is 15000 and split happened at 1

Table [2,4] = minimum of

= { (2,2) +(3,4) + 100*20*80 = 0 + 8000 + 160000 = 168000

= { (2,3) + (4,4) + 100*5*80 = 10000 + 0 + 40000 = 50000

Therefore Table of [2,4] is 50000 and split happened at 3

Table of [1,4] = minimum of

= { (1,1) +(2,4) + 10*100*80 = 0 + 50000 + 80000 = 130000

= { (1,2) +(3,4) + 10* 20* 80 = 20000 + 8000 + 16000 = 44000

= { (1,3) + (4,4) + 10*5*80 = 15000+0+4000 = 19000

Therefore table of [1,4] is 19000 which is final answer and split happened at 3.

Splitting way: (1234) is original in final outcome where 19000 answer we got split happened at 3 so ( 1 2 3 ) (4). Split for (123) means see at Table [1,3] that one minimum 15000 split at 1 . So ( ( 1 ) ( 2 3 ) ) ( 4). That means first do 2 x 3 and this 1 x first result and then this result x 4.

Time Complexity

If there are n number of matrices we are creating a table contains [(n) (n+1) ] / 2 cells that is in worst case total number of cells n*n = n2 cells we need calculate = O (n2)

For each one of entry we need find minimum number of multiplications taking worst (it happens at  last cell in table) that is Table [1,4] which equals to  O (n) time.

Finally O (n2) * O (n) = O (n3) is time complexity.

Space Complexity

We are creating a table of n x n so space complexity is O (n2).

Program for Matrix Chain Multiplication in C

// This code implemented using Algorithm in Coremen book

#include<stdio.h>
#include<limits.h>

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n

int MatrixChainMultiplication(int p[], int n)
{
    int m[n][n];
    int i, j, k, L, q;

    for (i=1; i<n; i++)
        m[i][i] = 0;    //number of multiplications are 0(zero) when there is only one matrix

    //Here L is chain length. It varies from length 2 to length n.
    for (L=2; L<n; L++)
    {
        for (i=1; i<n-L+1; i++)
        {
            j = i+L-1;
            m[i][j] = INT_MAX;  //assigning to maximum value

            for (k=i; k<=j-1; k++)
            {
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                {
                    m[i][j] = q;    //if number of multiplications found less that number will be updated.
                }
            }
        }
    }

    return m[1][n-1];   //returning the final answer which is M[1][n]

}

int main()
{
    int n,i;
    printf("Enter number of matrices\n");
    scanf("%d",&n);

    n++;

    int arr[n];

    printf("Enter dimensions \n");

    for(i=0;i<n;i++)
    {
        printf("Enter d%d :: ",i);
        scanf("%d",&arr[i]);
    }

    int size = sizeof(arr)/sizeof(arr[0]);

    printf("Minimum number of multiplications is %d ", MatrixChainMultiplication(arr, size));

    return 0;
}

Output

Enter number of matrices
4
Enter dimensions
Enter d0 :: 10
Enter d1 :: 100
Enter d2 :: 20
Enter d3 :: 5
Enter d4 :: 80
Minimum number of multiplications is 19000

Program for Matrix Chain Multiplication in C++

// This code implemented using Algorithm in Coremen book

#include<iostream>
#include<limits.h>

using namespace std;

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n

int MatrixChainMultiplication(int p[], int n)
{
    int m[n][n];
    int i, j, k, L, q;

    for (i=1; i<n; i++)
        m[i][i] = 0;    //number of multiplications are 0(zero) when there is only one matrix

    //Here L is chain length. It varies from length 2 to length n.
    for (L=2; L<n; L++)
    {
        for (i=1; i<n-L+1; i++)
        {
            j = i+L-1;
            m[i][j] = INT_MAX;  //assigning to maximum value

            for (k=i; k<=j-1; k++)
            {
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                {
                    m[i][j] = q;    //if number of multiplications found less that number will be updated.
                }
            }
        }
    }

    return m[1][n-1];   //returning the final answer which is M[1][n]

}

int main()
{
    int n,i;
    cout<<"Enter number of matrices\n";
    cin>>n;

    n++;

    int arr[n];

    cout<<"Enter dimensions \n";

    for(i=0;i<n;i++)
    {
        cout<<"Enter d"<<i<<" :: ";
        cin>>arr[i];
    }

    int size = sizeof(arr)/sizeof(arr[0]);

    cout<<"Minimum number of multiplications is "<<MatrixChainMultiplication(arr, size));

    return 0;
}

Comment below if you have any queries related to above program for matrix chain multiplication in C and C++.

The post Matrix Chain Multiplication in C and C++ appeared first on The Crazy Programmer.

Bellman-Ford Algorithm in C and C++

$
0
0

Here you will learn about Bellman-Ford Algorithm in C and C++.

Dijkstra and Bellman-Ford Algorithms used to find out single source shortest paths. i.e. there is a source node, from that node we have to find shortest distance to every other node. Dijkstra algorithm fails when graph has negative weight cycle. But Bellman-Ford Algorithm won’t fail even, the graph has negative edge cycle. If there any negative edge cycle it will detect and say there is negative edge cycle. If not it will give answer to given problem.

Bellman-Ford Algorithm will work on logic that, if graph has n nodes, then shortest path never contain more than n-1 edges. This is exactly what Bellman-Ford do. It is enough to relax each edge (v-1) times to find shortest path. But to find whether there is negative cycle or not we again do one more relaxation. If we get less distance in nth relaxation we can say that there is negative edge cycle. Reason for this is negative value added and distance get reduced.

Relaxing edge

In algorithm and code below we use this term Relaxing edge.

Relaxing edge is an operation performed on an edge (u, v) . when,

d(u) > d(v) + Cost(u,v)

Here d(u) means distance of u. If already known distance to “u” is greater than the path from “s” to “v” and “v” to “u” we update that d(u) value with d(v) + cost(u,v).

Algorithm and Time Complexity

Bellman-Ford (G,w,S){   //G is graph given, W is weight matrix, S is source vertex (starting vertex)
    Initialize single source (G,S)  //means initially distance to every node is infinity except to source. Source is 0 (zero). This will take O(v) time

    For i=1 to |G.V| -1     //Runs (v-1) times
        For each edge (G,V)€ G.E    // E times
            Relax(u,v,w)    //O(1) time

    For each edge (G,V) € G.E
        If (v.d > u.d + w(u,v))     //The idea behind this is we are relaxing edges nth time if we found more shortest path than (n-1)th level, we can say that graph is having negative edge cycle and detected.
            Return False

    return true
}

Finally time complexity is (v-1) (E) O(1) = O(VE)

Example Problem

Bellman-Ford Algorithm 1

This is the given directed graph.

(s,t) = 6  (y,x) = -3

(s,y)= 7  (y,z) = 9

(t,y) = 8  (x,t) = -2

(t,z) = -4  (z,x) = 7

(t,x) = 5  (z,s) = 2

Above we can see using vertex “S” as source (Setting distance as 0), we initialize all other distance as infinity.

  S T X Y Z
distance 0
Path

Table and Image explanation: This table, 2nd row shows distance from source to that particular node ad 3rd row shows to reach that node what is the node we visited recently. This path we can see in the image also.

Note: In each iteration, iteration “n” means it contains the path at most “n” edges. And while we are doing iteration “n” we must follow the graph which we obtained in iteration “n-1”.

Iteration 1: edge (s,t) and (z,y) relaxed and updating the distances to t and y.

Bellman-Ford Algorithm

  S T X Y Z
distance 0 6 7
Path S S

Iteration 2 : edge (t,z) and (y,x) relaxed and x and z values are updated.

Bellman-Ford Algorithm 3

  S T X Y Z
distance 0 6 4 7 2
Path S Y S T

Iteration 3: Value of t updated by relaxing (x,t)

Bellman-Ford Algorithm 4

  S T X Y Z
distance 0 2 4 7 2
Path X Y S T

Iteration 4: Value of z updated by relaxing edge (t,z)

Bellman-Ford Algorithm 5

Until now 4 iterations completed and shortest path found to every node form source node. Now we have to do one more iteration to find whether there exists negative edge cycle or not. When we do this nth (5th here) relaxation if we found less distance to any vertex from any other path we can say that there is negative edge cycle. Here we can relax any edge to graph which obtained in iteration 4and we can observe that there is no chance to change those values. So we can confirm that there is no negative edge cycle in this graph.

Program for Bellman-Ford Algorithm in C

Code explanation

Bellman-Ford Algorithm 6

This picture shows the Structure of our input graph.

We create a structure called “Graph” which contains two integers int v (represent number of vertices) and int E (represents number of edges) and also another structure inside this structure which represents edge. That structure contains 3 integers source, destination, weight of that edge. So we create “E” number of structures inside the structure Graph.

After creating Graph, choose a source node and send to BellmanFord function. In this function we relax each edge “v-1” times. After this we can store the result of shortest paths in an array. And we do one more relaxation to find whether there exists negative edge cycle or not. If we got less distance at any node in Vth relaxation of edges, then we can say that the graph have negative edge cycle.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

struct Edge
{
    // This structure is equal to an edge. Edge contains two end points. These edges are directed edges so they
	//contain source and destination and some weight. These 3 are elements in this structure
    int source, destination, weight;
};

// a structure to represent a connected, directed and weighted graph
struct Graph
{
    int V, E;
	// V is number of vertices and E is number of edges

    struct Edge* edge;
	// This structure contain another structure which we already created edge.
};

struct Graph* createGraph(int V, int E)
{
    struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph));
	//Allocating space to structure graph

    graph->V = V;   //assigning values to structure elements that taken form user.

    graph->E = E;

    graph->edge = (struct Edge*) malloc( graph->E * sizeof( struct Edge ) );
	//Creating "Edge" type structures inside "Graph" structure, the number of edge type structures are equal to number of edges

    return graph;
}

void FinalSolution(int dist[], int n)
{
	// This function prints the final solution
    printf("\nVertex\tDistance from Source Vertex\n");
    int i;

    for (i = 0; i < n; ++i){
		printf("%d \t\t %d\n", i, dist[i]);
	}
}

void BellmanFord(struct Graph* graph, int source)
{
    int V = graph->V;

    int E = graph->E;

    int StoreDistance[V];

    int i,j;

    // This is initial step that we know , we initialize all distance to infinity except source.
	// We assign source distance as 0(zero)

    for (i = 0; i < V; i++)
        StoreDistance[i] = INT_MAX;

    StoreDistance[source] = 0;

    //The shortest path of graph that contain V vertices, never contain "V-1" edges. So we do here "V-1" relaxations
    for (i = 1; i <= V-1; i++)
    {
        for (j = 0; j < E; j++)
        {
            int u = graph->edge[j].source;

            int v = graph->edge[j].destination;

            int weight = graph->edge[j].weight;

            if (StoreDistance[u] + weight < StoreDistance[v])
                StoreDistance[v] = StoreDistance[u] + weight;
        }
    }

    // Actually upto now shortest path found. But BellmanFord checks for negative edge cycle. In this step we check for that
    // shortest distances if graph doesn't contain negative weight cycle.

    // If we get a shorter path, then there is a negative edge cycle.
    for (i = 0; i < E; i++)
    {
        int u = graph->edge[i].source;

        int v = graph->edge[i].destination;

        int weight = graph->edge[i].weight;

        if (StoreDistance[u] + weight < StoreDistance[v])
            printf("This graph contains negative edge cycle\n");
    }

    FinalSolution(StoreDistance, V);

    return;
}

int main()
{
    int V,E,S;  //V = no.of Vertices, E = no.of Edges, S is source vertex

	printf("Enter number of vertices in graph\n");
    scanf("%d",&V);

	printf("Enter number of edges in graph\n");
    scanf("%d",&E);

	printf("Enter your source vertex number\n");
	scanf("%d",&S);

    struct Graph* graph = createGraph(V, E);    //calling the function to allocate space to these many vertices and edges

    int i;
    for(i=0;i<E;i++){
        printf("\nEnter edge %d properties Source, destination, weight respectively\n",i+1);
        scanf("%d",&graph->edge[i].source);
        scanf("%d",&graph->edge[i].destination);
        scanf("%d",&graph->edge[i].weight);
    }

    BellmanFord(graph, S);
	//passing created graph and source vertex to BellmanFord Algorithm function

    return 0;
}

Output

Enter number of vertices in graph
5
Enter number of edges in graph
10
Enter your source vertex number
0

Enter edge 1 properties Source, destination, weight respectively
0 1 6

Enter edge 2 properties Source, destination, weight respectively
0 2 7

Enter edge 3 properties Source, destination, weight respectively
1 2 8

Enter edge 4 properties Source, destination, weight respectively
1 4 -4

Enter edge 5 properties Source, destination, weight respectively
1 3 5

Enter edge 6 properties Source, destination, weight respectively
3 1 -2

Enter edge 7 properties Source, destination, weight respectively
2 3 -3

Enter edge 8 properties Source, destination, weight respectively
2 4 9

Enter edge 9 properties Source, destination, weight respectively
4 0 2

Enter edge 10 properties Source, destination, weight respectively
4 3 7

Vertex  Distance from Source Vertex
0  0
1  2
2  7
3  4
4  -2

Program for Bellman-Ford Algorithm in C++

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

using namespace std;

struct Edge
{
    // This structure is equal to an edge. Edge contains two end points. These edges are directed edges so they
	//contain source and destination and some weight. These 3 are elements in this structure
    int source, destination, weight;
};

// a structure to represent a connected, directed and weighted graph
struct Graph
{
    int V, E;
	// V is number of vertices and E is number of edges

    struct Edge* edge;
	// This structure contain another structure which we already created edge.
};

struct Graph* createGraph(int V, int E)
{
    struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph));
	//Allocating space to structure graph

    graph->V = V;   //assigning values to structure elements that taken form user.

    graph->E = E;

    graph->edge = (struct Edge*) malloc( graph->E * sizeof( struct Edge ) );
	//Creating "Edge" type structures inside "Graph" structure, the number of edge type structures are equal to number of edges

    return graph;
}

void FinalSolution(int dist[], int n)
{
	// This function prints the final solution
    cout<<"\nVertex\tDistance from Source Vertex\n";
    int i;

    for (i = 0; i < n; ++i){
		cout<<i<<"\t\t"<<dist[i]<<"\n";
	}
}

void BellmanFord(struct Graph* graph, int source)
{
    int V = graph->V;

    int E = graph->E;

    int StoreDistance[V];

    int i,j;

    // This is initial step that we know , we initialize all distance to infinity except source.
	// We assign source distance as 0(zero)

    for (i = 0; i < V; i++)
        StoreDistance[i] = INT_MAX;

    StoreDistance[source] = 0;

    //The shortest path of graph that contain V vertices, never contain "V-1" edges. So we do here "V-1" relaxations
    for (i = 1; i <= V-1; i++)
    {
        for (j = 0; j < E; j++)
        {
            int u = graph->edge[j].source;

            int v = graph->edge[j].destination;

            int weight = graph->edge[j].weight;

            if (StoreDistance[u] + weight < StoreDistance[v])
                StoreDistance[v] = StoreDistance[u] + weight;
        }
    }

    // Actually upto now shortest path found. But BellmanFord checks for negative edge cycle. In this step we check for that
    // shortest distances if graph doesn't contain negative weight cycle.

    // If we get a shorter path, then there is a negative edge cycle.
    for (i = 0; i < E; i++)
    {
        int u = graph->edge[i].source;

        int v = graph->edge[i].destination;

        int weight = graph->edge[i].weight;

        if (StoreDistance[u] + weight < StoreDistance[v])
            cout<<"\nThis graph contains negative edge cycle\n";
    }

    FinalSolution(StoreDistance, V);

    return;
}

int main()
{
    int V,E,S;  //V = no.of Vertices, E = no.of Edges, S is source vertex

	cout<<"Enter number of vertices in graph\n";
    cin>>V;

	cout<<"Enter number of edges in graph\n";
    cin>>E;

	cout<<"Enter your source vertex number\n";
	cin>>S;

    struct Graph* graph = createGraph(V, E);    //calling the function to allocate space to these many vertices and edges

    int i;
    for(i=0;i<E;i++){
        cout<<"\nEnter edge "<<i+1<<" properties Source, destination, weight respectively\n";
        cin>>graph->edge[i].source;
        cin>>graph->edge[i].destination;
        cin>>graph->edge[i].weight;
    }

    BellmanFord(graph, S);
	//passing created graph and source vertex to BellmanFord Algorithm function

    return 0;
}

Reference: Introduction to Algorithms by Thomas H. Cormen

Comment below if you have queries or found anything incorrect in above tutorial for Bellman-Ford Algorithm in C and C++.

The post Bellman-Ford Algorithm in C and C++ appeared first on The Crazy Programmer.

Dining Philosophers Problem in C and C++

$
0
0

In this tutorial you will learn about Dining Philosophers Problem in C and C++ with program example.

What is Dining Philosophers Problem?

There are some Philosophers whose work is just thinking and eating. Let there are 5 (for example) philosophers. They sat at a round table for dinner. To complete dinner each must need two Forks (spoons). But there are only 5 Forks available (Forks always equal to no. of Philosophers) on table. They take in such a manner that, first take left Fork and next right Fork. But problem is they try to take at same time. Since they are trying at same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1, 2, 3, 4, 5 respectively (since they are left side of each). And each one tries to ta ke right side Fork. But no one found available Fork. And also that each one thinks that someone will release the Fork and then I can eat. This continuous waiting leads to Dead Lock situation.

Dining Philosophers Problem

Also Read: Banker’s Algorithm in C

Dining Arrangement

Solution: To solve this Dead Lock situation, Last philosopher (any one can do this) first try to take right side fork and then left side fork. i.e in our example 5th person tries to take 4th Fork instead of 5th one. Since 4th Fork already taken by 4th the person, he gets nothing. But he left 5th Fork. Now the first person will take this 5th Fork and complete dinner and make 1st and 5th available for remaining people. Next 2nd person takes 1st fork and completes and releases 1st and 2nd. This continuous until all finishes dinner.

Operating System

In Operating System, this concept used in process synchronization. Same problem but instead of Philosophers processes are there and instead of Forks Resources are there. We follow above solution to avoid dead lock condition.

Program for Dining Philosophers Problem in C

#include<stdio.h>

#define n 4

int compltedPhilo = 0,i;

struct fork{
	int taken;
}ForkAvil[n];

struct philosp{
	int left;
	int right;
}Philostatus[n];

void goForDinner(int philID){ //same like threads concept here cases implemented
	if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
        printf("Philosopher %d completed his dinner\n",philID+1);
	//if already completed dinner
	else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
            //if just taken two forks
            printf("Philosopher %d completed his dinner\n",philID+1);

            Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10
            int otherFork = philID-1;

            if(otherFork== -1)
                otherFork=(n-1);

            ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
            printf("Philosopher %d released fork %d and fork %d\n",philID+1,philID+1,otherFork+1);
            compltedPhilo++;
        }
        else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork
                if(philID==(n-1)){
                    if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                        ForkAvil[philID].taken = Philostatus[philID].right = 1;
                        printf("Fork %d taken by philosopher %d\n",philID+1,philID+1);
                    }else{
                        printf("Philosopher %d is waiting for fork %d\n",philID+1,philID+1);
                    }
                }else{ //except last philosopher case
                    int dupphilID = philID;
                    philID-=1;

                    if(philID== -1)
                        philID=(n-1);

                    if(ForkAvil[philID].taken == 0){
                        ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
                        printf("Fork %d taken by Philosopher %d\n",philID+1,dupphilID+1);
                    }else{
                        printf("Philosopher %d is waiting for Fork %d\n",dupphilID+1,philID+1);
                    }
                }
            }
            else if(Philostatus[philID].left==0){ //nothing taken yet
                    if(philID==(n-1)){
                        if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                            ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
                            printf("Fork %d taken by philosopher %d\n",philID,philID+1);
                        }else{
                            printf("Philosopher %d is waiting for fork %d\n",philID+1,philID);
                        }
                    }else{ //except last philosopher case
                        if(ForkAvil[philID].taken == 0){
                            ForkAvil[philID].taken = Philostatus[philID].left = 1;
                            printf("Fork %d taken by Philosopher %d\n",philID+1,philID+1);
                        }else{
                            printf("Philosopher %d is waiting for Fork %d\n",philID+1,philID+1);
                        }
                    }
        }else{}
}

int main(){
	for(i=0;i<n;i++)
        ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;

	while(compltedPhilo<n){
		/* Observe here carefully, while loop will run until all philosophers complete dinner
		Actually problem of deadlock occur only thy try to take at same time
		This for loop will say that they are trying at same time. And remaining status will print by go for dinner function
		*/
		for(i=0;i<n;i++)
            goForDinner(i);
		printf("\nTill now num of philosophers completed dinner are %d\n\n",compltedPhilo);
	}

	return 0;
}

Output

Fork 1 taken by Philosopher 1
Fork 2 taken by Philosopher 2
Fork 3 taken by Philosopher 3
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 0

Fork 4 taken by Philosopher 1
Philosopher 2 is waiting for Fork 1
Philosopher 3 is waiting for Fork 2
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 0

Philosopher 1 completed his dinner
Philosopher 1 released fork 1 and fork 4
Fork 1 taken by Philosopher 2
Philosopher 3 is waiting for Fork 2
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 1

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 2 released fork 2 and fork 1
Fork 2 taken by Philosopher 3
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 2

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Philosopher 3 released fork 3 and fork 2
Fork 3 taken by philosopher 4

Till now num of philosophers completed dinner are 3

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Fork 4 taken by philosopher 4

Till now num of philosophers completed dinner are 3

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Philosopher 4 completed his dinner
Philosopher 4 released fork 4 and fork 3

Till now num of philosophers completed dinner are 4

Program for Dining Philosophers Problem in C++

#include<iostream>

#define n 4

using namespace std;

int compltedPhilo = 0,i;

struct fork{
	int taken;
}ForkAvil[n];

struct philosp{
	int left;
	int right;
}Philostatus[n];

void goForDinner(int philID){ //same like threads concept here cases implemented
	if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
        cout<<"Philosopher "<<philID+1<<" completed his dinner\n";
	//if already completed dinner
	else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
            //if just taken two forks
            cout<<"Philosopher "<<philID+1<<" completed his dinner\n";

            Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10
            int otherFork = philID-1;

            if(otherFork== -1)
                otherFork=(n-1);

            ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
            cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork "<<otherFork+1<<"\n";
            compltedPhilo++;
        }
        else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork
                if(philID==(n-1)){
                    if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                        ForkAvil[philID].taken = Philostatus[philID].right = 1;
                        cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"\n";
                    }else{
                        cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID+1<<"\n";
                    }
                }else{ //except last philosopher case
                    int dupphilID = philID;
                    philID-=1;

                    if(philID== -1)
                        philID=(n-1);

                    if(ForkAvil[philID].taken == 0){
                        ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
                        cout<<"Fork "<<philID+1<<" taken by Philosopher "<<dupphilID+1<<"\n";
                    }else{
                        cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork "<<philID+1<<"\n";
                    }
                }
            }
            else if(Philostatus[philID].left==0){ //nothing taken yet
                    if(philID==(n-1)){
                        if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                            ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
                            cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"\n";
                        }else{
                            cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID<<"\n";
                        }
                    }else{ //except last philosopher case
                        if(ForkAvil[philID].taken == 0){
                            ForkAvil[philID].taken = Philostatus[philID].left = 1;
                            cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"\n";
                        }else{
                            cout<<"Philosopher "<<philID+1<<" is waiting for Fork "<<philID+1<<"\n";
                        }
                    }
        }else{}
}

int main(){
	for(i=0;i<n;i++)
        ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;

	while(compltedPhilo<n){
		/* Observe here carefully, while loop will run until all philosophers complete dinner
		Actually problem of deadlock occur only thy try to take at same time
		This for loop will say that they are trying at same time. And remaining status will print by go for dinner function
		*/
		for(i=0;i<n;i++)
            goForDinner(i);
		cout<<"\nTill now num of philosophers completed dinner are "<<compltedPhilo<<"\n\n";
	}

	return 0;
}

Comment below if you have queries or found any information incorrect in above tutorial for dining philosophers problem in C and C++.

 

The post Dining Philosophers Problem in C and C++ appeared first on The Crazy Programmer.

Asymptotic Notations

$
0
0

Here you will learn about Asymptotic Analysis and Asymptotic Notations in detail.

It is common that we write Algorithm before writing code to any problem. There may exist more than one solution for a particular problem. But we need the solution which is better in time and space complexities. To compare and analyse algorithms complexities we do some analysis called Asymptotic Analysis. That is, we are concerned with the how running time of an algorithm increases with the input. Usually an algorithm asymptotically more efficient will be the best choice.

Also Read: Analysis of Algorithms

Asymptotic Notations

Asymptotic Notations are mathematical tools to represent time complexity of algorithms for asymptotic analysis.

Most commonly used three asymptotic notations are:

Big Oh Notation (O)

Big Oh Notation (O)

It is represented by O (capital alphabet O). See the above diagram.

The function f(n) represents that, how running time of the program is increasing when giving larger inputs to the problem.

Now, we try to find what is the worst case or upper bound of the function f(n). So we draw another function g(n) which is always greater than f(n) after some limit n = n0.

Therefore we say f(n) = O(g(n)), in the condition that, f(n) <= c g(n), where n >= n0., c > 0, n>= 1.

This says that f(n) is smaller than g(n). 

Example

Let f(n) = 3n+2; g(n) = n. To say that f(n) = O g(n),

We need to prove that, f(n) <= cg(n); where c > 0, n>= 1

3n+2 <= cn; If we substitute c = 4, then 3n+2 <= 4n. If we simplify n >= 2.

Therefore for every n >= 2 and c = 4, f(n) <= c g(n). So f(n) = O g(n).

Here we proved that, n is bounding given function so definitely greater than “n”, those are n2, n3.. also upper bound this function. But as per Big-O definition, we are interested in tightest (closest) upper bound. That is the reason we write 3n+2 = O(n).

Big Omega Notation (Ω)

Big Omega Notation (Ω)

It is represented by Greek letter Ω.

See the above picture, the actual increasing function of the algorithm is f(n). And we want to give a lower bound for that, it is cg(n).

cg(n) is less than f(n) after some value of n = n0.

f(n) >= cg(n) , n >= n0, c > 0, n>= 1.

If it satisfies above conditions we say, g(n) is smaller than f(n).

Example

Let, f(n) = 3n+2. g(n) = n.

Now check can this f(n) has lower bound as g(n) or not.

f(n) = Ω g(n), this will happen only if f(n) >= c g(n).

i.e 3n+2 >= cn.  Here c = 1 and n0 >= 1. This is satisfied so f(n) = Ω g(n).

Therefore, 3n+2 is lower bounded by n. Here also since n is lower bound of 3n+2, anything less than n also lower bound to 3n+2. That log(n), log log(n), like that. But as per definition we should take tightest lower bound, which is n.

Big Theta Notation (Θ)

Big Theta Notation (Θ)

This represented by Greek letter Θ.

See the above picture, f(n) is actual growing function. We should find the both the upper bound and lower bound just by varying the constant c, with same function. Here that function is g(n).

If f(n) is bounded by c1 g(n) and c2 g(n) we can say that f(n) = Θ g(n). Constants c1 and c2 could be different.

Therefore we say f(n) = Θ g(n) , if f(n) is bounded by g(n) both in the lower and upper.

c1 g(n) <= f(n) <= c2 g(n), where c1, c2 > 0, n >= n0, n0 >= 1.

Example

F(n) = 3n+2, g(n) = n.

F(n) <= c g(n) where c = 4; That is 3n+2 <= 4n. This is valid for all n>= 1.

So we can say g(n) is upper bound for f(n). Now see it is as well as lower bound also.

F(n) >= c g(n); That is 3n+2 >=  n. where n0 >= 1.

So both the cases are valid for this.

This theta notation also called asymptotically equal.

Applications of These Notations in Algorithms

  • The Big-O notation says the worst case complexity of the algorithm. That means with any large amount of input, that program never exceeds this complexity.
  • The Big-Omega notation says that best case complexity of the algorithm. That means with any small input, the program never executes less than this complexity.
  • Theta notation gives the average case of complexity.
  • Most of the cases we are interested in what is the worst case complexity of the program.

For more understanding, see the example below.

Let there is an array of “n” elements. We want to search an element “x” in that array.

If we do linear search we may find that element at first index i.e in Ω (1) time. This is the best case of this algorithm.

In worst case our element “x” many not exists in array. In that case we must check all elements and end up with no result. i.e O (n) time. This is the worst case of this algorithm.

Average case is, at some index of array we find that element i.e Θ (n/2) complexity.

Some common asymptotic notations are:

Constant time: O(1)

Logarithmic: O(log n)

Linear: O(n)

Quadratic: O(n2)

Cubic: O(n3)

Polynomial: nO(1)

Exponential: 2O(n)

Comment below if you have queries or found any information incorrect in above tutorial for asymptotic notations.

The post Asymptotic Notations appeared first on The Crazy Programmer.

Vigenere Cipher in C and C++

$
0
0

In this tutorial you will learn about vigenere cipher in C and C++ for encryption and decryption.

Vigenere Cipher is kind of polyalphabetic substitution method. It is used for encryption of alphabetic text. For encryption and decryption Vigenere Cipher Table is used in which alphabets from A to Z are written in 26 rows.

Vigenere Cipher Table

Also Read: Caesar Cipher in C and C++ [Encryption & Decryption]

Also Read: Hill Cipher in C and C++ (Encryption and Decryption)

Vigenere Cipher Encryption

Message Text: THECRAZYPROGRAMMER

Key: HELLO

Here we have to obtain a new key by repeating the given key till its length become equal to original message length.

New Generated Key: HELLOHELLOHELLOHEL

For encryption take first letter of message and new key i.e. T and H. Take the alphabet in Vigenere Cipher Table where T row and H column coincides i.e. A.

Repeat the same process for all remaining alphabets in message text. Finally the encrypted message text is:

Encrypted Message: ALPNFHDJAFVKCLATIC

The algorithm can be expressed in algebraic form as given below. The cipher text can be generated by below equation.

E= (P+ Ki) mod 26

Here P is plain text and K is key.

Vigenere Cipher Decryption

Encrypted Message: ALPNFHDJAFVKCLATIC

Key: HELLO

New Generated Key: HELLOHELLOHELLOHEL

Take first alphabet of encrypted message and generated key i.e. A and H. Analyze Vigenere Cipher Table, look for alphabet A in column H, the corresponding row will be the first alphabet of original message i.e. T.

Repeat the same process for all the alphabets in encrypted message.

Original Message: THECRAZYPROGRAMMER

Above process can be represented in algebraic form by following equation.

Pi = (E– Ki + 26) mod 26

We will use above algebraic equations in the program.

Program for Vigenere Cipher in C

#include<stdio.h>
#include<string.h>

int main(){
    char msg[] = "THECRAZYPROGRAMMER";
    char key[] = "HELLO";
    int msgLen = strlen(msg), keyLen = strlen(key), i, j;

    char newKey[msgLen], encryptedMsg[msgLen], decryptedMsg[msgLen];

    //generating new key
    for(i = 0, j = 0; i < msgLen; ++i, ++j){
        if(j == keyLen)
            j = 0;

        newKey[i] = key[j];
    }

    newKey[i] = '\0';

    //encryption
    for(i = 0; i < msgLen; ++i)
        encryptedMsg[i] = ((msg[i] + newKey[i]) % 26) + 'A';

    encryptedMsg[i] = '\0';

    //decryption
    for(i = 0; i < msgLen; ++i)
        decryptedMsg[i] = (((encryptedMsg[i] - newKey[i]) + 26) % 26) + 'A';

    decryptedMsg[i] = '\0';

    printf("Original Message: %s", msg);
    printf("\nKey: %s", key);
    printf("\nNew Generated Key: %s", newKey);
    printf("\nEncrypted Message: %s", encryptedMsg);
    printf("\nDecrypted Message: %s", decryptedMsg);

	return 0;
}

Output

Original Message: THECRAZYPROGRAMMER
Key: HELLO
New Generated Key: HELLOHELLOHELLOHEL
Encrypted Message: ALPNFHDJAFVKCLATIC
Decrypted Message: THECRAZYPROGRAMMER

Program for Vigenere Cipher in C++

#include<iostream>
#include<string.h>

using namespace std;

int main(){
    char msg[] = "THECRAZYPROGRAMMER";
    char key[] = "HELLO";
    int msgLen = strlen(msg), keyLen = strlen(key), i, j;

    char newKey[msgLen], encryptedMsg[msgLen], decryptedMsg[msgLen];

    //generating new key
    for(i = 0, j = 0; i < msgLen; ++i, ++j){
        if(j == keyLen)
            j = 0;

        newKey[i] = key[j];
    }

    newKey[i] = '\0';

    //encryption
    for(i = 0; i < msgLen; ++i)
        encryptedMsg[i] = ((msg[i] + newKey[i]) % 26) + 'A';

    encryptedMsg[i] = '\0';

    //decryption
    for(i = 0; i < msgLen; ++i)
        decryptedMsg[i] = (((encryptedMsg[i] - newKey[i]) + 26) % 26) + 'A';

    decryptedMsg[i] = '\0';

    cout<<"Original Message: "<<msg;
    cout<<"\nKey: "<<key;
    cout<<"\nNew Generated Key: "<<newKey;
    cout<<"\nEncrypted Message: "<<encryptedMsg;
    cout<<"\nDecrypted Message: "<<decryptedMsg;

	return 0;
}

Comment below if you have queries or found anything incorrect in above tutorial for vigenere cipher in C and C++.

The post Vigenere Cipher in C and C++ appeared first on The Crazy Programmer.

Bisection Method in C and C++

$
0
0

In this tutorial you will get program for bisection method in C and C++.

To find a root very accurately Bisection Method is used in Mathematics. Bisection method algorithm is very easy to program and it always converges which means it always finds root.

Bisection Method repeatedly bisects an interval and then selects a subinterval in which root lies. It is a very simple and robust method but slower than other methods.

It is also called Interval halving, binary search method and dichotomy method.

Bisection Method calculates the root by first calculating the mid point of the given interval end points.

Bisection Method in C and C++

Image Source

Bisection Method Procedure

The input for the method is a continuous function f, an interval [a, b], and the function values f(a) and f(b). The function values are of opposite sign (there is at least one zero crossing within the interval). Each iteration performs these steps:

1. Calculate the midpoint c = (a + b)/2

2. Calculate the function value at the midpoint, function(c).

3. If convergence is satisfactory (that is, a – c is sufficiently small, or f(c) is sufficiently small), return c and stop iterating.

4. Examine the sign of f(c) and replace either (a, f(a)) or (b, f(b)) with (c, f(c)) so that there is a zero crossing within the new interval.

Pros and Cons

Advantage of the bisection method is that it is guaranteed to be converged and very easy to implement.

Disadvantage of bisection method is that it cannot detect multiple roots and is slower compared to other methods of calculating the roots.

Program for Bisection Method in C

#include<stdio.h>

//function used is x^3-2x^2+3
double func(double x)
{
    return x*x*x - 2*x*x + 3;
}

double e=0.01;
double c;

void bisection(double a,double b)
{
    if(func(a) * func(b) >= 0)
    {
        printf("Incorrect a and b");
        return;
    }

    c = a;

    while ((b-a) >= e)
    {
        c = (a+b)/2;
        if (func(c) == 0.0){
            printf("Root = %lf\n",c);
            break;
        }
        else if (func(c)*func(a) < 0){
                printf("Root = %lf\n",c);
                b = c;
        }
        else{
                printf("Root = %lf\n",c);
                a = c;
        }
    }
}

int main()
{
    double a,b;
    a=-10;
    b=20;

    printf("The function used is x^3-2x^2+3\n");
    printf("a = %lf\n",a);
    printf("b = %lf\n",b);
    bisection(a,b);
    printf("\n");
    printf("Accurate Root calculated is = %lf\n",c);

    return 0;
}

Output

a = -10.000000
b = 20.000000
Root = 5.000000
Root = -2.500000
Root = 1.250000
Root = -0.625000
Root = -1.562500
Root = -1.093750
Root = -0.859375
Root = -0.976563
Root = -1.035156
Root = -1.005859
Root = -0.991211
Root = -0.998535

Accurate Root calculated is = -0.998535

Program for Bisection Method in C++

#include<iostream>

using namespace std;

//function used is x^3-2x^2+3
double func(double x)
{
    return x*x*x - 2*x*x + 3;
}

double e=0.01;
double c;

void bisection(double a,double b)
{
    if(func(a) * func(b) >= 0)
    {
        cout<<"Incorrect a and b";
        return;
    }

    c = a;

    while ((b-a) >= e)
    {
        c = (a+b)/2;
        if (func(c) == 0.0){
            cout << "Root = " << c<<endl;
            break;
        }
        else if (func(c)*func(a) < 0){
                cout << "Root = " << c<<endl;
                b = c;
        }
        else{
                cout << "Root = " << c<<endl;
                a = c;
        }
    }
}

int main()
{
    double a,b;
    a=-10;
    b=20;

    cout<<"The function used is x^3-2x^2+3\n";
    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
    bisection(a,b);
    cout<<"\n";
    cout<<"Accurate Root calculated is = "<<c<<endl;

    return 0;
}

This article is submitted by Rahul Maheshwari. You can connect with him on facebook.

Comment below if you have any queries regarding above program for bisection method in C and C++.

The post Bisection Method in C and C++ appeared first on The Crazy Programmer.

Sliding Window Protocol Program in C and C++

$
0
0

Here you will get sliding window protocol program in C.

In computer networks sliding window protocol is a method to transmit data on a network. Sliding window protocol is applied on the Data Link Layer of OSI model. At data link layer data is in the form of frames. In Networking, Window simply means a buffer which has data frames that needs to be transmitted.

Both sender and receiver agrees on some window size. If window size=w then after sending w frames sender waits for the acknowledgement (ack) of the first frame.

As soon as sender receives the acknowledgement of a frame it is replaced by the next frames to be transmitted by the sender. If receiver sends a collective or cumulative acknowledgement to sender then it understands that more than one frames are properly received, for eg:- if ack of frame 3 is received it understands that frame 1 and frame 2 are received properly.

Sliding Window Protocol

Image Source

In sliding window protocol the receiver has to have some memory to compensate any loss in transmission or if the frames are received unordered.

Efficiency of Sliding Window Protocol

η = (W*tx)/(tx+2tp)

W = Window Size

tx = Transmission time

tp = Propagation delay

Sliding window works in full duplex mode

It is of two types:-

1. Selective Repeat: Sender transmits only that frame which is erroneous or is lost.

2. Go back n: Sender transmits all frames present in the window that occurs after the error bit including error bit also.

Sliding Window Protocol Program in C

Below is the simulation of sliding window protocol in C.

#include<stdio.h>

int main()
{
    int w,i,f,frames[50];

    printf("Enter window size: ");
    scanf("%d",&w);

    printf("\nEnter number of frames to transmit: ");
    scanf("%d",&f);

    printf("\nEnter %d frames: ",f);

    for(i=1;i<=f;i++)
        scanf("%d",&frames[i]);

    printf("\nWith sliding window protocol the frames will be sent in the following manner (assuming no corruption of frames)\n\n");
    printf("After sending %d frames at each stage sender waits for acknowledgement sent by the receiver\n\n",w);

    for(i=1;i<=f;i++)
    {
        if(i%w==0)
        {
            printf("%d\n",frames[i]);
            printf("Acknowledgement of above frames sent is received by sender\n\n");
        }
        else
            printf("%d ",frames[i]);
    }

    if(f%w!=0)
        printf("\nAcknowledgement of above frames sent is received by sender\n");

    return 0;
}

Output

Enter window size: 3

Enter number of frames to transmit: 5

Enter 5 frames: 12 5 89 4 6

With sliding window protocol the frames will be sent in the following manner (assuming no corruption of frames)

After sending 3 frames at each stage sender waits for acknowledgement sent by the receiver

12 5 89
Acknowledgement of above frames sent is received by sender

4 6
Acknowledgement of above frames sent is received by sender

Sliding Window Protocol Program in C++

Below is the simulation of sliding window protocol in C++.

#include<iostream>

using namespace std;

int main()
{
    int w,i,f,frames[50];

    cout<<"Enter window size: ";
    cin>>w;

    cout<<"\nEnter number of frames to transmit: ";
    cin>>f;

    cout<<"\nEnter "<<f<<" frames: ";

    for(i=1;i<=f;i++)
        cin>>frames[i];

    cout<<"\nWith sliding window protocol the frames will be sent in the following manner (assuming no corruption of frames)\n\n";
    cout<<"After sending "<<w<<" frames at each stage sender waits for acknowledgement sent by the receiver\n\n";

    for(i=1;i<=f;i++)
    {
        if(i%w==0)
        {
            cout<<frames[i]<<"\n";
            cout<<"Acknowledgement of above frames sent is received by sender\n\n";
        }
        else
            cout<<frames[i]<<" ";
    }

    if(f%w!=0)
        cout<<"\nAcknowledgement of above frames sent is received by sender\n";

    return 0;
}

Comment below if you have any queries regarding above program.

The post Sliding Window Protocol Program in C and C++ appeared first on The Crazy Programmer.


Analysis of Algorithms

$
0
0

In this tutorial you will learn about analysis of algorithms.

Before learning analysis of algorithms lets quickly take a look on what is an algorithm and why we require it.

What is an Algorithm?

An algorithm is the step by step unambiguous procedure to solve a given problem.

For example steps for making Tea or Coffee can be considered as an algorithm.

So for solving a problem we require an algorithm.

Analysis of Algorithms

Design and Analysis of Algorithms

Image Source

There can be several algorithms for solving one problem. So analysis of algorithms is required to find the correctness (algorithm should give solution of problem in finite number of steps) and efficiency (time and memory it takes) of an algorithm.

For example: To go from city A to B there can be several ways like by bus, train, flight, etc.  Depending upon the availability and convenience we choose the one that suits best for us.

Similarly in computer science we use analysis of algorithms to choose the algorithm which is most efficient in terms of running time and space required.

Running Time Analysis

It is the process of determining how processing time of an algorithm increase as the input size increase.

Input size is the number of elements in the input. There can be different types of inputs depending upon the problem type. Below are some common types of inputs.

  • Size of an array.
  • Number of elements in matrix.
  • Vertices and edges in a graph.

Also Read: Asymptotic Notations

Types of Analysis

To analyze an algorithm we need to know for which input the algorithm takes less time and for which input it takes long time.

In terms of running time there can be three cases mentioned below.

Worst Case: It defines the input for which the algorithm takes longest time (slowest time) to complete.

Best Case: It defines the input for which the algorithm takes least time (fastest time) to complete.

Average Case: Run the algorithm using different random inputs and then find total running time by finding average of all running times.

Comment below if have any queries regarding above tutorial.

The post Analysis of Algorithms appeared first on The Crazy Programmer.

Travelling Salesman Problem in C and C++

$
0
0

Here you will learn about Travelling Salesman Problem (TSP) with example and also get a program that implements Travelling Salesman Problem in C and C++.

Let say there are some villages (1, 2, 3, 4, 5). To work with worst case let assume each villages connected with every other villages. And there is a Salesman living in village 1 and he has to sell his things in all villages by travelling and he has to come back to own village 1.

He has to travel each village exactly once, because it is waste of time and energy that revisiting same village. This is same as visiting each node exactly once, which is Hamiltonian Circuit. But our problem is bigger than Hamiltonian cycle because this is not only just finding Hamiltonian path, but also we have to find shortest path.

Finally the problem is we have to visit each vertex exactly once with minimum edge cost in a graph.

Brute Force Approach takes O (nn) time, because we have to check (n-1)! paths (i.e all permutations) and have to find minimum among them.

The correct approach for this problem is solving using Dynamic Programming.

Dynamic Programming can be applied only if main problem can be divided into sub-problems. Let’s check that.

Travelling Salesman Problem (TSP) Using Dynamic Programming

Example Problem

Travelling Salesman Problem (TSP)

Above we can see a complete directed graph and cost matrix which includes distance between each village. We can observe that cost matrix is symmetric that means distance between village 2 to 3 is same as distance between village 3 to 2.

Here problem is travelling salesman wants to find out his tour with minimum cost.

Say it is T (1,{2,3,4}), means, initially he is at village 1 and then he can go to any of {2,3,4}. From there to reach non-visited vertices (villages) becomes a new problem. Here we can observe that main problem spitted into sub-problem, this is property of dynamic programming.

Note: While calculating below right side values calculated in bottom-up manner. Red color values taken from below calculations.

T ( 1, {2,3,4} ) = minimum of

= { (1,2) + T (2,  {3,4} )     4+6=10

= { (1,3)  + T (3, {2,4} )     1+3=4

= { (1,4) + T (4, {2,3} )     3+3=6

Here minimum of above 3 paths is answer but we know only values of (1,2) , (1,3) , (1,4) remaining thing which is T ( 2, {3,4} ) …are new problems now. First we have to solve those and substitute here.

T (2, {3,4} )   = minimum of

=  { (2,3) + T (3, {4} )     2+5=7

= { (2,4) + T {4, {3} )     1+5=6

T (3, {2,4} )   = minimum of

=  { (3,2) + T (2, {4} )     2+1=3

= { (3,4) + T {4, {2} )     5+1=6

T (4, {2,3} )   = minimum of

=  { (4,2) + T (2, {3} )     1+2=3

= { (4,3) + T {3, {2} )     5+2=7

T ( 3, {4} ) =  (3,4) + T (4, {} )     5+0=5

T ( 4, {3} ) =  (4,3) + T (3, {} )     5+0=5

T ( 2, {4} ) =  (2,4) + T (4, {} )     1+0=1

T ( 4, {2} ) =  (4,2) + T (2, {} )     1+0 = 1

T ( 2, {3} ) =  (2,3) + T (3, {} )     2+0 = 2

T ( 3, {2} ) =  (3,2) + T (2, {} )     2+0=2

Here T ( 4, {} ) is reaching base condition in recursion, which returns 0 (zero ) distance.

This is where we can find final answer,

T ( 1, {2,3,4} ) = minimum of

= { (1,2) + T (2,  {3,4} )     4+6=10 in this path we have to add +1 because this path ends with 3. From there we have to reach 1 so 3->1 distance 1 will be added total distance is 10+1=11

= { (1,3)  + T (3, {2,4} )     1+3=4 in this path we have to add +3 because this path ends with 3. From there we have to reach 1 so 4->1 distance 3 will be added total distance is 4+3=7

= { (1,4) + T (4, {2,3} )     3+3=6 in this path we have to add +1 because this path ends with 3. From there we have to reach 1 so 3->1 distance 1 will be added total distance is 6+1=7

Minimum distance is 7 which includes path 1->3->2->4->1.

After solving example problem we can easily write recursive equation.

Recursive Equation

T (i , s) = min ( ( i , j) + T ( j , S – { j }) ) ;  S!= Ø   ; j € S ;

S is set that contains non visited vertices

=  ( i, 1 ) ;  S=Ø, This is base condition for this recursive equation.

Here,

T (i, S) means We are travelling from a vertex “i” and have to visit set of non-visited vertices  “S” and have to go back to vertex 1 (let we started from vertex 1).

( i, j ) means cost of path from node i  to node j

If we observe the first recursive equation from a node we are finding cost to all other nodes (i,j) and from that node to remaining using recursion ( T (j , {S-j}))

But it is not guarantee that every vertex is connected to other vertex then we take that cost as infinity. After that we are taking minimum among all so the path which is not connected get infinity in calculation and won’t be consider.

If S is empty that means we visited all nodes, we take distance from that last visited node to node 1 (first node). Because after visiting all he has to go back to initial node.

Time Complexity

Since we are solving this using Dynamic Programming, we know that Dynamic Programming approach contains sub-problems.

Here after reaching ith node finding remaining minimum distance to that ith node is a sub-problem.

If we solve recursive equation we will get total (n-1) 2(n-2)  sub-problems, which is O (n2n).

Each sub-problem will take  O (n) time (finding path to remaining (n-1) nodes).

Therefore total time complexity is O (n2n) * O (n) = O (n22n)

Space complexity is also number of sub-problems which is O (n2n)

Program for Travelling Salesman Problem in C

#include<stdio.h>

int ary[10][10],completed[10],n,cost=0;

void takeInput()
{
	int i,j;

	printf("Enter the number of villages: ");
	scanf("%d",&n);

	printf("\nEnter the Cost Matrix\n");

	for(i=0;i < n;i++)
	{
		printf("\nEnter Elements of Row: %d\n",i+1);

		for( j=0;j < n;j++)
			scanf("%d",&ary[i][j]);

		completed[i]=0;
	}

	printf("\n\nThe cost list is:");

	for( i=0;i < n;i++)
	{
		printf("\n");

		for(j=0;j < n;j++)
			printf("\t%d",ary[i][j]);
	}
}

void mincost(int city)
{
	int i,ncity;

	completed[city]=1;

	printf("%d--->",city+1);
	ncity=least(city);

	if(ncity==999)
	{
		ncity=0;
		printf("%d",ncity+1);
		cost+=ary[city][ncity];

		return;
	}

	mincost(ncity);
}

int least(int c)
{
	int i,nc=999;
	int min=999,kmin;

	for(i=0;i < n;i++)
	{
		if((ary[c][i]!=0)&&(completed[i]==0))
			if(ary[c][i]+ary[i][c] < min)
			{
				min=ary[i][0]+ary[c][i];
				kmin=ary[c][i];
				nc=i;
			}
	}

	if(min!=999)
		cost+=kmin;

	return nc;
}

int main()
{
	takeInput();

	printf("\n\nThe Path is:\n");
	mincost(0); //passing 0 because starting vertex

	printf("\n\nMinimum cost is %d\n ",cost);

	return 0;
}

Output

Enter the number of villages: 4

Enter the Cost Matrix

Enter Elements of Row: 1
0 4 1 3

Enter Elements of Row: 2
4 0 2 1

Enter Elements of Row: 3
1 2 0 5

Enter Elements of Row: 4
3 1 5 0
The cost list is:
0 4 1 3
4 0 2 1
1 2 0 5
3 1 5 0

The Path is:
1—>3—>2—>4—>1

Minimum cost is 7

Program for Travelling Salesman Problem in C++

#include<iostream>

using namespace std;

int ary[10][10],completed[10],n,cost=0;

void takeInput()
{
	int i,j;

	cout<<"Enter the number of villages: ";
	cin>>n;

	cout<<"\nEnter the Cost Matrix\n";

	for(i=0;i < n;i++)
	{
		cout<<"\nEnter Elements of Row: "<<i+1<<"\n";

		for( j=0;j < n;j++)
			cin>>ary[i][j];

		completed[i]=0;
	}

	cout<<"\n\nThe cost list is:";

	for( i=0;i < n;i++)
	{
		cout<<"\n";

		for(j=0;j < n;j++)
			cout<<"\t"<<ary[i][j];
	}
}

int least(int c)
{
	int i,nc=999;
	int min=999,kmin;

	for(i=0;i < n;i++)
	{
		if((ary[c][i]!=0)&&(completed[i]==0))
			if(ary[c][i]+ary[i][c] < min)
			{
				min=ary[i][0]+ary[c][i];
				kmin=ary[c][i];
				nc=i;
			}
	}

	if(min!=999)
		cost+=kmin;

	return nc;
}

void mincost(int city)
{
	int i,ncity;

	completed[city]=1;

	cout<<city+1<<"--->";
	ncity=least(city);

	if(ncity==999)
	{
		ncity=0;
		cout<<ncity+1;
		cost+=ary[city][ncity];

		return;
	}

	mincost(ncity);
}

int main()
{
	takeInput();

	cout<<"\n\nThe Path is:\n";
	mincost(0); //passing 0 because starting vertex

	cout<<"\n\nMinimum cost is "<<cost;

	return 0;
}

Comment below if you found any information incorrect or have doubts regarding Travelling Salesman Problem algorithm.

The post Travelling Salesman Problem in C and C++ appeared first on The Crazy Programmer.

Matrix Chain Multiplication in C and C++

$
0
0

Here you will learn about Matrix Chain Multiplication with example and also get a program that implements matrix chain multiplication in C and C++.

Before going to main problem first remember some basis.

We know that, to multiply two matrices it is condition that, number of columns in first matrix should be equal to number of rows in second matrix. Let say there are two matrices A and B with dimensions A (2 x 3) and B (3 x 2).

Let’s see an example.

Matrix Chain Multiplication

Above we can see resultant matrix is (2 x 2) matrix i.e. it contains total 4 elements. To calculate each element we did 3 multiplications (which is equal to number of columns in first matrix and number of rows in second matrix). So totally for 4 elements 4*3 = 12 multiplications are required.

In generalized way matrices A (P x Q) and B(Q x R) will result matrix (P x R) which contains P * R elements. To calculate each element need “Q” number of multiplications. Total multiplications needed are P * Q * R

Let’s  try to multiply more than two matrices.

If 3 matrices A, B ,C we can find the final result in two ways (AB)C or A(BC). We get same result in any way since matrix multiplication satisfies associativity property.

Let A (1 x 2 ), B (2 x 3 ), C ( 3 x 2 ). If we follow first way, i.e. (AB)C way.

To calculate (AB) we need 1*2*3 = 6 multiplications. Now resultant AB get dimensions 1 x 3 this multiplied with C need 1*3*2 = 6 multiplications. Total 6+6 = 12 multiplications needed.

If we follow second way, i.e. A(BC) way.

To calculate (BC) we need 2*3*2 = 12 multiplications. Now resultant BC get dimensions 2 x 3. A multiplied with this result need 1*2*3 = 6. Total 12+6 = 18 multiplications needed.

Here we can observe that based on the way we parenthesize the matrices total number of multiplications are changing.

If 4 matrices A, B, C, D we can find final result in 5 ways A(B(CD)) or A((BC)(D)) or (AB)(CD) 4. ((AB)C)D  or (A(BC))D. In this case also each way requires different number of multiplications.

General formula to find number of ways we can find solution is  (2n)! / [ (n+1)! n! ]. After parenthesizing these many ways each way requires different number of multiplications for final result. When dimensions are large (200 x 250 like this) with more number of matrices, then finding the parenthesizing way which requires minimum number of multiplications need will gives less time complexity.

So Matrix Chain Multiplication problem aim is not to find the final result of multiplication, it is finding how to parenthesize matrices so that, requires minimum number of multiplications.

Efficient way of solving this is using dynamic programming

Matrix Chain Multiplication Using Dynamic Programming

Let we have “n” number of matrices A1, A2, A3 ……… An and dimensions are d0 x d1, d1 x d2, d2 x d3 …………. dn-1 x dn  (i.e Dimension of Matrix Ai is di-1 x di

Solving a chain of matrix that,  Ai  Ai+1  Ai+2  Ai+3 ……. Aj = (Ai  Ai+1  Ai+2  Ai+3 ……. Ak ) (Ak+1  Ak+2 ……. Aj ) + di-1 dk dj where i <= k < j.

For more understanding check below example.

Here total i to j matrices, Matrix i to k and Matrix k+1 to j should be solved in recursive way and finally these two matrices multiplied and these dimensions di-1 dk dj (number of multiplications needed) added. The variable k is changed i to j.

Recursive Equation

Note: M[i, j] indicates that if we split from matrix i to matrix j then minimum number of scalar multiplications required.

M [ i , j ] = { 0 ; when i=j ; [means it is a single matrix . If there is only one matrix no need to multiply  with any other. So 0 (zero) multiplications required.]

= { min { M[ i, k ] + M[k+1, j  ] + di-1 dk dj } where i <= k< j

Example Problem

Given problem: A1 (10 x 100), A2 (100 x 20), A3(20 x 5), A4 (5 x 80)

To store results, in dynamic programming we create a table

1,1=0 2,2=0 3,3=0 4,4=0
1,2=20000 2,3=10000 3,4=8000
1,3=15000 2,4=50000
1,4=19000

This table filled using below calculations.

Here cell 2,3 stores the minimum number of scalar multiplications required to.

Using above recursive equation we can fill entire first row with all 0’s (zeros) because i=j (i.e. split happened at only one matrix which requires zero multiplications)

Table [1,2] = 10*100*20 = 20000

Table [2,3] = 100*20*5 = 10000

Table [3,4] = 20*5*80 = 8000

Table [1,3] = minimum of

= { (1,1) + (2,3) + 10* 100*5  = 0+10000+5000 = 15000

= { (1,2) + (3,3) + 10*20*5 = 20000+0+1000 = 21000

Therefore Table[1,3] is 15000 and split happened at 1

Table [2,4] = minimum of

= { (2,2) +(3,4) + 100*20*80 = 0 + 8000 + 160000 = 168000

= { (2,3) + (4,4) + 100*5*80 = 10000 + 0 + 40000 = 50000

Therefore Table of [2,4] is 50000 and split happened at 3

Table of [1,4] = minimum of

= { (1,1) +(2,4) + 10*100*80 = 0 + 50000 + 80000 = 130000

= { (1,2) +(3,4) + 10* 20* 80 = 20000 + 8000 + 16000 = 44000

= { (1,3) + (4,4) + 10*5*80 = 15000+0+4000 = 19000

Therefore table of [1,4] is 19000 which is final answer and split happened at 3.

Splitting way: (1234) is original in final outcome where 19000 answer we got split happened at 3 so ( 1 2 3 ) (4). Split for (123) means see at Table [1,3] that one minimum 15000 split at 1 . So ( ( 1 ) ( 2 3 ) ) ( 4). That means first do 2 x 3 and this 1 x first result and then this result x 4.

Time Complexity

If there are n number of matrices we are creating a table contains [(n) (n+1) ] / 2 cells that is in worst case total number of cells n*n = n2 cells we need calculate = O (n2)

For each one of entry we need find minimum number of multiplications taking worst (it happens at  last cell in table) that is Table [1,4] which equals to  O (n) time.

Finally O (n2) * O (n) = O (n3) is time complexity.

Space Complexity

We are creating a table of n x n so space complexity is O (n2).

Program for Matrix Chain Multiplication in C

// This code implemented using Algorithm in Coremen book

#include<stdio.h>
#include<limits.h>

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n

int MatrixChainMultiplication(int p[], int n)
{
    int m[n][n];
    int i, j, k, L, q;

    for (i=1; i<n; i++)
        m[i][i] = 0;    //number of multiplications are 0(zero) when there is only one matrix

    //Here L is chain length. It varies from length 2 to length n.
    for (L=2; L<n; L++)
    {
        for (i=1; i<n-L+1; i++)
        {
            j = i+L-1;
            m[i][j] = INT_MAX;  //assigning to maximum value

            for (k=i; k<=j-1; k++)
            {
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                {
                    m[i][j] = q;    //if number of multiplications found less that number will be updated.
                }
            }
        }
    }

    return m[1][n-1];   //returning the final answer which is M[1][n]

}

int main()
{
    int n,i;
    printf("Enter number of matrices\n");
    scanf("%d",&n);

    n++;

    int arr[n];

    printf("Enter dimensions \n");

    for(i=0;i<n;i++)
    {
        printf("Enter d%d :: ",i);
        scanf("%d",&arr[i]);
    }

    int size = sizeof(arr)/sizeof(arr[0]);

    printf("Minimum number of multiplications is %d ", MatrixChainMultiplication(arr, size));

    return 0;
}

Output

Enter number of matrices
4
Enter dimensions
Enter d0 :: 10
Enter d1 :: 100
Enter d2 :: 20
Enter d3 :: 5
Enter d4 :: 80
Minimum number of multiplications is 19000

Program for Matrix Chain Multiplication in C++

// This code implemented using Algorithm in Coremen book

#include<iostream>
#include<limits.h>

using namespace std;

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n

int MatrixChainMultiplication(int p[], int n)
{
    int m[n][n];
    int i, j, k, L, q;

    for (i=1; i<n; i++)
        m[i][i] = 0;    //number of multiplications are 0(zero) when there is only one matrix

    //Here L is chain length. It varies from length 2 to length n.
    for (L=2; L<n; L++)
    {
        for (i=1; i<n-L+1; i++)
        {
            j = i+L-1;
            m[i][j] = INT_MAX;  //assigning to maximum value

            for (k=i; k<=j-1; k++)
            {
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                {
                    m[i][j] = q;    //if number of multiplications found less that number will be updated.
                }
            }
        }
    }

    return m[1][n-1];   //returning the final answer which is M[1][n]

}

int main()
{
    int n,i;
    cout<<"Enter number of matrices\n";
    cin>>n;

    n++;

    int arr[n];

    cout<<"Enter dimensions \n";

    for(i=0;i<n;i++)
    {
        cout<<"Enter d"<<i<<" :: ";
        cin>>arr[i];
    }

    int size = sizeof(arr)/sizeof(arr[0]);

    cout<<"Minimum number of multiplications is "<<MatrixChainMultiplication(arr, size));

    return 0;
}

Comment below if you have any queries related to above program for matrix chain multiplication in C and C++.

The post Matrix Chain Multiplication in C and C++ appeared first on The Crazy Programmer.

Bellman-Ford Algorithm in C and C++

$
0
0

Here you will learn about Bellman-Ford Algorithm in C and C++.

Dijkstra and Bellman-Ford Algorithms used to find out single source shortest paths. i.e. there is a source node, from that node we have to find shortest distance to every other node. Dijkstra algorithm fails when graph has negative weight cycle. But Bellman-Ford Algorithm won’t fail even, the graph has negative edge cycle. If there any negative edge cycle it will detect and say there is negative edge cycle. If not it will give answer to given problem.

Bellman-Ford Algorithm will work on logic that, if graph has n nodes, then shortest path never contain more than n-1 edges. This is exactly what Bellman-Ford do. It is enough to relax each edge (v-1) times to find shortest path. But to find whether there is negative cycle or not we again do one more relaxation. If we get less distance in nth relaxation we can say that there is negative edge cycle. Reason for this is negative value added and distance get reduced.

Relaxing edge

In algorithm and code below we use this term Relaxing edge.

Relaxing edge is an operation performed on an edge (u, v) . when,

d(u) > d(v) + Cost(u,v)

Here d(u) means distance of u. If already known distance to “u” is greater than the path from “s” to “v” and “v” to “u” we update that d(u) value with d(v) + cost(u,v).

Algorithm and Time Complexity

Bellman-Ford (G,w,S){   //G is graph given, W is weight matrix, S is source vertex (starting vertex)
    Initialize single source (G,S)  //means initially distance to every node is infinity except to source. Source is 0 (zero). This will take O(v) time

    For i=1 to |G.V| -1     //Runs (v-1) times
        For each edge (G,V)€ G.E    // E times
            Relax(u,v,w)    //O(1) time

    For each edge (G,V) € G.E
        If (v.d > u.d + w(u,v))     //The idea behind this is we are relaxing edges nth time if we found more shortest path than (n-1)th level, we can say that graph is having negative edge cycle and detected.
            Return False

    return true
}

Finally time complexity is (v-1) (E) O(1) = O(VE)

Example Problem

Bellman-Ford Algorithm 1

This is the given directed graph.

(s,t) = 6  (y,x) = -3

(s,y)= 7  (y,z) = 9

(t,y) = 8  (x,t) = -2

(t,z) = -4  (z,x) = 7

(t,x) = 5  (z,s) = 2

Above we can see using vertex “S” as source (Setting distance as 0), we initialize all other distance as infinity.

  S T X Y Z
distance 0
Path

Table and Image explanation: This table, 2nd row shows distance from source to that particular node ad 3rd row shows to reach that node what is the node we visited recently. This path we can see in the image also.

Note: In each iteration, iteration “n” means it contains the path at most “n” edges. And while we are doing iteration “n” we must follow the graph which we obtained in iteration “n-1”.

Iteration 1: edge (s,t) and (z,y) relaxed and updating the distances to t and y.

Bellman-Ford Algorithm

  S T X Y Z
distance 0 6 7
Path S S

Iteration 2 : edge (t,z) and (y,x) relaxed and x and z values are updated.

Bellman-Ford Algorithm 3

  S T X Y Z
distance 0 6 4 7 2
Path S Y S T

Iteration 3: Value of t updated by relaxing (x,t)

Bellman-Ford Algorithm 4

  S T X Y Z
distance 0 2 4 7 2
Path X Y S T

Iteration 4: Value of z updated by relaxing edge (t,z)

Bellman-Ford Algorithm 5

Until now 4 iterations completed and shortest path found to every node form source node. Now we have to do one more iteration to find whether there exists negative edge cycle or not. When we do this nth (5th here) relaxation if we found less distance to any vertex from any other path we can say that there is negative edge cycle. Here we can relax any edge to graph which obtained in iteration 4and we can observe that there is no chance to change those values. So we can confirm that there is no negative edge cycle in this graph.

Program for Bellman-Ford Algorithm in C

Code explanation

Bellman-Ford Algorithm 6

This picture shows the Structure of our input graph.

We create a structure called “Graph” which contains two integers int v (represent number of vertices) and int E (represents number of edges) and also another structure inside this structure which represents edge. That structure contains 3 integers source, destination, weight of that edge. So we create “E” number of structures inside the structure Graph.

After creating Graph, choose a source node and send to BellmanFord function. In this function we relax each edge “v-1” times. After this we can store the result of shortest paths in an array. And we do one more relaxation to find whether there exists negative edge cycle or not. If we got less distance at any node in Vth relaxation of edges, then we can say that the graph have negative edge cycle.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

struct Edge
{
    // This structure is equal to an edge. Edge contains two end points. These edges are directed edges so they
	//contain source and destination and some weight. These 3 are elements in this structure
    int source, destination, weight;
};

// a structure to represent a connected, directed and weighted graph
struct Graph
{
    int V, E;
	// V is number of vertices and E is number of edges

    struct Edge* edge;
	// This structure contain another structure which we already created edge.
};

struct Graph* createGraph(int V, int E)
{
    struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph));
	//Allocating space to structure graph

    graph->V = V;   //assigning values to structure elements that taken form user.

    graph->E = E;

    graph->edge = (struct Edge*) malloc( graph->E * sizeof( struct Edge ) );
	//Creating "Edge" type structures inside "Graph" structure, the number of edge type structures are equal to number of edges

    return graph;
}

void FinalSolution(int dist[], int n)
{
	// This function prints the final solution
    printf("\nVertex\tDistance from Source Vertex\n");
    int i;

    for (i = 0; i < n; ++i){
		printf("%d \t\t %d\n", i, dist[i]);
	}
}

void BellmanFord(struct Graph* graph, int source)
{
    int V = graph->V;

    int E = graph->E;

    int StoreDistance[V];

    int i,j;

    // This is initial step that we know , we initialize all distance to infinity except source.
	// We assign source distance as 0(zero)

    for (i = 0; i < V; i++)
        StoreDistance[i] = INT_MAX;

    StoreDistance[source] = 0;

    //The shortest path of graph that contain V vertices, never contain "V-1" edges. So we do here "V-1" relaxations
    for (i = 1; i <= V-1; i++)
    {
        for (j = 0; j < E; j++)
        {
            int u = graph->edge[j].source;

            int v = graph->edge[j].destination;

            int weight = graph->edge[j].weight;

            if (StoreDistance[u] + weight < StoreDistance[v])
                StoreDistance[v] = StoreDistance[u] + weight;
        }
    }

    // Actually upto now shortest path found. But BellmanFord checks for negative edge cycle. In this step we check for that
    // shortest distances if graph doesn't contain negative weight cycle.

    // If we get a shorter path, then there is a negative edge cycle.
    for (i = 0; i < E; i++)
    {
        int u = graph->edge[i].source;

        int v = graph->edge[i].destination;

        int weight = graph->edge[i].weight;

        if (StoreDistance[u] + weight < StoreDistance[v])
            printf("This graph contains negative edge cycle\n");
    }

    FinalSolution(StoreDistance, V);

    return;
}

int main()
{
    int V,E,S;  //V = no.of Vertices, E = no.of Edges, S is source vertex

	printf("Enter number of vertices in graph\n");
    scanf("%d",&V);

	printf("Enter number of edges in graph\n");
    scanf("%d",&E);

	printf("Enter your source vertex number\n");
	scanf("%d",&S);

    struct Graph* graph = createGraph(V, E);    //calling the function to allocate space to these many vertices and edges

    int i;
    for(i=0;i<E;i++){
        printf("\nEnter edge %d properties Source, destination, weight respectively\n",i+1);
        scanf("%d",&graph->edge[i].source);
        scanf("%d",&graph->edge[i].destination);
        scanf("%d",&graph->edge[i].weight);
    }

    BellmanFord(graph, S);
	//passing created graph and source vertex to BellmanFord Algorithm function

    return 0;
}

Output

Enter number of vertices in graph
5
Enter number of edges in graph
10
Enter your source vertex number
0

Enter edge 1 properties Source, destination, weight respectively
0 1 6

Enter edge 2 properties Source, destination, weight respectively
0 2 7

Enter edge 3 properties Source, destination, weight respectively
1 2 8

Enter edge 4 properties Source, destination, weight respectively
1 4 -4

Enter edge 5 properties Source, destination, weight respectively
1 3 5

Enter edge 6 properties Source, destination, weight respectively
3 1 -2

Enter edge 7 properties Source, destination, weight respectively
2 3 -3

Enter edge 8 properties Source, destination, weight respectively
2 4 9

Enter edge 9 properties Source, destination, weight respectively
4 0 2

Enter edge 10 properties Source, destination, weight respectively
4 3 7

Vertex  Distance from Source Vertex
0  0
1  2
2  7
3  4
4  -2

Program for Bellman-Ford Algorithm in C++

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

using namespace std;

struct Edge
{
    // This structure is equal to an edge. Edge contains two end points. These edges are directed edges so they
	//contain source and destination and some weight. These 3 are elements in this structure
    int source, destination, weight;
};

// a structure to represent a connected, directed and weighted graph
struct Graph
{
    int V, E;
	// V is number of vertices and E is number of edges

    struct Edge* edge;
	// This structure contain another structure which we already created edge.
};

struct Graph* createGraph(int V, int E)
{
    struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph));
	//Allocating space to structure graph

    graph->V = V;   //assigning values to structure elements that taken form user.

    graph->E = E;

    graph->edge = (struct Edge*) malloc( graph->E * sizeof( struct Edge ) );
	//Creating "Edge" type structures inside "Graph" structure, the number of edge type structures are equal to number of edges

    return graph;
}

void FinalSolution(int dist[], int n)
{
	// This function prints the final solution
    cout<<"\nVertex\tDistance from Source Vertex\n";
    int i;

    for (i = 0; i < n; ++i){
		cout<<i<<"\t\t"<<dist[i]<<"\n";
	}
}

void BellmanFord(struct Graph* graph, int source)
{
    int V = graph->V;

    int E = graph->E;

    int StoreDistance[V];

    int i,j;

    // This is initial step that we know , we initialize all distance to infinity except source.
	// We assign source distance as 0(zero)

    for (i = 0; i < V; i++)
        StoreDistance[i] = INT_MAX;

    StoreDistance[source] = 0;

    //The shortest path of graph that contain V vertices, never contain "V-1" edges. So we do here "V-1" relaxations
    for (i = 1; i <= V-1; i++)
    {
        for (j = 0; j < E; j++)
        {
            int u = graph->edge[j].source;

            int v = graph->edge[j].destination;

            int weight = graph->edge[j].weight;

            if (StoreDistance[u] + weight < StoreDistance[v])
                StoreDistance[v] = StoreDistance[u] + weight;
        }
    }

    // Actually upto now shortest path found. But BellmanFord checks for negative edge cycle. In this step we check for that
    // shortest distances if graph doesn't contain negative weight cycle.

    // If we get a shorter path, then there is a negative edge cycle.
    for (i = 0; i < E; i++)
    {
        int u = graph->edge[i].source;

        int v = graph->edge[i].destination;

        int weight = graph->edge[i].weight;

        if (StoreDistance[u] + weight < StoreDistance[v])
            cout<<"\nThis graph contains negative edge cycle\n";
    }

    FinalSolution(StoreDistance, V);

    return;
}

int main()
{
    int V,E,S;  //V = no.of Vertices, E = no.of Edges, S is source vertex

	cout<<"Enter number of vertices in graph\n";
    cin>>V;

	cout<<"Enter number of edges in graph\n";
    cin>>E;

	cout<<"Enter your source vertex number\n";
	cin>>S;

    struct Graph* graph = createGraph(V, E);    //calling the function to allocate space to these many vertices and edges

    int i;
    for(i=0;i<E;i++){
        cout<<"\nEnter edge "<<i+1<<" properties Source, destination, weight respectively\n";
        cin>>graph->edge[i].source;
        cin>>graph->edge[i].destination;
        cin>>graph->edge[i].weight;
    }

    BellmanFord(graph, S);
	//passing created graph and source vertex to BellmanFord Algorithm function

    return 0;
}

Reference: Introduction to Algorithms by Thomas H. Cormen

Comment below if you have queries or found anything incorrect in above tutorial for Bellman-Ford Algorithm in C and C++.

The post Bellman-Ford Algorithm in C and C++ appeared first on The Crazy Programmer.

Dining Philosophers Problem in C and C++

$
0
0

In this tutorial you will learn about Dining Philosophers Problem in C and C++ with program example.

What is Dining Philosophers Problem?

There are some Philosophers whose work is just thinking and eating. Let there are 5 (for example) philosophers. They sat at a round table for dinner. To complete dinner each must need two Forks (spoons). But there are only 5 Forks available (Forks always equal to no. of Philosophers) on table. They take in such a manner that, first take left Fork and next right Fork. But problem is they try to take at same time. Since they are trying at same time, Fork 1, 2, 3, 4, 5 taken by Philosopher 1, 2, 3, 4, 5 respectively (since they are left side of each). And each one tries to ta ke right side Fork. But no one found available Fork. And also that each one thinks that someone will release the Fork and then I can eat. This continuous waiting leads to Dead Lock situation.

Dining Philosophers Problem

Also Read: Banker’s Algorithm in C

Dining Arrangement

Solution: To solve this Dead Lock situation, Last philosopher (any one can do this) first try to take right side fork and then left side fork. i.e in our example 5th person tries to take 4th Fork instead of 5th one. Since 4th Fork already taken by 4th the person, he gets nothing. But he left 5th Fork. Now the first person will take this 5th Fork and complete dinner and make 1st and 5th available for remaining people. Next 2nd person takes 1st fork and completes and releases 1st and 2nd. This continuous until all finishes dinner.

Operating System

In Operating System, this concept used in process synchronization. Same problem but instead of Philosophers processes are there and instead of Forks Resources are there. We follow above solution to avoid dead lock condition.

Program for Dining Philosophers Problem in C

#include<stdio.h>

#define n 4

int compltedPhilo = 0,i;

struct fork{
	int taken;
}ForkAvil[n];

struct philosp{
	int left;
	int right;
}Philostatus[n];

void goForDinner(int philID){ //same like threads concept here cases implemented
	if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
        printf("Philosopher %d completed his dinner\n",philID+1);
	//if already completed dinner
	else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
            //if just taken two forks
            printf("Philosopher %d completed his dinner\n",philID+1);

            Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10
            int otherFork = philID-1;

            if(otherFork== -1)
                otherFork=(n-1);

            ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
            printf("Philosopher %d released fork %d and fork %d\n",philID+1,philID+1,otherFork+1);
            compltedPhilo++;
        }
        else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork
                if(philID==(n-1)){
                    if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                        ForkAvil[philID].taken = Philostatus[philID].right = 1;
                        printf("Fork %d taken by philosopher %d\n",philID+1,philID+1);
                    }else{
                        printf("Philosopher %d is waiting for fork %d\n",philID+1,philID+1);
                    }
                }else{ //except last philosopher case
                    int dupphilID = philID;
                    philID-=1;

                    if(philID== -1)
                        philID=(n-1);

                    if(ForkAvil[philID].taken == 0){
                        ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
                        printf("Fork %d taken by Philosopher %d\n",philID+1,dupphilID+1);
                    }else{
                        printf("Philosopher %d is waiting for Fork %d\n",dupphilID+1,philID+1);
                    }
                }
            }
            else if(Philostatus[philID].left==0){ //nothing taken yet
                    if(philID==(n-1)){
                        if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                            ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
                            printf("Fork %d taken by philosopher %d\n",philID,philID+1);
                        }else{
                            printf("Philosopher %d is waiting for fork %d\n",philID+1,philID);
                        }
                    }else{ //except last philosopher case
                        if(ForkAvil[philID].taken == 0){
                            ForkAvil[philID].taken = Philostatus[philID].left = 1;
                            printf("Fork %d taken by Philosopher %d\n",philID+1,philID+1);
                        }else{
                            printf("Philosopher %d is waiting for Fork %d\n",philID+1,philID+1);
                        }
                    }
        }else{}
}

int main(){
	for(i=0;i<n;i++)
        ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;

	while(compltedPhilo<n){
		/* Observe here carefully, while loop will run until all philosophers complete dinner
		Actually problem of deadlock occur only thy try to take at same time
		This for loop will say that they are trying at same time. And remaining status will print by go for dinner function
		*/
		for(i=0;i<n;i++)
            goForDinner(i);
		printf("\nTill now num of philosophers completed dinner are %d\n\n",compltedPhilo);
	}

	return 0;
}

Output

Fork 1 taken by Philosopher 1
Fork 2 taken by Philosopher 2
Fork 3 taken by Philosopher 3
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 0

Fork 4 taken by Philosopher 1
Philosopher 2 is waiting for Fork 1
Philosopher 3 is waiting for Fork 2
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 0

Philosopher 1 completed his dinner
Philosopher 1 released fork 1 and fork 4
Fork 1 taken by Philosopher 2
Philosopher 3 is waiting for Fork 2
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 1

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 2 released fork 2 and fork 1
Fork 2 taken by Philosopher 3
Philosopher 4 is waiting for fork 3

Till now num of philosophers completed dinner are 2

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Philosopher 3 released fork 3 and fork 2
Fork 3 taken by philosopher 4

Till now num of philosophers completed dinner are 3

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Fork 4 taken by philosopher 4

Till now num of philosophers completed dinner are 3

Philosopher 1 completed his dinner
Philosopher 2 completed his dinner
Philosopher 3 completed his dinner
Philosopher 4 completed his dinner
Philosopher 4 released fork 4 and fork 3

Till now num of philosophers completed dinner are 4

Program for Dining Philosophers Problem in C++

#include<iostream>

#define n 4

using namespace std;

int compltedPhilo = 0,i;

struct fork{
	int taken;
}ForkAvil[n];

struct philosp{
	int left;
	int right;
}Philostatus[n];

void goForDinner(int philID){ //same like threads concept here cases implemented
	if(Philostatus[philID].left==10 && Philostatus[philID].right==10)
        cout<<"Philosopher "<<philID+1<<" completed his dinner\n";
	//if already completed dinner
	else if(Philostatus[philID].left==1 && Philostatus[philID].right==1){
            //if just taken two forks
            cout<<"Philosopher "<<philID+1<<" completed his dinner\n";

            Philostatus[philID].left = Philostatus[philID].right = 10; //remembering that he completed dinner by assigning value 10
            int otherFork = philID-1;

            if(otherFork== -1)
                otherFork=(n-1);

            ForkAvil[philID].taken = ForkAvil[otherFork].taken = 0; //releasing forks
            cout<<"Philosopher "<<philID+1<<" released fork "<<philID+1<<" and fork "<<otherFork+1<<"\n";
            compltedPhilo++;
        }
        else if(Philostatus[philID].left==1 && Philostatus[philID].right==0){ //left already taken, trying for right fork
                if(philID==(n-1)){
                    if(ForkAvil[philID].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                        ForkAvil[philID].taken = Philostatus[philID].right = 1;
                        cout<<"Fork "<<philID+1<<" taken by philosopher "<<philID+1<<"\n";
                    }else{
                        cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID+1<<"\n";
                    }
                }else{ //except last philosopher case
                    int dupphilID = philID;
                    philID-=1;

                    if(philID== -1)
                        philID=(n-1);

                    if(ForkAvil[philID].taken == 0){
                        ForkAvil[philID].taken = Philostatus[dupphilID].right = 1;
                        cout<<"Fork "<<philID+1<<" taken by Philosopher "<<dupphilID+1<<"\n";
                    }else{
                        cout<<"Philosopher "<<dupphilID+1<<" is waiting for Fork "<<philID+1<<"\n";
                    }
                }
            }
            else if(Philostatus[philID].left==0){ //nothing taken yet
                    if(philID==(n-1)){
                        if(ForkAvil[philID-1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION
                            ForkAvil[philID-1].taken = Philostatus[philID].left = 1;
                            cout<<"Fork "<<philID<<" taken by philosopher "<<philID+1<<"\n";
                        }else{
                            cout<<"Philosopher "<<philID+1<<" is waiting for fork "<<philID<<"\n";
                        }
                    }else{ //except last philosopher case
                        if(ForkAvil[philID].taken == 0){
                            ForkAvil[philID].taken = Philostatus[philID].left = 1;
                            cout<<"Fork "<<philID+1<<" taken by Philosopher "<<philID+1<<"\n";
                        }else{
                            cout<<"Philosopher "<<philID+1<<" is waiting for Fork "<<philID+1<<"\n";
                        }
                    }
        }else{}
}

int main(){
	for(i=0;i<n;i++)
        ForkAvil[i].taken=Philostatus[i].left=Philostatus[i].right=0;

	while(compltedPhilo<n){
		/* Observe here carefully, while loop will run until all philosophers complete dinner
		Actually problem of deadlock occur only thy try to take at same time
		This for loop will say that they are trying at same time. And remaining status will print by go for dinner function
		*/
		for(i=0;i<n;i++)
            goForDinner(i);
		cout<<"\nTill now num of philosophers completed dinner are "<<compltedPhilo<<"\n\n";
	}

	return 0;
}

Comment below if you have queries or found any information incorrect in above tutorial for dining philosophers problem in C and C++.

 

The post Dining Philosophers Problem in C and C++ appeared first on The Crazy Programmer.

Viewing all 56 articles
Browse latest View live