C Everything
This is a C repository containing a curated set of generic data structures and algorithm.
graph.c
Go to the documentation of this file.
1 
6 #include "graph.h"
7 #include "link_list.h"
8 #include "queue.h"
9 #include "stack.h"
10 #include "heap.h"
11 #include "disjoint_set.h"
12 #include "array.h"
13 
14 // function Declarations
17 int graph_len(t_gen);
25 t_gen graph_add_wedge(t_gen d, t_gen n1, t_gen n2, int weight);
26 t_gen graph_add_wedge_sym(t_gen d, t_gen n1, t_gen n2, int weight);
30 void graph_neigh_print(t_gen d, t_gen neigh);
31 void graph_print(t_gen d);
32 void graph_wprint(t_gen d);
33 void graph_destroy(t_gen d);
34 
42 t_gen create_graph(char *name, int size, t_dparams *prm)
43 {
44  t_graph *g = get_mem(1, sizeof(t_graph));
45 
46  // Initailze graph Params
47  g->name = name;
48  g->count = 0;
49  g->total_edges = 0;
50  g->max_size = size;
51  g->nodes = get_mem(size, sizeof(t_gnode));
52 
53  // Initailze graph routines
63  g->bfs = graph_bfs;
64  g->dfs = graph_dfs;
66  g->find = graph_find;
67  g->len = graph_len;
68  g->print = graph_print;
69  g->wprint = graph_wprint;
71 
72  // Initailze data type based operations req for prop working of graph
73  g->cmpr = prm->cmpr;
74  g->swap = prm->swap;
75  g->free = prm->free;
76  g->print_data = prm->print_data;
77 
78  return (t_gen)g;
79 }
80 
81 
88 {
89  return ((t_graph*)g)->count;
90 }
91 
99 {
100  t_graph *g = (t_graph*)d;
101  int i;
102 
103  for (i = 0; i < g->count; i++) {
104  if (g->cmpr(g->nodes[i].id, data) == eEQUAL) {
105  return &g->nodes[i];
106  }
107  }
108 
109  return NULL;
110 }
111 
119 {
120  t_gedge *neighl = (t_gedge*) x;
121  t_gnode *node = (t_gnode*) y;
122 
123  if (neighl->node == node) {
124  return eEQUAL;
125  }
126 
127  return eLESS;
128 }
129 
137 void graph_neigh_list_free(t_gen mem, char *file, int line)
138 {
139  t_gedge *neighl = (t_gedge*) mem;
140 
141  neighl->node = NULL;
142 
143  free_mem(neighl);
144 
145 }
146 
154 {
155  t_graph *g = (t_graph*)d;
156  t_gnode *node;
157  t_dparams dp;
158 
159  // existing node return
160  node = g->find(g, data);
161  if (node != NULL) {
162  //LOG_WARN("GRAPH", "%s: node already present\n",g->name);
163  return node;
164  }
165 
166  // Graph size full
167  if (g->count >= g->max_size) {
168  //LOG_WARN("GRAPH", "%s: No space left to add node in graph\n",g->name);
169  return NULL;
170  }
171 
172  // add node to graph
173  node = &g->nodes[g->count];
174  node->idx = g->count;
175  g->count++;
176 
177  // create link list to store node neighbors
178  node->id = data;
179  init_data_params(&dp, eUSER);
182 // node->neigh = create_link_list("neighNodes", eDOUBLE_LINKLIST, &dp);
183  node->neigh = create_link_list("neighNodes", eXOR_LINKLIST, &dp);
184 
185  return node;
186 }
187 
196 {
197  t_graph *g = (t_graph*)d;
198  t_gnode *A, *B;
199 
200  A = g->find(g, n1);
201  B = g->find(g, n2);
202 
203  // Nodes not present
204  if (A == NULL || B == NULL) {
205  return NULL;
206  }
207 
208  // return if B present A's neigh list
209  return A->neigh->find(A->neigh, B);
210 }
211 
220 {
221  t_graph *g = (t_graph*)d;
222  t_gnode *A, *B;
223  t_gedge *edge;
224 
225  // ADD Node if node doesn't exit else get node
226  A = g->add_vertex(g, n1);
227  B = g->add_vertex(g, n2);
228 
229  // Return if Graph FULL
230  if (A == NULL || B == NULL) {
231  return NULL;
232  }
233 
234  // Return Link already exists
235  if (g->has_edge(g, n1, n2) != NULL) {
236  return NULL;
237  }
238 
239  g->total_edges++;
240 
241  edge = get_mem(1, sizeof(t_gedge));
242  edge->node = B;
243  edge->weight = 0;
244 
245  // link N1->N2
246  A->neigh->append(A->neigh, edge);
247 
248  return A;
249 }
250 
259 t_gen graph_add_wedge(t_gen d, t_gen n1, t_gen n2, int weight)
260 {
261  t_graph *g = (t_graph*)d;
262  t_gnode *A, *B;
263  t_gedge *edge;
264 
265  // ADD Node if node doesn't exit else get node
266  A = g->add_vertex(g, n1);
267  B = g->add_vertex(g, n2);
268 
269  // Return if Graph FULL
270  if (A == NULL || B == NULL) {
271  return NULL;
272  }
273 
274  // Return Link already exists
275  if (g->has_edge(g, n1, n2) != NULL) {
276  return NULL;
277  }
278 
279  g->total_edges++;
280 
281  edge = get_mem(1, sizeof(t_gedge));
282  edge->node = B;
283  edge->weight = weight;
284 
285  // link N1->N2
286  A->neigh->append(A->neigh, edge);
287 
288  return A;
289 }
290 
299 {
300  t_graph *g = (t_graph*)d;
301  t_gnode *A, *B;
302 
303  A = g->find(g, n1);
304  B = g->find(g, n2);
305 
306  // Nodes not present
307  if (A == NULL || B == NULL) {
308  return NULL;
309  }
310 
311  // unlink N1->N2
312  d = A->neigh->del(A->neigh, B);
313  free_mem(d);
314  return A;
315 }
316 
325 {
326  t_graph *g = (t_graph*)d;
327  t_gen ret;
328 
329  // link N1->N2
330  ret = g->add_edge(g, n1, n2);
331  // link N2->N1
332  ret = g->add_edge(g, n2, n1);
333 
334  return ret;
335 }
336 
345 t_gen graph_add_wedge_sym(t_gen d, t_gen n1, t_gen n2, int weight)
346 {
347  t_graph *g = (t_graph*)d;
348  t_gen ret;
349 
350  // link N1->N2
351  ret = g->add_wedge(g, n1, n2, weight);
352  // link N2->N1
353  ret = g->add_wedge(g, n2, n1, weight);
354 
355  return ret;
356 }
357 
366 {
367  t_graph *g = (t_graph*)d;
368  t_gen ret;
369 
370  // unlink N1->N2
371  ret = g->del_edge(g, n1, n2);
372 
373  // unlink N2->N1
374  ret = g->del_edge(g, n2, n1);
375 
376 }
377 
385 {
386  t_graph *g = (t_graph*)d;
387  int i;
388  t_gnode *A, *node;
389  t_gen tmp = NULL;
390 
391  // Find node
392  A = g->find(g, n1);
393 
394  // return if node doesn't exist
395  if (A == NULL) {
396  return tmp;
397  }
398 
399 
400  // travers all nodes in graph
401  // and delete itself from each node->neigh list
402  for (i = 0; i < g->count; i++) {
403  if (A->idx == i) {
404  continue;
405  }
406  node = &g->nodes[i];
407  tmp = node->neigh->del(node->neigh, A);
408  free_mem(tmp);
409  }
410  // destroy neigh list
411  A->neigh->destroy(A->neigh);
412  tmp = A->id;
413 
414  g->count--;
415 
416  if (g->count != 0 && g->count != A->idx) {
417  // Swap node to be deleted with last node
418  A->id = g->nodes[g->count].id;
419  A->neigh = g->nodes[g->count].neigh;
420  }
421 
422  return tmp;
423 }
424 
435 void bfs_core(t_graph *g, t_gnode *node, t_bfsinfo *bfs, t_queue *q, int comp)
436 {
437  t_linklist *neigh_list;
438  t_llnode *cur, *end;
439  t_gnode *neigh;
440  t_gedge *edge;
441 
442  // Initializations
443  bfs[node->idx].level = 0;
444  bfs[node->idx].parent = NULL;
445  bfs[node->idx].comp = comp;
446  q->enq(q, node);
447  while (q->empty(q) != true) {
448  node = q->deq(q);
449 
450  // For each vertex in queue
451  // Increment level and update parent for each new vertex
452  neigh_list = (t_linklist*)node->neigh;
453  cur = neigh_list->head_node(neigh_list);
454  end = neigh_list->end_node(neigh_list);
455  while (cur) {
456  edge = cur->data;
457  neigh = edge->node;
458  // If neigh node not visited add neigh to queue
459  if (bfs[neigh->idx].level == -1) {
460  bfs[neigh->idx].level = bfs[node->idx].level + 1;
461  bfs[neigh->idx].parent = node->id;
462  bfs[neigh->idx].comp = comp;
463  q->enq(q, neigh);
464  }
465  // Get next node in neigh list
466  cur = neigh_list->next_node(neigh_list, cur);
467  if (cur == end) {
468  break;
469  }
470  }
471  }
472 }
473 
474 
486 {
487  t_graph *g = (t_graph*)d;
488  t_gnode *node;
489  t_queue *q;
490  t_bfsinfo *bfs = NULL;
491  t_dparams dp;
492  int comp;
493  bool all_nodes_visited = false;
494 
495  // Find node
496  node = g->find(g, n);
497 
498  // return if node doesn't exist
499  if (node == NULL) {
500  return bfs;
501  }
502 
503  // Create queue and bfs info array for bfs
504  init_data_params(&dp, eINT32);
505  dp.free = dummy_free;
506  q = create_queue("bfs_Q", g->count, eLL_QUEUE_CIRC, &dp);
507  bfs = get_mem(g->count, sizeof(t_bfsinfo));
508 
509  // Init bfs data struct for vertex exploration
510  for (int i = 0; i < g->count; i++) {
511  bfs[i].parent = NULL;
512  bfs[i].comp = bfs[i].level = -1;
513  }
514 
515  // Run BFS for different connected Components of graph
516  comp = 0;
517  while (all_nodes_visited == false) {
518  bfs_core(g, node, bfs, q, comp);
519 
520  all_nodes_visited = true;
521 
522  for (int i = 0; i < g->count; i++) {
523  // unvisited Vertex remains and belongs to different component
524  // Run BFS with new unvisited vertex
525  if (bfs[i].level == -1) {
526  all_nodes_visited = false;
527  node = &g->nodes[i];
528  comp++;
529  break;
530  }
531  }
532  }
533 
534  q->destroy(q);
535 
536  return bfs;
537 }
538 
550 void dfs_core(t_graph *g, t_gnode *node, t_dfsinfo *dfs, t_stack *s, int comp, int *gcount)
551 {
552  t_linklist *neigh_list;
553  t_llnode *cur, *end;
554  t_gnode *neigh;
555  t_gedge *edge;
556  int count = *gcount;
557 
558  dfs[node->idx].parent = NULL;
559  dfs[node->idx].pre = count++;
560  dfs[node->idx].comp = comp;
561  s->push(s, node);
562  do {
563  neigh_list = (t_linklist*)node->neigh;
564  cur = neigh_list->head_node(neigh_list);
565  end = neigh_list->end_node(neigh_list);
566  // Depth Traversal of unvisited neighbor vertex
567  // Don't check Neighbor list if already all neighbors visited
568  while (cur && dfs[node->idx].visited_neighbors != 0) {
569  edge = cur->data;
570  neigh = edge->node;
571  // For each unvisited neighbor vertex
572  // update parent and pre count
573  // Push Node to stack break for Depth Traversal
574  if (dfs[neigh->idx].pre == -1) {
575  dfs[neigh->idx].parent = node->id;
576  dfs[neigh->idx].pre = count++;
577  dfs[neigh->idx].comp = comp;
578  s->push(s, neigh);
579  node = neigh;
580  break;
581  }
582  // Else get next unvisited vertex in neigh list
583  else {
584  // Get next unvisited node in neigh list
585  cur = neigh_list->next_node(neigh_list, cur);
586 
587  if (cur == end) {
588  // All neighbor of current node have been visited
589  dfs[node->idx].visited_neighbors = 0;
590  break;
591  }
592  }
593  }
594 
595  node = s->pop(s);
596  // Pop'd node has unvisted neighbors
597  // Push node on to stack again to continue DFS for unvisited neighbors
598  if (dfs[node->idx].visited_neighbors != 0 && cur) {
599  s->push(s, node);
600  continue;
601  }
602 
603  // All neighbors visited update post count on exit
604  dfs[node->idx].post = count++;
605  } while (s->empty(s) != true);
606 
607  // Preserve count value for remaining nodes
608  *gcount = count;
609 }
610 
611 
623 {
624  t_graph *g = (t_graph*)d;
625  t_gnode *node;
626  t_stack *s;
627  t_dfsinfo *dfs = NULL;
628  t_dparams dp;
629  int count, comp;
630  bool all_nodes_visited = false;
631 
632  // Find node
633  node = g->find(g, n);
634 
635  // return if node doesn't exist
636  if (node == NULL) {
637  return dfs;
638  }
639 
640  // Create stack and dfs info array for dfs
641  init_data_params(&dp, eINT32);
642  dp.free = dummy_free;
643  s = create_stack("dfs_Stack", g->count, eLL_STACK, &dp);
644  dfs = get_mem(g->count, sizeof(t_dfsinfo));
645 
646  // Init dfs data struct for vertex exploration
647  for (int i = 0; i < g->count; i++) {
648  dfs[i].comp = -1;
649  dfs[i].parent = NULL;
650  dfs[i].pre = dfs[i].post = -1;
651  dfs[i].visited_neighbors = 1;
652  }
653 
654  // Run DFS for different connected Components of graph
655  comp = count = 0;
656  while (all_nodes_visited == false) {
657  dfs_core(g, node, dfs, s, comp, &count);
658 
659  all_nodes_visited = true;
660  for (int i = 0; i < g->count; i++) {
661  // unvisited Vertex remains and belongs to different component
662  // Run DFS with new unvisited vertex
663  if (dfs[i].pre == -1) {
664  all_nodes_visited = false;
665  node = &g->nodes[i];
666  comp++;
667  break;
668  }
669  }
670  }
671  s->destroy(s);
672 
673  return dfs;
674 }
675 
686 {
687  t_graph *g = (t_graph*)d;
688  t_gnode *node, *neigh;
689  t_gedge *edge;
690  t_stack *s;
691  t_dfsinfo *dfs = NULL;
692  t_dparams dp;
693  t_linklist *neigh_list;
694  t_llnode *cur, *end = NULL;
695  int count = 0;
696 
697  // Find node
698  node = g->find(g, n);
699 
700  // return if node doesn't exist
701  if (node == NULL) {
702  return dfs;
703  }
704 
705  // Create queue and dfs info array for dfs
706  init_data_params(&dp, eINT32);
707  dp.free = dummy_free;
708  s = create_stack("dfs_Stack", g->count, eLL_STACK, &dp);
709  dfs = get_mem(g->count, sizeof(t_dfsinfo));
710 
711  // Init dfs data struct for vertex exploration
712  for (int i = 0; i < g->count; i++) {
713  dfs[i].parent = NULL;
714  dfs[i].pre = dfs[i].post = -1;
715  neigh_list = (t_linklist*)(g->nodes[i].neigh);
716  dfs[i].visited_neighbors = neigh_list->len(neigh_list);
717  }
718 
719  dfs[node->idx].pre = count++;
720  s->push(s, node);
721  do {
722  neigh_list = (t_linklist*)node->neigh;
723  cur = neigh_list->head_node(neigh_list);
724 
725  // Depth Traversal of unvisited neighbor vertex
726  // Don't check Neighbor list if already visited all the neighbors
727  while (cur && dfs[node->idx].visited_neighbors != 0) {
728  edge = cur->data;
729  neigh = edge->node;
730  dfs[node->idx].visited_neighbors--;
731  // For each vertex unvisited vertex
732  // update parent and pre count
733  // Push Node to stack for Depth Traversal
734  if (dfs[neigh->idx].pre == -1) {
735  dfs[neigh->idx].parent = node->id;
736  s->push(s, neigh);
737  dfs[neigh->idx].pre = count++;
738  node = neigh;
739 
740  // Constant 0(1) del and append on link list
741  // To ensure not visiting a previously visited vertex
742  // By pushing the unvisited node to last
743  // And eliminating it being revisited
744  // By traversing the list only 'visited_neighbors' times
745  edge = neigh_list->del_idx(neigh_list, 0);
746  neigh_list->append(neigh_list, edge);
747  break;
748  }
749  // Else get next unvisited vertex in neigh list
750  else {
751  // Get next unvisited node in neigh list
752  cur = neigh_list->next_node(neigh_list, cur);
753 
754  if (cur == end) {
755  // All neighbor of current node have been visited
756  //dfs[node->idx].visited_neighbors = true;
757  break;
758  }
759  }
760  }
761 
762  node = s->pop(s);
763  // Pop'd node has unvisted neighbors
764  // Push node on to stack again to continue DFS for unvisited neighbors
765  if (dfs[node->idx].visited_neighbors != 0) {
766  s->push(s, node);
767  continue;
768  }
769 
770  // All neighbors visited update post count on exit
771  dfs[node->idx].post = count++;
772  } while (s->empty(s) != true);
773 
774  s->destroy(s);
775 
776  return dfs;
777 }
778 
779 
790 {
791  t_graph *g = (t_graph*)d;
792  t_gnode *node, *neigh;
793  t_gedge *edge;
794  t_linklist *neigh_list;
795  t_llnode *cur,*end;
796  t_daginfo *dag_inf;
797  t_dparams dp;
798  t_queue *q;
799 
800  // Create queue and array for dag_inf
801  dag_inf = get_mem(g->count, sizeof(t_daginfo));
802  init_data_params(&dp, eINT32);
803  dp.free = dummy_free;
804  q = create_queue("topo_dag", g->count, eLL_QUEUE_CIRC, &dp);
805 
806  // Indegree initialization
807  for (int i = 0; i < g->count; i++) {
808  dag_inf[i].indegree = 0;
809  dag_inf[i].longest_path = 0;
810  }
811 
812  // Update indegree for all nodes
813  for (int i = 0; i < g->count; i++) {
814  neigh_list = g->nodes[i].neigh;
815  cur = neigh_list->head_node(neigh_list);
816  end = neigh_list->end_node(neigh_list);
817  while (cur) {
818  edge = cur->data;
819  node = edge->node;
820  dag_inf[node->idx].indegree += 1;
821  cur = neigh_list->next_node(neigh_list, cur);
822  if (cur == end) {
823  break;
824  }
825  }
826  }
827 
828  // Add vertices with indegree 0
829  for (int i = 0; i < g->count; i++) {
830  if (dag_inf[i].indegree == 0) {
831  q->enq(q, &g->nodes[i]);
832  }
833  }
834 
835  // Start exploration to sort/order by
836  // Enumerating the vertices(delete/visited)
837  while (q->empty(q) != true) {
838  node = q->deq(q);
839  // Enumerate node, i.e, mark as visited
840  dag_inf[node->idx].node = node->id;
841  dag_inf[node->idx].indegree = -1;
842 
843  // update longest path and indegree of neighbors
844  // for the enumerated vertex
845  neigh_list = node->neigh;
846  cur = neigh_list->head_node(neigh_list);
847  end = neigh_list->end_node(neigh_list);
848  while (cur) {
849  edge = cur->data;
850  neigh = edge->node;
851  dag_inf[neigh->idx].indegree -= 1;
852  // update path as max of parent and cur longest path
853  dag_inf[neigh->idx].longest_path =
854  (dag_inf[neigh->idx].longest_path > dag_inf[node->idx].longest_path) ?
855  dag_inf[neigh->idx].longest_path : (dag_inf[node->idx].longest_path + 1);
856 
857  //push to queue any neigh with indegree 0
858  if (dag_inf[neigh->idx].indegree == 0) {
859  q->enq(q, neigh);
860  }
861  // Get next neigh
862  cur = neigh_list->next_node(neigh_list, cur);
863  if (cur == end) {
864  break;
865  }
866  }
867  }
868 
869  q->destroy(q);
870 
871  return dag_inf;
872 }
873 
881 {
882  t_graph *g = (t_graph*)d;
883  t_gnode *node;
884  t_gedge *edge;
885  t_linklist *l = (t_linklist*)neigh;
886  t_llnode *cur, *end;
887 
888  printf("{ ");
889  cur = l->head_node(l);
890  while (cur) {
891  edge = cur->data;
892  node = edge->node;
893  g->print_data(node->id);
894  printf(" ");
895  cur = l->next_node(l, cur);
896  if (cur == end) {
897  break;
898  }
899  }
900  printf("}");
901 }
902 
909 {
910  t_graph *g = (t_graph*)d;
911  int i;
912 
913  printf("%s: vertex:%d edges:%d\n", g->name, g->count, g->total_edges);
914 
915  for (i = 0; i < g->count; i++) {
916  g->print_data(g->nodes[i].id);
917  printf(":");
918  graph_neigh_print(g,g->nodes[i].neigh);
919  printf("\n");
920  }
921 }
922 
930 {
931  t_graph *g = (t_graph*)d;
932  t_gnode *node;
933  t_gedge *edge;
934  t_linklist *l = (t_linklist*)neigh;
935  t_llnode *cur, *end;
936 
937  printf("{ ");
938  cur = l->head_node(l);
939  while (cur) {
940  edge = cur->data;
941  node = edge->node;
942  printf("<");
943  g->print_data(node->id);
944  printf(" %d> ", edge->weight);
945  cur = l->next_node(l, cur);
946  if (cur == end) {
947  break;
948  }
949  }
950  printf("}");
951 }
952 
953 
960 {
961  t_graph *g = (t_graph*)d;
962  int i;
963 
964  printf("%s: vertex:%d edges:%d\n", g->name, g->count, g->total_edges);
965 
966  for (i = 0; i < g->count; i++) {
967  g->print_data(g->nodes[i].id);
968  printf(":");
969  graph_wneigh_print(g,g->nodes[i].neigh);
970  printf("\n");
971  }
972 }
973 
981 {
982  t_gedge *A = (t_gedge*)x;
983  t_gedge *B = (t_gedge*)y;
984  e_cmpr ret = eEQUAL;
985 
986  if (A->weight > B->weight) {
987  ret = eGREAT;
988  }
989  else if (A->weight < B->weight) {
990  ret = eLESS;
991  }
992 
993  return ret;
994 }
995 
1005 {
1006  t_gen *arr = (t_gen*)x;
1007  return graph_wedge_cmpr(arr[i], arr[j]);
1008 }
1009 
1019 {
1020  t_distinfo *arr = (t_distinfo*)x;
1021  return graph_wedge_cmpr(&arr[i], &arr[j]);
1022 }
1023 
1032 SWP_IDX(t_distinfo, graph_wedge_swap_idx)
1033 
1034 
1044 {
1045  t_graph *g = (t_graph*)d;
1046  t_gnode *node;
1047  t_gedge *v, *u;
1048  t_llnode *cur, *end;
1049  t_linklist *neigh_list;
1050  t_distinfo *dist, *tmp;
1051  t_heap *h;
1052  t_dparams dp;
1053  t_gen *pq;
1054  int alt_weight;
1055 
1056  // Get vertex
1057  node = g->find(g, data);
1058  if (node == NULL) {
1059  return NULL;
1060  }
1061 
1062  // Data specific operation for generic min heap
1063  init_data_params(&dp, eUSER);
1064  dp.free = dummy_free;
1065  dp.cmpr = graph_wedge_cmpr;
1067  dp.swap_idx = gen_swp_idx;
1068  dp.copy_idx = gen_cpy_idx;
1069  dp.get_idx = gen_get_idx;
1070 
1071  // Creating a generic min heap to store edges
1072  pq = get_mem(g->count, sizeof(t_gen));
1073  h = create_heap("Dijkstra's Heap", pq, g->count, eMIN_HEAP, &dp);
1074 
1075  // Initalize all dist to all nodes as infinite
1076  dist = get_mem(g->count, sizeof(t_distinfo));
1077  for (int i = 0; i < g->count; i++) {
1078  dist[i].edge.node = &g->nodes[i];
1079  dist[i].edge.weight = INT_MAX;
1080  dist[i].parent = NULL;
1081  }
1082 
1083  // Set the source node dist as 0
1084  dist[node->idx].edge.weight = 0;
1085 
1086  // Add source vertex to heap
1087  h->insert(h, &dist[node->idx].edge);
1088  while (h->empty(h) != true) {
1089  // Get min dist vertex from heap and traverse all its edges
1090  // check if dist from cur vertex to its neigh vertex is smaller
1091  // Using heaps cos extract min is O(1)
1092  u = h->extract(h);
1093 
1094  neigh_list = (t_linklist*)u->node->neigh;
1095  cur = neigh_list->head_node(neigh_list);
1096  end = neigh_list->end_node(neigh_list);
1097  while (cur) {
1098  v = (t_gedge*)cur->data;
1099 
1100  // If cur dist is greater than the alt dist
1101  alt_weight = u->weight + v->weight;
1102  if (dist[v->node->idx].edge.weight > alt_weight) {
1103  // Set cur dist as alt dist, update parent
1104  // and add edge to heap
1105  dist[v->node->idx].edge.weight = alt_weight;
1106  dist[v->node->idx].parent = u->node;
1107  h->insert(h, &dist[v->node->idx].edge);
1108  }
1109 
1110  // Exit after neigh list traversal complete
1111  cur = neigh_list->next_node(neigh_list, cur);
1112  if (cur == end) {
1113  break;
1114  }
1115  }
1116  }
1117 
1118  // Destroy heap and destroy the array used for storing heap
1119  h->destroy(h);
1120  free_mem(pq);
1121 
1122  return dist;
1123 }
1124 
1136 {
1137  t_graph *g = (t_graph*)d;
1138  t_gnode *node;
1139  t_gedge *v, *u;
1140  t_llnode *cur, *end;
1141  t_linklist *neigh_list;
1142  t_distinfo *dist, *tmp;
1143  t_dparams dp;
1144  t_queue *q;
1145  int alt_weight;
1146  bool *in_q;
1147 
1148  // Get vertex
1149  node = g->find(g, data);
1150  if (node == NULL) {
1151  return NULL;
1152  }
1153 
1154  init_data_params(&dp, eINT32);
1155  dp.free = dummy_free;
1156  q = create_queue("bellman_q", g->count, eLL_QUEUE_CIRC, &dp);
1157 
1158  // Initalize all dist to all nodes as infinite
1159  dist = get_mem(g->count, sizeof(t_distinfo));
1160  in_q = get_mem(g->count, sizeof(bool));
1161  for (int i = 0; i < g->count; i++) {
1162  dist[i].edge.node = &g->nodes[i];
1163  dist[i].edge.weight = INT_MAX;
1164  dist[i].parent = NULL;
1165  in_q[i] = false;
1166  }
1167 
1168  // Set the source node dist as 0
1169  dist[node->idx].edge.weight = 0;
1170  q->enq(q, &dist[node->idx].edge);
1171  in_q[node->idx] = true;
1172  while (q->empty(q) != true) {
1173  u = q->deq(q);
1174  in_q[u->node->idx] = false;
1175  neigh_list = (t_linklist*)u->node->neigh;
1176  cur = neigh_list->head_node(neigh_list);
1177  end = neigh_list->end_node(neigh_list);
1178 
1179  while (cur) {
1180  v = (t_gedge*)cur->data;
1181 
1182  // If cur dist is greater than the alt dist
1183  alt_weight = dist[u->node->idx].edge.weight + v->weight;
1184  if (dist[v->node->idx].edge.weight > alt_weight) {
1185  // Set cur dist as alt dist, update parent
1186  // and add edge to queue if vertex not already in queue
1187  dist[v->node->idx].edge.weight = alt_weight;
1188  dist[v->node->idx].parent = u->node;
1189  if (in_q[v->node->idx] != true) {
1190  q->enq(q, &dist[v->node->idx].edge);
1191  in_q[v->node->idx] = true;
1192  }
1193 
1194  }
1195 
1196  // Exit after neigh list traversal complete
1197  cur = neigh_list->next_node(neigh_list, cur);
1198  if (cur == end) {
1199  break;
1200  }
1201  }
1202  }
1203 
1204  q->destroy(q);
1205  free_mem(in_q);
1206 
1207  return dist;
1208 }
1209 
1218 {
1219  t_graph *g = (t_graph*)d;
1220  t_gedge *v, *u;
1221  t_llnode *cur, *end;
1222  t_linklist *neigh_list;
1223  t_distinfo *dist, *tmp;
1224  t_heap *h;
1225  t_dparams dp;
1226  t_gen *pq;
1227 
1228  // Data specific operation for generic min heap
1229  init_data_params(&dp, eUSER);
1230  dp.free = dummy_free;
1231  dp.cmpr = graph_wedge_cmpr;
1233  dp.swap_idx = gen_swp_idx;
1234  dp.copy_idx = gen_cpy_idx;
1235  dp.get_idx = gen_get_idx;
1236 
1237  // Creating a generic min heap to store edges
1238  pq = get_mem(g->count, sizeof(t_gen));
1239  h = create_heap("Dijkstra's Heap", pq, g->count, eMIN_HEAP, &dp);
1240 
1241  // Initalize all dist to all nodes as infinite
1242  dist = get_mem(g->count, sizeof(t_distinfo));
1243  for (int i = 0; i < g->count; i++) {
1244  dist[i].edge.node = &g->nodes[i];
1245  dist[i].edge.weight = INT_MAX;
1246  dist[i].parent = NULL;
1247  }
1248 
1249 
1250  // Set 0 as start vertex
1251  h->insert(h, &dist[0].edge);
1252  while (h->empty(h) != true) {
1253  // Of the edges that connect the tree to vertices not yet in the tree,
1254  // Find the minimum-weight edge, and transfer it to the tree
1255  u = h->extract(h);
1256 
1257  neigh_list = (t_linklist*)u->node->neigh;
1258  cur = neigh_list->head_node(neigh_list);
1259  end = neigh_list->end_node(neigh_list);
1260  while (cur) {
1261  v = (t_gedge*)cur->data;
1262 
1263  // If cur edge weight is greater than new edge
1264  // and the end vertex is not visited
1265  if (dist[v->node->idx].edge.weight > v->weight) {
1266  // Set new edge as part of MST, update parent
1267  // and add edge to heap
1268  dist[v->node->idx].edge.weight = v->weight;
1269  dist[v->node->idx].parent = u->node;
1270  h->insert(h, &dist[v->node->idx].edge);
1271  }
1272 
1273  // Exit after neigh list traversal complete
1274  cur = neigh_list->next_node(neigh_list, cur);
1275  if (cur == end) {
1276  break;
1277  }
1278  }
1279  }
1280 
1281  // Destroy heap and destroy the array used for storing heap
1282  h->destroy(h);
1283  free_mem(pq);
1284 
1285  return dist;
1286 }
1287 
1296 {
1297  t_graph *g = (t_graph*)d;
1298  t_gnode *v, *u;
1299  t_llnode *cur, *end;
1300  t_linklist *neigh_list;
1301  t_distinfo *dist, *tmp;
1302  t_dparams dp;
1303  t_disjset *set;
1304  int i, j;
1305 
1306  // Allocate mem for edge list
1307  tmp = get_mem(g->total_edges, sizeof(t_distinfo));
1308  // Allocate mem for storing MST
1309  dist = get_mem(g->count, sizeof(t_distinfo));
1310  // Create a disjoint set
1311  set = create_disjoint_set("Kruskal graph set", g->total_edges);
1312 
1313  // Create edge list from Adjancency list
1314  for (j = i = 0; i < g->count; i++) {
1315  neigh_list = (t_linklist*)(g->nodes[i].neigh);
1316  cur = neigh_list->head_node(neigh_list);
1317  end = neigh_list->end_node(neigh_list);
1318  while (cur) {
1319  tmp[j].parent = &g->nodes[i];
1320  tmp[j++].edge = *((t_gedge*)cur->data);
1321 
1322  // Exit after neigh list traversal complete
1323  cur = neigh_list->next_node(neigh_list, cur);
1324  if (cur == end) {
1325  break;
1326  }
1327  }
1328  }
1329 
1330  // Data specific operation for sorting edges
1331  init_data_params(&dp, eUSER);
1333  dp.swap_idx = graph_wedge_swap_idx;
1334 
1335  // Sort the edge List based on weights
1336  quick_sort(tmp, g->total_edges, &dp);
1337 
1338  // Make a disjoint set for all the vertex in graph
1339  //(create a forest (a set of trees), where each vertex in the graph is a separate tree)
1340  set->make(set);
1341 
1342  // Get edges in ascending order from the edge list
1343  // Kruskals algorithm terminates if MST is formed(dist contains V-1 edges)
1344  // or, all edges have been visited
1345  for (j = i = 0; (j < g->count) && (i < g->total_edges); i++) {
1346  u = tmp[i].parent;
1347  v = tmp[i].edge.node;
1348 
1349  // If edges connect two different trees add to forest(Minimum spanning Tree)
1350  if (set->find(set, u->idx) != set->find(set, v->idx)) {
1351  dist[j++] = tmp[i];
1352  set->merge(set, u->idx, v->idx);
1353  }
1354  }
1355 
1356  // Destroy disjoint set and the edge list
1357  set->destroy(set);
1358  free_mem(tmp);
1359 
1360  return dist;
1361 }
1362 
1369 {
1370  t_graph *g = (t_graph*)d;
1371  int i;
1372 
1373  // Go through each node and delete neigh list and data
1374  for (i = 0; i < g->count; i++) {
1375  g->nodes[i].neigh->destroy(g->nodes[i].neigh);
1376  g->free(g->nodes[i].id, __FILE__, __LINE__);
1377  }
1378 
1379  free_mem(g->nodes);
1380  free_mem(g);
1381 }
1382 
1383 
void quick_sort(t_gen a, int n, t_dparams *op)
Quicksort is an in-place sorting algorithm is a divide and conquer algorithm which relies on a partit...
Definition: array.c:122
Contains declations of array operations and structure.
void init_data_params(t_dparams *, e_data_types)
Called to initalize data params for default data types Else for custom data types the data params str...
Definition: common.c:15
void dummy_free(void *mem_addr, char *file, int line)
Dummy free function Else for custom data types the data params structure is to be defined by user
Definition: common.c:75
t_gen create_disjoint_set(char *name, int size)
Create an instance of disjoint set data struct
Definition: disjoint_set.c:20
Contains declations of disjoint_set types, operations and structure.
t_gen gen_get_idx(t_gen x, int idx1)
Definition: generic_def.c:68
void gen_swp_idx(t_gen x, int idx1, int idx2)
Definition: generic_def.c:80
void gen_cpy_idx(t_gen x, int idx1, t_gen data)
Definition: generic_def.c:74
#define SWP_IDX(T, NAME)
Template function for swaping elemts at given indicies of an array for default data types.
Definition: generic_def.h:83
t_gen graph_add_edge(t_gen d, t_gen n1, t_gen n2)
Add an asymmetric edge between two vertices(nodes) in graph;
Definition: graph.c:219
void graph_wneigh_print(t_gen d, t_gen neigh)
Util function to Print neighbor list of a vetex(node) with edge weights
Definition: graph.c:929
void graph_neigh_print(t_gen d, t_gen neigh)
Util function to Print neighbor list of a vetex(node)
Definition: graph.c:880
void graph_neigh_list_free(t_gen mem, char *file, int line)
Util free function for deleting neigh link list node data
Definition: graph.c:137
t_gen graph_del_vertex(t_gen d, t_gen n1)
Del a vertex(node) in graph;
Definition: graph.c:384
t_gen graph_toplogicaly_order_dag(t_gen d)
Topologicaly order/Topologicaly sort the nodes of a DAG And get the longest path to each of the verti...
Definition: graph.c:789
e_cmpr graph_wedge_cmpr_idx2(t_gen x, int i, int j)
Utils function used by quick sort for comparing graph edge weights
Definition: graph.c:1018
t_gen graph_add_wedge_sym(t_gen d, t_gen n1, t_gen n2, int weight)
Add a symmetric weighted edge between two vertices(nodes) in graph;
Definition: graph.c:345
void graph_wprint(t_gen d)
Print Graph info with edge weights
Definition: graph.c:959
t_gen graph_has_edge(t_gen d, t_gen n1, t_gen n2)
Check edge between two Vertices(nodes) in graph;
Definition: graph.c:195
t_gen graph_add_edge_sym(t_gen d, t_gen n1, t_gen n2)
Add a symmetric edge between two vertices(nodes) in graph;
Definition: graph.c:324
t_gen graph_dfs(t_gen d, t_gen n)
Depth First Search DFS info contains
Definition: graph.c:622
e_cmpr graph_wedge_cmpr_idx(t_gen x, int i, int j)
Utils function used by genric heap for comparing graph edge weights
Definition: graph.c:1004
t_gen dijkstra(t_gen d, t_gen data)
Utils function used by quick sort for swapping graph edges
Definition: graph.c:1043
t_gen graph_del_edge(t_gen d, t_gen n1, t_gen n2)
Del an asymmetric edge between two vertices(nodes) in graph;
Definition: graph.c:298
t_gen graph_delete(t_gen, t_gen)
t_gen graph_bfs(t_gen d, t_gen n)
Breath First Search BFS info Contains
Definition: graph.c:485
void graph_print(t_gen d)
Print Graph info
Definition: graph.c:908
e_cmpr graph_wedge_cmpr(t_gen x, t_gen y)
Utils function used for comparing two different graph edges
Definition: graph.c:980
t_gen kruskals_mst(t_gen d)
Find the Minimum Spanning for weighted undirected graph Using Kruskal's Algorithm
Definition: graph.c:1295
t_gen graph_del_edge_sym(t_gen d, t_gen n1, t_gen n2)
Del a symmetric edge between two vertices(nodes) in graph;
Definition: graph.c:365
t_gen graph_find(t_gen, t_gen)
Find a Vertex(node) in graph;
Definition: graph.c:98
t_gen graph_add_wedge(t_gen d, t_gen n1, t_gen n2, int weight)
Add an asymmetric weighted edge between two vertices(nodes) in graph;
Definition: graph.c:259
void bfs_core(t_graph *g, t_gnode *node, t_bfsinfo *bfs, t_queue *q, int comp)
Breath First Search Core routine This routine does bfs on all conncted components
Definition: graph.c:435
void graph_destroy(t_gen d)
Destroy instance of graph
Definition: graph.c:1368
void dfs_core(t_graph *g, t_gnode *node, t_dfsinfo *dfs, t_stack *s, int comp, int *gcount)
Depth First Search Core routine This routine does dfs on all conncted components
Definition: graph.c:550
t_gen create_graph(char *name, int size, t_dparams *prm)
Create an instance of graph
Definition: graph.c:42
int graph_len(t_gen)
get num Vertex(nodes) in graph;
Definition: graph.c:87
t_gen graph_add_vertex(t_gen d, t_gen data)
Add a Vertex(node) in graph;
Definition: graph.c:153
t_gen graph_dfs_optimised(t_gen d, t_gen n)
Depth First Search Optimised by eliminating the need for revisiting a previously visited vetex in nei...
Definition: graph.c:685
e_cmpr graph_neigh_list_compare(t_gen x, t_gen y)
Util compare function for neigh link list node data
Definition: graph.c:118
t_gen prims_mst(t_gen d)
Find the Minimum Spanning for weighted undirected graph Using Prim's Algorithm
Definition: graph.c:1217
t_gen bellman_ford(t_gen d, t_gen data)
Find the shortest path from a given source vertex to all source nodes in a graph with negative edges ...
Definition: graph.c:1135
Contains declations of graph types, operations and structure.
t_gen create_heap(char *name, t_gen data, int size, e_heaptype htype, t_dparams *prm)
Create an instance of heap
Definition: heap.c:29
Contains declations of heap types, operations and structure.
@ eMIN_HEAP
Minimum Heap
Definition: heap.h:10
#define free_mem(mem_addr)
Definition: memory_manager.h:9
#define get_mem(nmemb, size)
Definition: memory_manager.h:8
t_gen create_queue(char *name, int max_size, e_queuetype qtype, t_dparams *prm)
Destroy queue instance
Definition: queue.c:37
Contains declations of queue types, operations and structure.
@ eLL_QUEUE_CIRC
Link List Based Queue.
Definition: queue.h:12
t_gen create_stack(char *name, int max_size, e_stacktype stype, t_dparams *prm)
Create an instance of stack
Definition: stack.c:37
Contains declations of stack types, operations and structure.
@ eLL_STACK
LinkList based Stack.
Definition: stack.h:13
Level and Parent info after BFS walk.
Definition: graph.h:64
t_gen parent
Pointer to Parent Vertex.
Definition: graph.h:65
int comp
Subgraph id of vertex.
Definition: graph.h:67
int level
Level of vertex from the source.
Definition: graph.h:66
Longest Path and Node order after DAG ordering.
Definition: graph.h:80
int indegree
Used internally for topologicaly order and find longest path in DAG.
Definition: graph.h:83
int longest_path
Longest path to vertex in DAG.
Definition: graph.h:82
t_gen node
Pointer to Vertex in topologically sorted order.
Definition: graph.h:81
data params struct defn
Definition: common.h:18
f_cmpr cmpr
Routine used for comparing two given elems of said type.
Definition: common.h:23
f_get_idx get_idx
Routine used for getting elem in given array index.
Definition: common.h:32
f_swap swap
Routine used for swaping two elemnts of goven data.
Definition: common.h:25
f_swp_idx swap_idx
Routine used for swapring elems in given array indicies.
Definition: common.h:29
f_free free
Routine used for freeing elements of said data.
Definition: common.h:26
f_cpy_idx copy_idx
Routine used for copying elems in given array indicies.
Definition: common.h:30
f_print print_data
Routine used for printing elem data.
Definition: common.h:33
f_cmp_idx cmpr_idx
Routine used for comparing elems in given array indicies.
Definition: common.h:28
Level and Parent info after DFS walk.
Definition: graph.h:71
t_gen parent
Pointer to Parent Vertex.
Definition: graph.h:72
int post
Post Interval of a vertex on dfs walk.
Definition: graph.h:74
int comp
Subgraph id of vertex.
Definition: graph.h:75
int visited_neighbors
Used internally Flag indicating neighbors still to be visited.
Definition: graph.h:76
int pre
Pre Interval of a vertex on dfs walk.
Definition: graph.h:73
Disjoint set main struct definition.
Definition: disjoint_set.h:19
f_set2 merge
routine to merge to set
Definition: disjoint_set.h:26
f_destroy destroy
routine to destroy the instace of disjoint set
Definition: disjoint_set.h:29
f_set1 find
routine to find an elem in the set
Definition: disjoint_set.h:25
f_vgen make
routine to add an new elem to the set
Definition: disjoint_set.h:24
Dist info.
Definition: graph.h:87
t_gnode * parent
Pointer to Vertex vertex.
Definition: graph.h:89
t_gedge edge
Pointer to edge.
Definition: graph.h:88
graph neighbor edges represented in neigh list
Definition: graph.h:17
int weight
Cost of the edge.
Definition: graph.h:19
t_gnode * node
Pointer to neighbor vertex.
Definition: graph.h:18
graph Vertex
Definition: graph.h:10
t_linklist * neigh
Link List to neighbor vertices(nodes)
Definition: graph.h:13
t_gen id
Pointer to store Data.
Definition: graph.h:11
int idx
Index of vertex in adaceny list.
Definition: graph.h:12
graph struct defn
Definition: graph.h:26
f_find find
routine to find a vertex in graph
Definition: graph.h:50
f_len len
routine to get vertex count in graph
Definition: graph.h:51
f_cmpr cmpr
Definition: graph.h:57
f_print wprint
routine to print graph info with edge weights
Definition: graph.h:53
f_gen3 del_edge_sym
routine to del a symmetric edge in graph
Definition: graph.h:42
f_swap swap
Definition: graph.h:58
f_print print
routine to print graph info
Definition: graph.h:52
t_gnode * nodes
Adaceny List Representation of graph vertices.
Definition: graph.h:34
f_wedge add_wedge_sym
routine to add a weighted symmetric edge in graph
Definition: graph.h:44
char * name
Graph Instance Name.
Definition: graph.h:28
f_destroy destroy
routine to destroy the graph instance
Definition: graph.h:54
f_free free
Definition: graph.h:59
f_gen3 add_edge_sym
routine to add a symmetric edge in graph
Definition: graph.h:41
f_gen3 del_edge
routine to del an edge in graph
Definition: graph.h:40
f_gen3 has_edge
routine to check an edge between two vertices graph
Definition: graph.h:45
f_gen3 add_edge
routine to add an edge in graph
Definition: graph.h:39
int max_size
Max Vertex count of graph.
Definition: graph.h:30
f_wedge add_wedge
routine to add a weighted edge in graph
Definition: graph.h:43
f_print print_data
Definition: graph.h:60
f_gen2 bfs
routine to Breadth First Search in graph
Definition: graph.h:46
f_gen2 del_vertex
routine to del a vertex in graph
Definition: graph.h:38
int count
Vertex Count of graph.
Definition: graph.h:29
f_gen2 dfs
routine to Depth First Search in graph
Definition: graph.h:47
f_gen topo_order_dag
routine to topologica order a DAG
Definition: graph.h:49
f_gen2 add_vertex
routine to add a vertex in graph
Definition: graph.h:37
int total_edges
Edge count of graph.
Definition: graph.h:31
Heap struct defn.
Definition: heap.h:18
f_ins insert
routine to insert elements in heap
Definition: heap.h:28
f_destroy destroy
routine to destroy
Definition: heap.h:37
f_empty empty
routine to check if heap empty
Definition: heap.h:35
f_gen extract
routine to extract min/max root element in heap
Definition: heap.h:29
Link list node definition.
Definition: link_list.h:19
t_gen data
Pointer to the data to be stored in link list.
Definition: link_list.h:20
stack struct defn
Definition: stack.h:19
f_vgen destroy
routine to destroy stack contents
Definition: stack.h:36
f_gen2 push
stack operations
Definition: stack.h:29
f_empty empty
routine to check if stack is empty
Definition: stack.h:33
f_gen pop
routine to pop element into stack
Definition: stack.h:30
queue struct defn
Definition: queue.h:17
f_gen deq
routine to pop elements out of queue
Definition: queue.h:30
f_destroy destroy
routine to detroy queue instance
Definition: queue.h:36
f_empty empty
routine to check if queue empty
Definition: queue.h:34
f_ins enq
routine to push elements to queue
Definition: queue.h:29
void * t_gen
Base Data type used for all data structure and data elements.
Definition: typedefs.h:41
e_cmpr
Custom Compare function return type.
Definition: typedefs.h:34
@ eGREAT
Definition: typedefs.h:37
@ eLESS
Definition: typedefs.h:35
@ eEQUAL
Definition: typedefs.h:36
@ eINT32
Definition: typedefs.h:24
@ eUSER
Definition: typedefs.h:30