shortestpath.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "shortestpath.h"
  5. #define INFINITE 1500000
  6. #define INVALID_INDEX -1
  7. void read_num_nodes(FILE *mfptr, int *num_nodes){
  8. // read first value in file
  9. if((fscanf(mfptr, "%d", num_nodes)) == EOF){
  10. return;
  11. }
  12. }
  13. void read_map(FILE *mfptr, int num_nodes, int **adjacent, int **verticies){
  14. // declare variables
  15. int a, b, c = 0; // store values
  16. int i = 0; // incrementor
  17. // ensure the fptr is at the beginning
  18. rewind(mfptr);
  19. // allocate memory and move fptr to correct spot
  20. fscanf(mfptr, "%d %d", &a, &b); // move past line 1
  21. //printf("%d %d\n", a, b); // for testing
  22. for(i = 0; i < num_nodes; i++){
  23. verticies[i] = calloc(2, sizeof(int)); // init to 0
  24. adjacent[i] = calloc(num_nodes, sizeof(int)); // init to 0
  25. fscanf(mfptr, "%d\t%d\t%d", &a, &b, &c); // move through
  26. verticies[i][0] = b;
  27. verticies[i][1] = c;
  28. }
  29. // scan relevent values
  30. while(fscanf(mfptr, "%d %d", &a, &b) != EOF){
  31. //printf("%d %d\n", a, b); // for testing
  32. adjacent[a][b] = 1;
  33. adjacent[b][a] = 1;
  34. }
  35. }
  36. void read_num_queries(FILE *qfptr, int *num_queries){
  37. // read first value in file
  38. if((fscanf(qfptr, "%d", num_queries)) == EOF){
  39. return;
  40. }
  41. }
  42. void read_queries(FILE *qfptr, int num_queries, int *queries){
  43. int a, b = 0; // store values
  44. int i = 0; // incrementor
  45. rewind(qfptr);
  46. fscanf(qfptr, "%d\n", &a); // move past line 1
  47. for(i = 0; i < num_queries; i++){
  48. fscanf(qfptr, "%d %d", &a, &b);
  49. queries[2 * i] = a;
  50. queries[2 * i + 1] = b;
  51. }
  52. }
  53. //
  54. // void read_verticies(FILE *mfptr, int num_nodes, int **verticies){
  55. // // declare variables
  56. // int a, b, c = 0; // store values
  57. // int i = 0; // incrementor
  58. //
  59. // // ensure the fptr is at the beginning
  60. // rewind(mfptr);
  61. //
  62. // // allocate memory and move fptr to correct spot
  63. // fscanf(mfptr, "%d %d", &a, &b); // move past line 1
  64. // //printf("%d %d\n", a, b); // for testing
  65. // for(i = 0; i < num_nodes; i++){
  66. // verticies[i] = calloc(2, sizeof(int)); // init to 0
  67. // fscanf(mfptr, "%d\t%d\t%d", &a, &b, &c); // move through
  68. // verticies[i][0] = b;
  69. // verticies[i][1] = c;
  70. // //printf("%d\t%d\t%d\n", a, b, c); // for testing
  71. // }
  72. // }
  73. int all_visited(int num_nodes, int *visited){
  74. int i = 0;
  75. for(i = 0; i < num_nodes; i++){
  76. if(visited[i] == 0){
  77. return 0;
  78. }
  79. }
  80. return 1;
  81. }
  82. void calculate_distances(int num_nodes, int **adjacent, int **verticies){
  83. int i, j = 0;
  84. for(i = 0; i < num_nodes; i++){
  85. for(j = 0; j < num_nodes; j++){
  86. if(i == j){
  87. adjacent[i][j] = 0;
  88. }else{
  89. if(adjacent[i][j] > 0){
  90. adjacent[i][j] = sqrt(pow(verticies[j][0] - verticies[i][0], 2) + pow(verticies[j][1] - verticies[i][1], 2));
  91. }else{
  92. adjacent[i][j] = INFINITE;
  93. }
  94. }
  95. }
  96. }
  97. }
  98. int dijkstra(int num_nodes, int source, int dest, int **adjacent){
  99. int *distance = calloc(num_nodes, sizeof(int));
  100. int *previous = calloc(num_nodes, sizeof(int));
  101. int *visited = calloc(num_nodes, sizeof(int));
  102. int *path = calloc(num_nodes, sizeof(int));
  103. int i, m, min, start, d, j = 0;
  104. for(i = 1; i < num_nodes; i++){
  105. distance[i] = adjacent[source][i];
  106. previous[i] = INVALID_INDEX;
  107. }
  108. start = source;
  109. visited[start] = 1;
  110. distance[start] = 0;
  111. while(visited[dest] == 0){
  112. min = INFINITE;
  113. m = 0;
  114. for(i = 1; i < num_nodes; i++){
  115. d = distance[start] + adjacent[start][i];
  116. if((d < distance[i]) && (visited[i] == 0)){
  117. distance[i] = d;
  118. previous[i] = start;
  119. }
  120. if((min > distance[i]) && (visited[i] == 0)){
  121. min = distance[i];
  122. m = i;
  123. }
  124. }
  125. start = m;
  126. visited[start] = 1;
  127. }
  128. start = dest;
  129. j = 0;
  130. while(start != -1){
  131. path[j++] = start;
  132. start = previous[start];
  133. }
  134. path[j] = source;
  135. printf("\n%d\n", distance[dest]);
  136. while(j >= 0){
  137. printf("%d ", path[j]);
  138. j--;
  139. }
  140. printf("\n");
  141. return distance[dest];
  142. }
  143. int main (int argc, char **argv){
  144. int num_nodes = 0;
  145. int num_queries = 0;
  146. // open files for reading
  147. FILE *mfptr = fopen(argv[1], "r");
  148. if (mfptr == NULL){ // check for error
  149. printf("Map file name error.\n");
  150. return EXIT_FAILURE;
  151. }
  152. FILE *qfptr = fopen(argv[2], "r");
  153. if (qfptr == NULL){ // check for error
  154. printf("Query file name error.\n");
  155. return EXIT_FAILURE;
  156. }
  157. read_num_nodes(mfptr, &num_nodes);
  158. int **adjacent = malloc(num_nodes * sizeof(int *));
  159. int **verticies = malloc(num_nodes * sizeof(int *));
  160. read_map(mfptr, num_nodes, adjacent, verticies);
  161. calculate_distances(num_nodes, adjacent, verticies);
  162. read_num_queries(qfptr, &num_queries);
  163. int *queries = calloc(num_queries * 2 + 1, sizeof(int));
  164. read_queries(qfptr, num_queries, queries);
  165. int i = 0;
  166. for(i = 0; i < num_queries; i++){
  167. dijkstra(num_nodes, queries[2 * i], queries[2 * i + 1], adjacent);
  168. }
  169. // clean up
  170. for(i = 0; i < num_nodes; i++){
  171. free(adjacent[i]);
  172. }
  173. free(adjacent);
  174. fclose(mfptr);
  175. //fclose(qfptr);
  176. return EXIT_SUCCESS;
  177. }