Advertisement
Guest User

Untitled

a guest
Sep 16th, 2015
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.00 KB | None | 0 0
  1. //#include "stdafx.h" /* make compatible with MS Visual Studio */
  2.  
  3. #include <limits.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7.  
  8. #define TIME 29
  9. #define NOPT 3
  10.  
  11. typedef struct e {
  12. int to, from, cost;
  13. } edge;
  14.  
  15. typedef struct c {
  16. int c1, c2, group;
  17. } city;
  18.  
  19. int * table;
  20.  
  21. int n_cities;
  22.  
  23. void swap (edge ** e, edge ** f);
  24.  
  25. int part (edge ** edges, int low, int high);
  26.  
  27. void quicksort (edge ** edges, int low, int high);
  28.  
  29. int compare (edge * e, edge * f);
  30.  
  31. void city_init(city * c);
  32.  
  33. int city_open(city * c);
  34.  
  35. void city_connect(city * c, int i);
  36.  
  37. int cities_verify(city * cities);
  38.  
  39. void cities_output (city * cities, int size, int sum);
  40.  
  41. void shuffle_one (edge ** edges, int min, int max);
  42.  
  43. int * access_table (int i, int j);
  44.  
  45. int * cities_convert (city * input);
  46.  
  47. // command line arguments example
  48. // tsp 1000 tsp_exp.txt
  49. // 0 1 2
  50.  
  51. int main (int argc, const char * argv[]) {
  52. time_t start_time, stop_time;
  53.  
  54. start_time = stop_time = clock();
  55.  
  56. if (argc < 3) {
  57. printf("Usage: tsp [number of cities] [matrix file]\n");
  58. return 1;
  59. }
  60.  
  61. FILE * file_in = 0;
  62.  
  63. srand((unsigned int)time(0));
  64.  
  65. n_cities = atoi(argv[1]);
  66.  
  67. if (n_cities < 1) {
  68. printf("FILE READ ERROR!\n");
  69. return 2;
  70. }
  71.  
  72. file_in = fopen(argv[2], "r");
  73.  
  74. if (!file_in) {
  75. printf("FILE NOT FOUND!\n");
  76. return 3;
  77. }
  78.  
  79. table = (int*)malloc(n_cities * n_cities * sizeof(int));
  80.  
  81. edge ** edges = (edge**)malloc((n_cities * (n_cities - 1) >> 1) * sizeof(edge*));
  82.  
  83. int r = 0;
  84.  
  85. for (int i = 0; i < n_cities; i++) {
  86. for (int j = 0; j < n_cities; j++) {
  87. if(fscanf(file_in, "%u%*[,]", access_table(i, j))) {
  88. if (i < j) {
  89. edges[r] = (edge*)malloc(sizeof(edge));
  90. edges[r]->from = i;
  91. edges[r]->to = j;
  92. edges[r]->cost = *access_table(i, j);
  93. r++;
  94. }
  95. } else {
  96. printf("READ ERROR!\n");
  97. return 4;
  98. }
  99. }
  100. }
  101.  
  102. fclose(file_in);
  103.  
  104. city * cities = (city*)malloc(n_cities * sizeof(city));
  105.  
  106. printf("Sorting edges...");
  107. time_t qst = clock();
  108. quicksort(edges, 0, r-1);
  109. stop_time = clock() - qst;
  110.  
  111. printf(" done! (%.3f s)\n", stop_time / (double)CLOCKS_PER_SEC);
  112.  
  113. int sum = INT_MAX;
  114.  
  115. do {
  116. int group_count, sum_tmp, lowest_cost, connection_count, index, first;
  117.  
  118. for (int k = 0; k < n_cities; k++) {
  119. city_init(&cities[k]);
  120. }
  121.  
  122. index = first = connection_count = sum_tmp = 0;
  123.  
  124. lowest_cost = edges[0]->cost;
  125.  
  126. group_count = 1;
  127.  
  128. while(connection_count < n_cities - 1) {
  129.  
  130. int i, j;
  131.  
  132. i = edges[index]->from;
  133. j = edges[index]->to;
  134.  
  135. if(*access_table(i, j) > lowest_cost) {
  136. shuffle_one(edges, first, index - 1);
  137. lowest_cost = *access_table(i, j);
  138. first = index;
  139. }
  140.  
  141. if (++index > r) index = 0;
  142.  
  143. // check if cities have free connections
  144. if (city_open(&cities[i]) && city_open(&cities[j])) {
  145. // check group status of cities
  146. // true if both cities belong to no group or one city belongs to a group
  147. // false if both cities belong to the same group
  148. if(cities[i].group == -1 || cities[j].group == -1 || cities[i].group != cities[j].group) {
  149.  
  150. city_connect(&cities[i], j);
  151. city_connect(&cities[j], i);
  152.  
  153. sum_tmp += *access_table(i,j);
  154. connection_count++;
  155.  
  156.  
  157. if (cities[i].group != cities[j].group && cities[i].group != -1 && cities[j].group != -1) {
  158. int i_prev, i_this, i_next;
  159.  
  160. i_this = i;
  161. i_next = j;
  162.  
  163. do {
  164. cities[i_next].group = cities[i].group;
  165.  
  166. i_prev = i_this;
  167. i_this = i_next;
  168. i_next = cities[i_this].c1 != i_prev ? cities[i_this].c1 : cities[i_this].c2;
  169. } while ( i_next != -1);
  170.  
  171. } else if (cities[i].group != -1) {
  172. cities[j].group = cities[i].group;
  173. //check if city j belongs to a group, if so add city i to the same group
  174. } else if (cities[j].group != -1) {
  175. cities[i].group = cities[j].group;
  176. //check if cities belongs to different groups, if so add all connected cities to group of city i
  177. } else {
  178. cities[i].group = cities[j].group = group_count;
  179. group_count++;
  180. }
  181. }
  182. }
  183. }
  184.  
  185. int lastindex = -1;
  186. int i = 0;
  187.  
  188. while (connection_count != n_cities) {
  189.  
  190. if (city_open(&cities[i])) {
  191. if (lastindex == -1) {
  192. lastindex = i;
  193. } else {
  194. city_connect(&cities[i], lastindex);
  195. city_connect(&cities[lastindex], i);
  196. sum_tmp += *access_table(i, lastindex);
  197. connection_count++;
  198. }
  199. }
  200. i++;
  201. }
  202.  
  203. // int opt = 3;
  204. // for(int n = 2; n < opt; n++) {
  205. // int k = n;
  206. //
  207. // int * p = malloc(n * sizeof(int));
  208. //
  209. // for(int t = 0; t < n; t++) {
  210. // p[n] = 0;
  211. // }
  212. //
  213. // while( k ) {
  214. // for (int j = 0; j < n; n++) {
  215. //
  216. // ;
  217. // }
  218. // k--;
  219. // ;
  220. // }
  221. //
  222. // int * cities_ordered = cities_convert(cities);
  223. //
  224. // int x, y, new_cost;
  225. // new_cost = sum_tmp;
  226. //
  227. // for (int i = 0; i < n_cities; i++) {
  228. // for (int j = 0; j < n_cities; j++) {
  229. // if (i >= j) {
  230. // x = y = n_cities; // NDBG
  231. // }
  232. // }
  233. //
  234. //
  235. //
  236. // for every permutation of n elements from opt elements
  237. // in other words n kanter ska swappas
  238. // för det finns n! / (n! * opt!) möjligheter
  239. // där varje möjlighet innehåller n kanter
  240. //
  241. // för varje möjlighet kan
  242. // finns det n^2 kombinationer
  243. // varav vissa återkommer
  244. //
  245. // ;
  246. // }
  247.  
  248.  
  249. if (sum_tmp < sum && cities_verify(cities)) {
  250. sum = sum_tmp;
  251.  
  252. printf("(new result: %d, %.3f s)\n", sum, stop_time / (double)CLOCKS_PER_SEC);
  253.  
  254. cities_output(cities, n_cities, sum);
  255. }
  256.  
  257. stop_time = clock() - start_time;
  258. } while(clock() - start_time < TIME * CLOCKS_PER_SEC);
  259.  
  260. printf("Final result: %d (%.3f s)\n", sum, stop_time / (double)CLOCKS_PER_SEC);
  261.  
  262. return 0;
  263. }
  264.  
  265. void swap (edge ** e, edge ** f) {
  266. edge * t;
  267.  
  268. t = *e;
  269.  
  270. *e = *f;
  271.  
  272. *f = t;
  273. }
  274.  
  275. int part (edge ** edges, int low, int high) {
  276. int i = low - 1;
  277.  
  278. for (int j = low; j <= high - 1; j++) {
  279. if(compare(edges[j], edges[high])) {
  280. swap(&edges[++i], &edges[j]);
  281. }
  282. }
  283. swap(&edges[i + 1], &edges[high]);
  284. return (i + 1);
  285. }
  286.  
  287. void quicksort (edge ** edges, int low, int high) {
  288. if (low < high) {
  289. int p = part(edges, low, high);
  290.  
  291. quicksort(edges, low, p - 1);
  292. quicksort(edges, p + 1, high);
  293. }
  294. }
  295.  
  296. int compare (edge * e, edge * f) {
  297. return e->cost <= f->cost;
  298. }
  299.  
  300. void city_init(city * c) {
  301. c->c1 = c->c2 = c->group = -1;
  302. }
  303.  
  304. int city_open(city * c) {
  305. int count = 2;
  306. if (c->c1 != -1)
  307. count--;
  308. if (c->c2 != -1)
  309. count--;
  310.  
  311. return count;
  312. }
  313.  
  314. void city_connect(city * c, int i) {
  315. if (c->c1 == -1) c->c1 = i;
  316. else if (c->c2 == -1) c->c2 = i;
  317. }
  318.  
  319. int cities_verify(city * cities) {
  320.  
  321. int * city_visited = (int*)malloc(n_cities * sizeof(int));
  322.  
  323. for (int i = 0; i < n_cities; i++) city_visited[i] = 0;
  324.  
  325. int count, i_prev, i_this, i_next;
  326.  
  327. i_this = count = 0;
  328. i_next = cities[i_this].c1;
  329.  
  330. while (i_next != -1 && count < n_cities) {
  331. if (!city_visited[i_this]) {
  332. city_visited[i_this]++;
  333. count++;
  334. } else break;
  335.  
  336. i_prev = i_this;
  337. i_this = i_next;
  338. i_next = cities[i_this].c1 != i_prev ? cities[i_this].c1 : cities[i_this].c2;
  339. }
  340.  
  341. free(city_visited);
  342.  
  343. return !i_this && count == n_cities ;
  344. }
  345.  
  346. void cities_output (city * cities, int size, int sum) {
  347. char filename[0xC0];
  348. // sprintf(filename,"o_%d.txt",sum);
  349. sprintf(filename,"output.txt");
  350. FILE * file_out = fopen(filename, "w");
  351.  
  352. int count, i_prev, i_this, i_next;
  353.  
  354. i_this = count = 0;
  355. i_next = cities[i_this].c1;
  356.  
  357. while (i_next != -1 && count++ <= size) {
  358.  
  359. fprintf(file_out,"%d\n",i_this+1);
  360.  
  361. i_prev = i_this;
  362. i_this = i_next;
  363. i_next = cities[i_this].c1 != i_prev ? cities[i_this].c1 : cities[i_this].c2;
  364. }
  365.  
  366. fclose(file_out);
  367. }
  368.  
  369. void shuffle_one (edge ** edges, int min, int max) {
  370. int r, size;
  371.  
  372. size = max - min;
  373.  
  374. if (size) {
  375. r = size > 1 ? min + (rand() % size) + 1 : max;
  376. swap(&edges[min], &edges[r]);
  377. }
  378. }
  379.  
  380. int * access_table (int i, int j) {
  381. int offset = i * n_cities + j;
  382.  
  383. return &table[offset];
  384. }
  385.  
  386. // void cities_convert(city * input, int * output) {write to output}
  387. // void cities_convert(city * input, int * output) {malloc, modify pointer}
  388. // int * cities_convert(city * input) { malloc ... }
  389.  
  390. int * cities_convert (city * input) {
  391. int * output = (int*)malloc(n_cities*sizeof(int));
  392.  
  393. for (int i = 0; i < n_cities ; i++)
  394. output[i] = 0;
  395.  
  396. return output;
  397. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement