The post Asymptotic Notations appeared first on The Crazy Programmer.
]]>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 are mathematical tools to represent time complexity of algorithms for asymptotic analysis.
Most commonly used three asymptotic notations are:
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 = n_{0}.
Therefore we say f(n) = O(g(n)), in the condition that, f(n) <= c g(n), where n >= n_{0.}, c > 0, n_{0 }>= 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_{0 }>= 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 n^{2}, n^{3}.. also upper bound this function. But as per BigO definition, we are interested in tightest (closest) upper bound. That is the reason we write 3n+2 = O(n).
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 = n_{0}.
f(n) >= cg(n) , n >= n_{0}, c > 0, n_{0 }>= 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 n_{0 }>= 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.
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 >= n_{0}, n_{0} >= 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_{0 }>= 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 n_{0} >= 1.
So both the cases are valid for this.
This theta notation also called asymptotically equal.
Applications of These Notations in Algorithms
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(n^{2})
Cubic: O(n^{3})
Polynomial: n^{O(1)}
Exponential: 2^{O(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.
]]>The post Dining Philosophers Problem in C and C++ appeared first on The Crazy Programmer.
]]>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.
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.
#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 = philID1; if(otherFork== 1) otherFork=(n1); 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==(n1)){ 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=(n1); 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==(n1)){ if(ForkAvil[philID1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID1].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
#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 = philID1; if(otherFork== 1) otherFork=(n1); 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==(n1)){ 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=(n1); 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==(n1)){ if(ForkAvil[philID1].taken==0){ //KEY POINT OF THIS PROBLEM, THAT LAST PHILOSOPHER TRYING IN reverse DIRECTION ForkAvil[philID1].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.
]]>The post Priority Queue in C and C++ appeared first on The Crazy Programmer.
]]>Priority Queue is an ordered list of homogeneous elements. In normal queue, service is provided on the basis of FirstInFirstOut. In a priority queue service isn’t provided on the basis of FirstInFirstOut service, but rather then each element has a priority based on the urgency of the need.
An example of priority queue is a hospital waiting room. A patient having a more fatal problem would be admitted before other patients.
Other applications of priority queues are found in long term scheduling of jobs processed in a computer. In practice, short processes are given a priority over long processes as it improves the average response of the system.
Priority Queue can be implemented using a circular array.
As the service must be provided to an element having highest priority, there could be a choice between:
#include <stdio.h> #include <stdlib.h> #define MAX 30 typedef struct pqueue { int data[MAX]; int rear,front; }pqueue; void initialize(pqueue *p); int empty(pqueue *p); int full(pqueue *p); void enqueue(pqueue *p, int x); int dequeue(pqueue *p); void print(pqueue *p); void main() { int x,op,n,i; pqueue q; initialize(&q); do { printf("\n1)Create \n2)Insert \n3)Delete \n4)Print \n5)EXIT"); printf("\nEnter Choice: "); scanf("%d",&op); switch (op) { case 1: printf("\nEnter Number of Elements"); scanf("%d",&n ); initialize(&q); printf("Enter the data"); for(i=0; i<n; i++) { scanf("%d",&x); if(full(&q)) { printf("\nQueue is Full.."); exit(0); } enqueue(&q,x); } break; case 2: printf("\nEnter the element to be inserted"); scanf("%d\n",&x); if(full(&q)) { printf("\nQueue is Full"); exit(0); } enqueue(&q,x); break; case 3: if(empty(&q)) { printf("\nQueue is empty.."); exit(0); } x=dequeue(&q); printf("\nDeleted Element=%d",x); break; case 4: print(&q); break; default: break; } }while (op!=5); } void initialize(pqueue *p) { p>rear=1; p>front=1; } int empty(pqueue *p) { if(p>rear==1) return(1); return(0); } int full(pqueue *p) { if((p>rear+1)%MAX==p>front) return(1); return(0); } void enqueue(pqueue *p, int x) { int i; if(full(p)) printf("\nOverflow"); else { if(empty(p)) { p>rear=p>front=0; p>data[0]=x; } else { i=p>rear; while(x>p>data[i]) { p>data[(i+1)%MAX]=p>data[i]; i=(i1+MAX)%MAX; //anticlockwise movement inside the queue if((i+1)%MAX==p>front) break; } //insert x i=(i+1)%MAX; p>data[i]=x; //readjust rear p>rear=(p>rear+1)%MAX; } } } int dequeue(pqueue *p) { int x; if(empty(p)) { printf("\nUnderflow.."); } else { x=p>data[p>front]; if(p>rear==p>front) //delete the last element initialize(p); else p>front=(p>front +1)%MAX; } return(x); } void print(pqueue *p) { int i,x; if(empty(p)) { printf("\nQueue is empty.."); } else { i=p>front; while(i!=p>rear) { x=p>data[i]; printf("\n%d",x); i=(i+1)%MAX; } //prints the last element x=p>data[i]; printf("\n%d",x); } }
Output
1)Create
2)Insert
3)Delete
4)Print
5)EXIT
Enter Choice: 1
Enter Number of Elements4
Enter the data9
12
4
6
1)Create
2)Insert
3)Delete
4)Print
5)EXIT
Enter Choice: 4
12
9
6
4
1)Create
2)Insert
3)Delete
4)Print
5)EXIT
Enter Choice: 3
Deleted Element=12
1)Create
2)Insert
3)Delete
4)Print
5)EXIT
Enter Choice: 5
#include <iostream> #include <stdlib.h> #define MAX 30 using namespace std; typedef struct pqueue { int data[MAX]; int rear,front; }pqueue; void initialize(pqueue *p); int empty(pqueue *p); int full(pqueue *p); void enqueue(pqueue *p, int x); int dequeue(pqueue *p); void print(pqueue *p); int main() { int x,op,n,i; pqueue q; initialize(&q); do { cout<<"\n1)Create \n2)Insert \n3)Delete \n4)Print \n5)EXIT"; cout<<"\nEnter Choice: "; cin>>op; switch (op) { case 1: cout<<"\nEnter Number of Elements"; cin>>n; initialize(&q); cout<<"Enter the data"; for(i=0; i<n; i++) { cin>>x; if(full(&q)) { cout<<"\nQueue is Full.."; exit(0); } enqueue(&q,x); } break; case 2: cout<<"\nEnter the element to be inserted"; cin>>x; if(full(&q)) { cout<<"\nQueue is Full"; exit(0); } enqueue(&q,x); break; case 3: if(empty(&q)) { cout<<"\nQueue is empty.."; exit(0); } x=dequeue(&q); cout<<"\nDeleted Element="<<x; break; case 4: print(&q); break; default: break; } }while (op!=5); return 0; } void initialize(pqueue *p) { p>rear=1; p>front=1; } int empty(pqueue *p) { if(p>rear==1) return(1); return(0); } int full(pqueue *p) { if((p>rear+1)%MAX==p>front) return(1); return(0); } void enqueue(pqueue *p, int x) { int i; if(full(p)) cout<<"\nOverflow"; else { if(empty(p)) { p>rear=p>front=0; p>data[0]=x; } else { i=p>rear; while(x>p>data[i]) { p>data[(i+1)%MAX]=p>data[i]; i=(i1+MAX)%MAX; //anticlockwise movement inside the queue if((i+1)%MAX==p>front) break; } //insert x i=(i+1)%MAX; p>data[i]=x; //readjust rear p>rear=(p>rear+1)%MAX; } } } int dequeue(pqueue *p) { int x; if(empty(p)) { cout<<"\nUnderflow.."; } else { x=p>data[p>front]; if(p>rear==p>front) //delete the last element initialize(p); else p>front=(p>front +1)%MAX; } return(x); } void print(pqueue *p) { int i,x; if(empty(p)) { cout<<"\nQueue is empty.."; } else { i=p>front; while(i!=p>rear) { x=p>data[i]; cout<<"\n"<<x; i=(i+1)%MAX; } //prints the last element x=p>data[i]; cout<<"\n"<<x; } }
Comment below if you have queries or found any information incorrect in above tutorial for priority queue in C and C++.
The post Priority Queue in C and C++ appeared first on The Crazy Programmer.
]]>The post TCP/IP Socket Programming in C and C++ (Client Server Program) appeared first on The Crazy Programmer.
]]>We know that in Computer Networks, communication between server and client using TCP/IP protocol is connection oriented (which buffers and bandwidth are reserved for client). Server will get so many hits from different clients, and then server has to identify each client uniquely to reply every request. To achieve this we use “ip address of client (32 bit) + port number (16 bit) of the process”. This is called Socket (48 bit). Any network communication should goes through socket.
Let’s see how to create server and client using C programming. Below code will work in C++ also.
We now create a server which run continuously, and if any client hit the server with a request then server will send it’s date and time. To know the success message we here printing that time and date.
#include <stdio.h> // standard input and output library #include <stdlib.h> // this includes functions regarding memory allocation #include <string.h> // contains string functions #include <errno.h> //It defines macros for reporting and retrieving error conditions through error codes #include <time.h> //contains various functions for manipulating date and time #include <unistd.h> //contains various constants #include <sys/types.h> //contains a number of basic derived types that should be used whenever appropriate #include <arpa/inet.h> // defines in_addr structure #include <sys/socket.h> // for socket creation #include <netinet/in.h> //contains constants and structures needed for internet domain addresses int main() { time_t clock; char dataSending[1025]; // Actually this is called packet in Network Communication, which contain data and send through. int clintListn = 0, clintConnt = 0; struct sockaddr_in ipOfServer; clintListn = socket(AF_INET, SOCK_STREAM, 0); // creating socket memset(&ipOfServer, '0', sizeof(ipOfServer)); memset(dataSending, '0', sizeof(dataSending)); ipOfServer.sin_family = AF_INET; ipOfServer.sin_addr.s_addr = htonl(INADDR_ANY); ipOfServer.sin_port = htons(2017); // this is the port number of running server bind(clintListn, (struct sockaddr*)&ipOfServer , sizeof(ipOfServer)); listen(clintListn , 20); while(1) { printf("\n\nHi,Iam running server.Some Client hit me\n"); // whenever a request from client came. It will be processed here. clintConnt = accept(clintListn, (struct sockaddr*)NULL, NULL); clock = time(NULL); snprintf(dataSending, sizeof(dataSending), "%.24s\r\n", ctime(&clock)); // Printing successful message write(clintConnt, dataSending, strlen(dataSending)); close(clintConnt); sleep(1); } return 0; }
Explanation
1. socket() function creates a new socket inside kernel and returns an integer which used as socket descriptor.
2. For IP4 address we are sending first argument as AF_INET. You can also see we are assigning ipOfServer = AF_INET, represents that this argument related to Internet IP addresses.
3. SOCK_STREAM argument confirms that we are using TCP as a protocol in this communication, which is reliable communication.
4. Sending ‘0’ as third argument is, we are saying to kernel that use default protocol
5. Next we have to bind the created socket to structure ipOfServer. For this we are calling bind() functional. Which includes port, ip addresses as details.
6. listen() also an inbuilt function the 2nd argument 20 says that maximum 20 number of clients can connect to that server. So maximum 20 queue process can be handled by server.
7. Upto now server started. Next server waits for client request by accept() function.
8. accept() runs infinite loop to keep server always running. But it may eat up all CPU processing, to avoid that we have written sleep(1), which server went to sleep for 1 sec.
9. When server hit by client, it prints date and time on clients socket through descriptor returned by accept().
#include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <arpa/inet.h> int main() { int CreateSocket = 0,n = 0; char dataReceived[1024]; struct sockaddr_in ipOfServer; memset(dataReceived, '0' ,sizeof(dataReceived)); if((CreateSocket = socket(AF_INET, SOCK_STREAM, 0))< 0) { printf("Socket not created \n"); return 1; } ipOfServer.sin_family = AF_INET; ipOfServer.sin_port = htons(2017); ipOfServer.sin_addr.s_addr = inet_addr("127.0.0.1"); if(connect(CreateSocket, (struct sockaddr *)&ipOfServer, sizeof(ipOfServer))<0) { printf("Connection failed due to port and ip problems\n"); return 1; } while((n = read(CreateSocket, dataReceived, sizeof(dataReceived)1)) > 0) { dataReceived[n] = 0; if(fputs(dataReceived, stdout) == EOF) { printf("\nStandard output error"); } printf("\n"); } if( n < 0) { printf("Standard input error \n"); } return 0; }
Explanation
This code can connect to server and receive date and time from server.
1. Since this communication through socket, here also, we created socket.
2. Port number of the process and IP address both bundled in a structure. We connect these with socket
3. Once sockets are connected, the server sends the date and time to client socket through clients socket descriptor.
First run server.c file and create an output file for that in Unix or Linux.
Type gcc server.c o server command in terminal.
Now run the server using ./server
After running the server just minimize the terminal. Open new terminal. Do remaining work there.
To know the server is running or not we can check using netstat command.
After opening new terminal, type sudo netstat ntlp
Here we can see running server with port 2017
Now check with client by sending request with same port:
Type gcc client o client
Type ./client
After that you can see the date and time which is sent by server.
It means connection established successfully.
Whenever we run client program that means we are requesting the server, every time server will send date and time saying that connection established successfully.
Comment below if you have queries or found something incorrect in above tutorial for socket programming in C and C++.
The post TCP/IP Socket Programming in C and C++ (Client Server Program) appeared first on The Crazy Programmer.
]]>The post Hashing in C and C++ appeared first on The Crazy Programmer.
]]>Searching is dominant operation on any data structure. Most of the cases for inserting, deleting, updating all operations required searching first. So searching operation of particular data structure determines it’s time complexity. If we take any data structure the best time complexity for searching is O (log n) in AVL tree and sorted array only. Most of the cases it will take O (n) time. To solve this searching problem hashing concept introduced which will take O (1) time for searching. It’s constant time.
Earlier when this concept introduced programmers used to create “Direct address table”. Direct address table means, when we have “n” number of unique keys we create an array of length “n” and insert element “i” at ith index of the array. That array is called Hash Table. But due to this method even we have 10 elements of each range 1 lack, we should create table of size 1 lack for only 10 elements. Which is going to be waste of memory.
To avoid this problem we fix the size of hash table (array) and map our elements into that table using a function, called Hash function. This function decides where to put a given element into that table. If we want to search also first apply hash function decide whether the element present in hash table or not.
Example
We have numbers from 1 to 100 and hash table of size 10. Hash function is mod 10. That means number 23 will be mapped to (23 mod 10 = 3) 3rd index of hash table.
But problem is if elements (for example) 2, 12, 22, 32, elements need to be inserted then they try to insert at index 2 only. This problem is called Collision. To solve this collision problem we use different types of hash function techniques. Those are given below.
These also called collision resolution techniques.
In hash table instead of putting one element in index we maintain a linked list. When collision happened we place that element in corresponding linked list. Here some space is wasted because of pointers.
In case if we have collision we again calculate the hash value using corresponding hash function. But this time we do some minor modifications to that input. This process of searching for empty space to insert element in called Probing.
Probing hash function is: h (k, i)
here k is the key value which is to be inserted. And i is number of collision with that element.
Example: If we are inserting 2, we find its hash value using h (2, 0) because it’s first collision. Suppose the answer (index) to this function index already occupied we again need to apply h (2, 1) to hash function.
Linear Probing
Let hash function is h, hash table contains 0 to n1 slots.
Now we want to insert an element k. Apply h (k). If it results “x” and the index “x” already contain a value then we again apply hash function that h (k, 1) this equals to (h (k) + 1) mod n.
General form: h1 (k, j) = (h (k) + j) mod n
Example: Let hash table of size 5 which has function is mod 5 has already filled at positions 0, 2, 3.
Now new element 10 will try to insert. 10 mod 5 = 0. But index 0 already occupied. So it checks (probes) next (index 1) position. So 10 will insert at index 1.
Now element 11 will try to insert. 11 mod 5 = 1. But index 1 already occupied, check index 2 it also occupied (data given), 3 also occupied. So it will insert at index 4 which is empty.
We can observe that it linearly checking for next empty position. So it’s called linear probing.
Problems with linear probing:
Quadratic Probing
It is same as linear probing. But when collision occurs we use different function. If collision happened that element try to occupy at quadratic distance instead of linear distance.
Due to this “Primary clustering” will be reduced. But secondary clustering won’t be eliminated.
Double Hashing
Here we use two hash functions.
h1 (k) = (h1 (k) + i h2 (k)) mod n. Here h1 and h2 are two hash functions.
Here the next prob position will depend on two functions h1 and h2 also.
Advantages by this method are there is no chance of primary clustering. And also Secondary clustering also eliminated.
Chaining  Open Addressing 
Elements can be stored at outside of the table  In open addressing elements should be stored inside the table only 
In chaining at any time the number of elements in the hash table may greater than the size of the hash table  In open addressing the number of elements present in the hash table will not exceed to number of indices in hash table. 
In case of deletion chaining is the best method  If deletion is not required. Only inserting and searching is required open addressing is better 
Chaining requires more space  Open addressing requires less space than chaining. 
Below is the implementation of hashing or hash table in C.
#include<stdio.h> #include<limits.h> /* This is code for linear probing in open addressing. If you want to do quadratic probing and double hashing which are also open addressing methods in this code when I used hash function that (pos+1)%hFn in that place just replace with another function. */ void insert(int ary[],int hFn, int size){ int element,pos,n=0; printf("Enter key element to insert\n"); scanf("%d",&element); pos = element%hFn; while(ary[pos]!= INT_MIN) { // INT_MIN and INT_MAX indicates that cell is empty. So if cell is empty loop will break and goto bottom of the loop to insert element if(ary[pos]== INT_MAX) break; pos = (pos+1)%hFn; n++; if(n==size) break; // If table is full we should break, if not check this, loop will go to infinite loop. } if(n==size) printf("Hash table was full of elements\nNo Place to insert this element\n\n"); else ary[pos] = element; //Inserting element } void delete(int ary[],int hFn,int size){ /* very careful observation required while deleting. To understand code of this delete function see the note at end of the program */ int element,n=0,pos; printf("Enter element to delete\n"); scanf("%d",&element); pos = element%hFn; while(n++ != size){ if(ary[pos]==INT_MIN){ printf("Element not found in hash table\n"); break; } else if(ary[pos]==element){ ary[pos]=INT_MAX; printf("Element deleted\n\n"); break; } else{ pos = (pos+1) % hFn; } } if(n==size) printf("Element not found in hash table\n"); } void search(int ary[],int hFn,int size){ int element,pos,n=0; printf("Enter element you want to search\n"); scanf("%d",&element); pos = element%hFn; while(n++ != size){ if(ary[pos]==element){ printf("Element found at index %d\n",pos); break; } else if(ary[pos]==INT_MAX ary[pos]!=INT_MIN) pos = (pos+1) %hFn; } if(n==size) printf("Element not found in hash table\n"); } void display(int ary[],int size){ int i; printf("Index\tValue\n"); for(i=0;i<size;i++) printf("%d\t%d\n",i,ary[i]); } int main(){ int size,hFn,i,choice; printf("Enter size of hash table\n"); scanf("%d",&size); int ary[size]; printf("Enter hash function [if mod 10 enter 10]\n"); scanf("%d",&hFn); for(i=0;i<size;i++) ary[i]=INT_MIN; //Assigning INT_MIN indicates that cell is empty do{ printf("Enter your choice\n"); printf(" 1> Insert\n 2> Delete\n 3> Display\n 4> Searching\n 0> Exit\n"); scanf("%d",&choice); switch(choice){ case 1: insert(ary,hFn,size); break; case 2: delete(ary,hFn,size); break; case 3: display(ary,size); break; case 4: search(ary,hFn,size); break; default: printf("Enter correct choice\n"); break; } }while(choice); return 0; } /* Note: Explanation for delete function and search function suppose hash table contains elements 22, 32, 42 at index positions 2, 3, 4. Now delete(22) applied. As per hash function defined we first check for index 2. Found, so deleted. And make that index to nill. Next apply delete(32). This time also it first check at index 2, but found that its nothing.Then we stop and say element 32 not found in hash table. But it's present at index 3. But how should we know whether to check to other index or not? For this when we delete any element we flag that with INT_MAX which indicates that in that position previously some element is there now it's deleted. So don't stop here your required element may present at next index. */
Output
Enter size of hash table
10
Enter hash function [if mod 10 enter 10]
10
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
1
Enter key element to insert
12
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
1
Enter key element to insert
22
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
1
Enter key element to insert
32
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
3
Index Value
0 2147483648
1 2147483648
2 12
3 22
4 32
5 2147483648
6 2147483648
7 2147483648
8 2147483648
9 2147483648
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
2
Enter element to delete
12
Element deleted
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
4
Enter element you want to search
32
Element found at index 4
Enter your choice
1> Insert
2> Delete
3>Display
4>Searching
0>Exit
0
Below is the implementation of hashing or hash table in C++.
#include<iostream> #include<limits.h> using namespace std; /* This is code for linear probing in open addressing. If you want to do quadratic probing and double hashing which are also open addressing methods in this code when I used hash function that (pos+1)%hFn in that place just replace with another function. */ void Insert(int ary[],int hFn, int Size){ int element,pos,n=0; cout<<"Enter key element to insert\n"; cin>>element; pos = element%hFn; while(ary[pos]!= INT_MIN) { // INT_MIN and INT_MAX indicates that cell is empty. So if cell is empty loop will break and goto bottom of the loop to insert element if(ary[pos]== INT_MAX) break; pos = (pos+1)%hFn; n++; if(n==Size) break; // If table is full we should break, if not check this, loop will go to infinite loop. } if(n==Size) cout<<"Hash table was full of elements\nNo Place to insert this element\n\n"; else ary[pos] = element; //Inserting element } void Delete(int ary[],int hFn,int Size){ /* very careful observation required while deleting. To understand code of this delete function see the note at end of the program */ int element,n=0,pos; cout<<"Enter element to delete\n"; cin>>element; pos = element%hFn; while(n++ != Size){ if(ary[pos]==INT_MIN){ cout<<"Element not found in hash table\n"; break; } else if(ary[pos]==element){ ary[pos]=INT_MAX; cout<<"Element deleted\n\n"; break; } else{ pos = (pos+1) % hFn; } } if(n==Size) cout<<"Element not found in hash table\n"; } void Search(int ary[],int hFn,int Size){ int element,pos,n=0; cout<<"Enter element you want to search\n"; cin>>element; pos = element%hFn; while(n++ != Size){ if(ary[pos]==element){ cout<<"Element found at index "<<pos<<"\n"; break; } else if(ary[pos]==INT_MAX ary[pos]!=INT_MIN) pos = (pos+1) %hFn; } if(n==Size) cout<<"Element not found in hash table\n"; } void display(int ary[],int Size){ int i; cout<<"Index\tValue\n"; for(i=0;i<Size;i++) cout<<i<<"\t"<<ary[i]<<"\n"; } int main(){ int Size,hFn,i,choice; cout<<"Enter size of hash table\n"; cin>>Size; int ary[Size]; cout<<"Enter hash function [if mod 10 enter 10]\n"; cin>>hFn; for(i=0;i<Size;i++) ary[i]=INT_MIN; //Assigning INT_MIN indicates that cell is empty do{ cout<<"Enter your choice\n"; cout<<" 1> Insert\n 2> Delete\n 3> Display\n 4> Searching\n 0> Exit\n"; cin>>choice; switch(choice){ case 1: Insert(ary,hFn,Size); break; case 2: Delete(ary,hFn,Size); break; case 3: display(ary,Size); break; case 4: Search(ary,hFn,Size); break; default: cout<<"Enter correct choice\n"; break; } }while(choice); return 0; } /* Note: Explanation for delete function and search function suppose hash table contains elements 22, 32, 42 at index positions 2, 3, 4. Now delete(22) applied. As per hash function defined we first check for index 2. Found, so deleted. And make that index to nill. Next apply delete(32). This time also it first check at index 2, but found that its nothing.Then we stop and say element 32 not found in hash table. But it's present at index 3. But how should we know whether to check to other index or not? For this when we delete any element we flag that with INT_MAX which indicates that in that position previously some element is there now it's deleted. So don't stop here your required element may present at next index. */
Comment below if have queries or found anything incorrect in above tutorial for Hashing in C and C++.
The post Hashing in C and C++ appeared first on The Crazy Programmer.
]]>The post Difference between BFS and DFS appeared first on The Crazy Programmer.
]]>Breadth First Search (BFS) and Depth First Search (DFS) are two popular algorithms to search an element in Graph or to find whether a node can be reachable from root node in Graph or not. And these are popular traversing methods also.
When we apply these algorithms on a Graph, we can see following types of nodes.
S. No.  Breadth First Search (BFS)  Depth First Search (DFS) 
1.  BFS visit nodes level by level in Graph.  DFS visit nodes of graph depth wise. It visits nodes until reach a leaf or a node which doesn’t have nonvisited nodes. 
2.  A node is fully explored before any other can begin.  Exploration of a node is suspended as soon as another unexplored is found. 
3.  Uses Queue data structure to store Unexplored nodes.  Uses Stack data structure to store Unexplored nodes. 
4.  BFS is slower and require more memory.  DFS is faster and require less memory. 
5.  Some Applications:

