one_D_bit_array.h
one_D_bit_array.c
two_D_bit_array.h
two_D_bit_array.c
Graph_AdjacencyMatrix.h
Graph_AdjacencyMatrix.c
main.c
Makefile
SampleTestData.txt
int get_one_D_bit_array(int ,int *); void reset_one_D_bit_array(int ,int *); void set_one_D_bit_array(int ,int *);
one_D_bit_array.c
#include"one_D_bit_array.h" int get_one_D_bit_array(int i,int* arr) { if((arr[i/32]&((unsigned int)1<<(31-i%32)))!=0) return 1; return 0; } void set_one_D_bit_array(int i,int *arr) { arr[i/32]|=((unsigned int)1<<(31-i%32)); // to set its 31-(n%32) th bit. } void reset_one_D_bit_array(int i,int *arr) { arr[i/32]&=(~((unsigned int)1<<(31-i%32))); // to reset its 31-(n%32) th bit. }
two_D_bit_array.h
int get_two_D_bit_array(int ,int ,int *,int); void set_two_D_bit_array(int ,int ,int *,int); void reset_two_D_bit_array(int ,int ,int *,int);
two_D_bit_array.c
#include"two_D_bit_array.h" /* this function will return bit value in ith row and jth column from the array 'arr' which provides an abstraction of 2-D bit array of size n * n. */ int get_two_D_bit_array(int i,int j,int* arr,int n) { int bitNumber=i*n+j; if((arr[bitNumber/32]&((unsigned int)1<<(31-bitNumber%32)))!=0) return 1; return 0; } /* this function will set the bit value in ith row and jth column in the array 'arr' which provides an abstraction of 2-D bit array of size n * n to 1. */ void set_two_D_bit_array(int i,int j,int *arr,int n) { int bitNumber=i*n+j; arr[bitNumber/32]|=((unsigned int)1<<(31-bitNumber%32)); // to set its 31-(bitNumber%32) th bit. } /* this function will set the bit value in ith row and jth column in the array 'arr' which provides an abstraction of 2-D bit array of size n * n to 0. */ void reset_two_D_bit_array(int i,int j,int *arr,int n) { int bitNumber=i*n+j; arr[bitNumber/32]&=(~((unsigned int)1<<(31-bitNumber%32))); // to reset its 31-(bitNumber%32) th bit. }
Graph_AdjacencyMatrix.h
struct Graph { int numberOfVertices,numberOfEdges; unsigned int*adjacencyMatrix; }; struct Graph*makeNewGraph(); void initializeAdjacencyMatrix(struct Graph*); void createEdge(struct Graph*,int,int); void removeEdge(struct Graph*,int,int); void showAdjacencyMatrix(struct Graph*); int findNumberOfComponents(struct Graph*);
Graph_AdjacencyMatrix.c
#include<stdio.h> #include<stdlib.h> #include"Graph_AdjacencyMatrix.h" #include"two_D_bit_array.h" #include"one_D_bit_array.h" struct Graph*makeNewGraph() { struct Graph*g; g=(struct Graph*)malloc(sizeof(struct Graph)); return g; } void initializeAdjacencyMatrix(struct Graph*g) { /* The adjacencyMatrix corresponding to vertex u and v will contain 1 if there is an edge from u to v otherwise it will contain 0 Description of data structure used for making adjacencyMatrix: * We will need n*n bits to represent the existence of an edge between two vertices * These n*n bits should be assumed to be arranged in the linear fashion * For implementing this linear fashion we will use an array of integers. * For a standard 32 bit compiler (like gcc 4.8.2) size of an integer is 32 bits (4 bytes). * By this linear arrangement of AdjacencyMatrix we will optimally exploit every single bit. */ int sizeOfIntegerColumns,i,j; sizeOfIntegerColumns=((g->numberOfVertices)*(g->numberOfVertices))/32+1; (g->adjacencyMatrix)=(unsigned int*)malloc(sizeof(unsigned int)*sizeOfIntegerColumns); for(i=0;i<sizeOfIntegerColumns;i++) (g->adjacencyMatrix)[i]=0; } void createEdge(struct Graph*g,int a,int b) { set_two_D_bit_array(a,b,g->adjacencyMatrix,g->numberOfVertices); } void removeEdge(struct Graph*g,int a,int b) { reset_two_D_bit_array(a,b,g->adjacencyMatrix,g->numberOfVertices); } void showAdjacencyMatrix(struct Graph*g) { int i,j,bitNumber; printf("The adjacency Matrix of the Graph is as follows : \n"); for(i=0;i<(g->numberOfVertices);i++) { for(j=0;j<(g->numberOfVertices);j++) printf("%d",get_two_D_bit_array(i,j,g->adjacencyMatrix,g->numberOfVertices)); printf("\n"); } } int findNumberOfComponents(struct Graph*g) { /* first of all we need to create a copy of the AdjacencyMatrix. */ unsigned int *adjacencyMatrix_copy,*flag,sizeOfIntegerColumns,i,j,k,components; sizeOfIntegerColumns=((g->numberOfVertices)*(g->numberOfVertices))/32+1; adjacencyMatrix_copy=(unsigned int*)malloc(sizeof(unsigned int)*sizeOfIntegerColumns); for(i=0;i<sizeOfIntegerColumns;i++) adjacencyMatrix_copy[i]=(g->adjacencyMatrix)[i]; /* copy of adjacencyMatrix created */ /* now we need to keep the track of vertices being merged for this we need to introduce a one-D bit array that will keep track of this information. let this one-D bit array be flag. */ flag=(unsigned int *)malloc(sizeof(unsigned int)*(g->numberOfVertices)/32+1); for(i=0;i<(g->numberOfVertices)/32+1;i++) flag[i]=0; /* if the nth bit of flag array is 0 this means that the vertex with vertexNumber 'n' is still alive and is not merged with any other vertex. if the nth bit of flag array is 1 this means that the vertex with vertexNumber 'n' is dead and is merged with some other vertex and has no existence now. */ /* now we are ready for merging vertices in our dummy (copied) adjacencyMatrix. */ for(i=0;i<(g->numberOfVertices);i++) { if(get_one_D_bit_array(i,flag)==0) // means ith vertex is alive { for(j=0;j<(g->numberOfVertices);j++) { if(j!=i && get_one_D_bit_array(j,flag)==0) // means the jth vertex is alive { if(get_two_D_bit_array(i,j,adjacencyMatrix_copy,g->numberOfVertices)==1) { /* now we need to merge the ith node with the jth node for this we need to merge ith row with jth row, and ith col with jth col */ for(k=0;k<(g->numberOfVertices);k++) // merging the ith and jth rows { if(get_two_D_bit_array(i,k,adjacencyMatrix_copy,g->numberOfVertices) | get_two_D_bit_array(j,k,adjacencyMatrix_copy,g->numberOfVertices)) set_two_D_bit_array(i,k,adjacencyMatrix_copy,g->numberOfVertices); } for(k=0;k<(g->numberOfVertices);k++) // merging the ith and jth cols { if(get_two_D_bit_array(k,i,adjacencyMatrix_copy,g->numberOfVertices) | get_two_D_bit_array(k,j,adjacencyMatrix_copy,g->numberOfVertices)) set_two_D_bit_array(k,i,adjacencyMatrix_copy,g->numberOfVertices); } /* now the jth vertex is merged with ith vertex so the ith vertex should have no existence */ /* so we need to set the jth bit of flag array to 1 */ set_one_D_bit_array(j,flag); // declaring that the jth vertex is now dead. } } } } } /* now the total number of components in the graph will be the number of vertices that still have zero correponding to their vertex number in flag array. */ components=0; for(i=0;i<(g->numberOfVertices);i++) if(get_one_D_bit_array(i,flag)==0) components++; return components; }
main.c
#include<stdio.h> #include"Graph_AdjacencyMatrix.h" int main() { int i,n,a,b; struct Graph*g; g=makeNewGraph(); printf("Enter the number of Vertices in the Graph : "); scanf("%d",&(g->numberOfVertices)); printf("Enter the number of Edges in the Graph : "); scanf("%d",&(g->numberOfEdges)); initializeAdjacencyMatrix(g); printf("NOTE : The ordering of the vertices is zero indexed.\n"); for(i=0;i<(g->numberOfEdges);i++) { printf("Enter the edge Number %d : ",i+1); scanf("%d%d",&a,&b); createEdge(g,a,b); } showAdjacencyMatrix(g); printf("Number of components in the Graph = %d\n",findNumberOfComponents(g)); printf("\nProgram execution successful...\n"); return 0; }
Makefile
all: hello hello: one_D_bit_array.o two_D_bit_array.o Graph_AdjacencyMatrix.o main.o gcc one_D_bit_array.o two_D_bit_array.o Graph_AdjacencyMatrix.o main.o -o hello one_D_bit_array.o: one_D_bit_array.c gcc -c one_D_bit_array.c two_D_bit_array.o: two_D_bit_array.c gcc -c two_D_bit_array.c main.o: main.c gcc -c main.c graph.o: Graph_AdjacencyMatrix.c gcc -c Graph_AdjacencyMatrix.c clean: rm -rf *~ *.o hello
SampleTestData.txt
4 8 0 2 2 0 1 3 3 1 0 3 3 0 3 2 2 3
No comments:
Post a Comment