Some Applications:

Example
Considering A as starting vertex.
Note: There are many sequences possible for BFS and DFS. Using permutations we can find how many are there.
Comment below if you found any information incorrect or missing in above tutorial for difference between dfs and bfs.
The post Difference between BFS and DFS appeared first on The Crazy Programmer.
]]>The post BellmanFord Algorithm in C and C++ appeared first on The Crazy Programmer.
]]>Dijkstra and BellmanFord 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 BellmanFord 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.
BellmanFord Algorithm will work on logic that, if graph has n nodes, then shortest path never contain more than n1 edges. This is exactly what BellmanFord do. It is enough to relax each edge (v1) 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).
BellmanFord (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 (v1) 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 (n1)th level, we can say that graph is having negative edge cycle and detected. Return False return true }
Finally time complexity is (v1) (E) O(1) = O(VE)
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 “n1”.
Iteration 1: edge (s,t) and (z,y) relaxed and updating the distances to t and y.
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.
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)
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)
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.
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 “v1” 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 "V1" edges. So we do here "V1" relaxations for (i = 1; i <= V1; 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
#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 "V1" edges. So we do here "V1" relaxations for (i = 1; i <= V1; 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 BellmanFord Algorithm in C and C++.
The post BellmanFord Algorithm in C and C++ appeared first on The Crazy Programmer.
]]>The post Topological Sort in C and C++ appeared first on The Crazy Programmer.
]]>We know many sorting algorithms used to sort the given data. It may be numeric data or strings. Take a situation that our data items have relation. They are related with some condition that one should happen only after other one happened.
For example shoe should wear after socks only. Another example, in academic course one should study Applications of Algorithms subject only after studying Designing of Algorithms. And Designing of Algorithms should study only after learning any programming language. We can observe that a work requires prerequisite. In these situations we represent our data in a graph and we use directed edges from prerequisite to next one. And we apply Topological sorting to solve.
Most important condition to do Topological sorting on any graph is that Graph should be Connected Directed Acyclic graph. It is not possible to apply Topological sorting either graph is not directed or it have a Cycle.
One more condition is that graph should contain a sink vertex. The vertex which doesn’t have any outgoing edge is called sink vertex. Idea behind this sink vertex is that if every vertex has an outgoing edge in a directed graph it definitely forms a cycle, which violates the condition.
Note: Topological sorting on a graph results nonunique solution
Solving Using Indegree Method
Step 1: Write indegree of all vertices:
Vertex  indegree 
1  0 
2  1 
3  1 
4  2 
Step 2: Write the vertex which has indegree 0 (zero) in solution. Here vertex 1 has indegree 0. So,
Solution is: 1 > (not yet completed )
Decrease indegree count of vertices who are adjacent to the vertex which recently added to the solution.
Here vertex 1 is recently added to the solution. Vertices 2 and 3 are adjacent to vertex 1. So decrease the indegree count of those and update.
Updated result is:
Vertex  indegree 
1  Already added to solution 
2  0 
3  0 
4  2 
Again repeat the same thing which we have done in step1 that, write the vertices which have degree 0 in solution.
Here we can observe that two vertices (2 and 3) have indegree 0 (zero). Add any vertex into the solution.
Note that, you may add vertex 2 into solution, and I may add vertex 3 to solution. That means the solution to topological sorting is not unique.
Now add vertex 3.
Solution is: 1>3>
Again decrease the indegree count of vertices which are adjacent to vertex 3.
Updated result is:
Vertex  indegree 
1  Already added to solution 
2  0 
3  Already added to solution 
4  1 
Now add vertex 2 to solution because it only has indegree 0.
Solution is: 1>3>2>
Updated result is:
Vertex  indegree 
1  Already added to solution 
2  Already added to solution 
3  Already added to solution 
4  0 
Finally add 4 to solution.
Final solution is: 1>3>2>4
#include <stdio.h> int main(){ int i,j,k,n,a[10][10],indeg[10],flag[10],count=0; printf("Enter the no of vertices:\n"); scanf("%d",&n); printf("Enter the adjacency matrix:\n"); for(i=0;i<n;i++){ printf("Enter row %d\n",i+1); for(j=0;j<n;j++) scanf("%d",&a[i][j]); } for(i=0;i<n;i++){ indeg[i]=0; flag[i]=0; } for(i=0;i<n;i++) for(j=0;j<n;j++) indeg[i]=indeg[i]+a[j][i]; printf("\nThe topological order is:"); while(count<n){ for(k=0;k<n;k++){ if((indeg[k]==0) && (flag[k]==0)){ printf("%d ",(k+1)); flag [k]=1; } for(i=0;i<n;i++){ if(a[i][k]==1) indeg[k]; } } count++; } return 0; }
Output
Enter the no of vertices:
4
Enter the adjacency matrix:
Enter row 1
0 1 1 0
Enter row 2
0 0 0 1
Enter row 3
0 0 0 1
Enter row 4
0 0 0 0
The topological order is:1 2 3 4
#include<iostream> using namespace std; int main(){ int i,j,k,n,a[10][10],indeg[10],flag[10],count=0; cout<<"Enter the no of vertices:\n"; cin>>n; cout<<"Enter the adjacency matrix:\n"; for(i=0;i<n;i++){ cout<<"Enter row "<<i+1<<"\n"; for(j=0;j<n;j++) cin>>a[i][j]; } for(i=0;i<n;i++){ indeg[i]=0; flag[i]=0; } for(i=0;i<n;i++) for(j=0;j<n;j++) indeg[i]=indeg[i]+a[j][i]; cout<<"\nThe topological order is:"; while(count<n){ for(k=0;k<n;k++){ if((indeg[k]==0) && (flag[k]==0)){ cout<<k+1<<" "; flag[k]=1; } for(i=0;i<n;i++){ if(a[i][k]==1) indeg[k]; } } count++; } return 0; }
Comment below if you have any queries related to above program for topological sort in C and C++.
The post Topological Sort in C and C++ appeared first on The Crazy Programmer.
]]>The post Matrix Chain Multiplication in C and C++ appeared first on The Crazy Programmer.
]]>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.
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
Let we have “n” number of matrices A1, A2, A3 ……… An and dimensions are d0 x d1, d1 x d2, d2 x d3 …………. d_{n1} x d_{n } (i.e Dimension of Matrix A_{i} is d_{i1} x d_{i}
Solving a chain of matrix that, A_{i} A_{i+1 } A_{i+2 } A_{i+3 }……. A_{j }= (A_{i} A_{i+1 } A_{i+2 } A_{i+3 }……. A_{k }) (A_{k+1 }A_{k+2 }……. A_{j }) + d_{i1} d_{k} d_{j} 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 d_{i1} d_{k} d_{j }(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 ] + d_{i1} d_{k} d_{j} } 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 = n^{2} cells we need calculate = O (n^{2})
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 (n^{2}) * O (n) = O (n^{3}) is time complexity.
Space Complexity
We are creating a table of n x n so space complexity is O (n^{2}).
// This code implemented using Algorithm in Coremen book #include<stdio.h> #include<limits.h> // Matrix Ai has dimension p[i1] 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<nL+1; i++) { j = i+L1; m[i][j] = INT_MAX; //assigning to maximum value for (k=i; k<=j1; k++) { q = m[i][k] + m[k+1][j] + p[i1]*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][n1]; //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
// This code implemented using Algorithm in Coremen book #include<iostream> #include<limits.h> using namespace std; // Matrix Ai has dimension p[i1] 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<nL+1; i++) { j = i+L1; m[i][j] = INT_MAX; //assigning to maximum value for (k=i; k<=j1; k++) { q = m[i][k] + m[k+1][j] + p[i1]*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][n1]; //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.
]]>The post Travelling Salesman Problem in C and C++ appeared first on The Crazy Programmer.
]]>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 (n^{n}) time, because we have to check (n1)! 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 subproblems. Let’s check that.
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 nonvisited vertices (villages) becomes a new problem. Here we can observe that main problem spitted into subproblem, this is property of dynamic programming.
Note: While calculating below right side values calculated in bottomup 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.
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 nonvisited 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 , {Sj}))
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.
Since we are solving this using Dynamic Programming, we know that Dynamic Programming approach contains subproblems.
Here after reaching i^{th} node finding remaining minimum distance to that i^{th} node is a subproblem.
If we solve recursive equation we will get total (n1) 2^{(n2) }subproblems, which is O (n2^{n}).
Each subproblem will take O (n) time (finding path to remaining (n1) nodes).
Therefore total time complexity is O (n2^{n}) * O (n) = O (n^{2}2^{n})
Space complexity is also number of subproblems which is O (n2^{n})
#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
#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.
]]>