Emania

pal03 working

Nov 18th, 2016
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.27 KB | None | 0 0
  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6.  
  7. /*
  8.  * File:   main.c
  9.  * Author: Jan
  10.  *
  11.  * Created on November 18, 2016, 3:15 PM
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <limits.h>
  17.  
  18. #define CONSOLE 0
  19.  
  20. struct Edge {
  21.     int start;
  22.     int end;
  23.     int cost;
  24.     int component;
  25. };
  26.  
  27. int recursive(int n, int k);
  28. int print_arr(int arr[], int k);
  29. int my_compare(struct Edge * e1, struct Edge * e2);
  30.  
  31. struct Edge * edges_ground;
  32. struct Edge * edges_bet;
  33.  
  34. int * edges_ground_start;
  35. int * edges_ground_end;
  36. int * edges_ground_cost;
  37. int * edges_bet_start;
  38. int * edges_bet_end;
  39. int * edges_bet_cost;
  40.  
  41. int * components;
  42. int * used_vertices;
  43. int edges_ground_num = 0;
  44. int edges_bet_num = 0;
  45. int v_num, e_num, bet_num, bet_total, border;
  46. int best_cost = INT_MAX;
  47.  
  48.  
  49. int main(int argc, char** argv) {
  50.     int i, j, start_tmp, end_tmp, cost_tmp;
  51.    
  52.    
  53.    
  54.    
  55. #if CONSOLE
  56.     /*READ FROM INPUT*/
  57.    
  58.     scanf("%d", &v_num);
  59.     scanf("%d", &e_num);
  60.    
  61.     int * data = (int *) malloc(e_num * 3 * sizeof(int));  
  62.     stack =  (int *) malloc(v_num * sizeof(int));
  63.    
  64.     for(i = 0; i < e_num*3; i++){
  65.         scanf("%d", data + i);
  66.     }
  67.    
  68. #else
  69.     /*
  70.         1 - 30
  71.         2 - 21
  72.         3 - 59
  73.         4 - 270
  74.         5 - 126
  75.         6 - 87653
  76.         7 - 3254
  77.         8 - 16962
  78.         9 - 6633
  79.         10 - 522203
  80.         */      
  81.    
  82.     /*READ FROM FILE*/
  83.     FILE* file;
  84.     file = fopen("./data/pub09.in", "r");
  85.     fscanf(file, "%d", &e_num);
  86.     fscanf(file, "%d", &v_num);
  87.     fscanf(file, "%d", &border);
  88.     fscanf(file, "%d", &bet_num);
  89.    
  90.     printf("total number of edges        = %d\n", e_num);
  91.     printf("total number of vertices     = %d\n", v_num);
  92.     printf("total number of border edges = %d\n", bet_num);
  93.     printf("bet index                    = %d\n", border);
  94.    
  95. //    int edges_ground_num = 0;
  96. //    int edges_bet_num = 0;
  97.    
  98.     edges_ground = (struct Edge *) malloc(e_num * sizeof(struct Edge));
  99.     edges_bet = (struct Edge *) malloc(e_num * sizeof(struct Edge));
  100.    
  101.     components = (int *) malloc(v_num * sizeof(int));
  102.     used_vertices = (int *) malloc(v_num * sizeof(int));
  103. //    components = (int *) calloc(v_num, sizeof(int));
  104. //    used_vertices = (int *) calloc(v_num, sizeof(int));
  105.    
  106.    
  107.     /* read file and split the edges */
  108.     for(i = 0; i < e_num; i++){
  109.         fscanf(file, "%d", &start_tmp);
  110.         fscanf(file, "%d", &end_tmp);
  111.         fscanf(file, "%d", &cost_tmp);
  112.         if((start_tmp <= border && end_tmp <= border) || (start_tmp > border && end_tmp > border)){
  113.             struct Edge * e = &edges_ground[edges_ground_num];
  114.             e->start = start_tmp;
  115.             e->end = end_tmp;
  116.             e->cost = cost_tmp;
  117.             edges_ground_num++;
  118.         } else {
  119.             struct Edge * e = &edges_bet[edges_bet_num];
  120.             e->start = start_tmp;
  121.             e->end = end_tmp;
  122.             e->cost = cost_tmp;
  123.             edges_bet_num++;
  124.         }
  125.     }
  126.    
  127.     fclose(file);
  128.    
  129.    
  130. #endif
  131.    
  132.     qsort(edges_ground, edges_ground_num, sizeof(struct Edge), my_compare);
  133.    
  134.    
  135.     edges_ground_start = (int *) malloc(edges_ground_num * sizeof(int));
  136.     edges_ground_end = (int *) malloc(edges_ground_num * sizeof(int));
  137.     edges_ground_cost = (int *) malloc(edges_ground_num * sizeof(int));
  138.     edges_bet_start = (int *) malloc(edges_bet_num * sizeof(int));
  139.     edges_bet_end = (int *) malloc(edges_bet_num * sizeof(int));
  140.     edges_bet_cost = (int *) malloc(edges_bet_num * sizeof(int));
  141.    
  142.    
  143.    
  144.     /* read file and split the edges */
  145.     for(i = 0; i < edges_bet_num; i++){
  146.         edges_bet_start[i] = edges_bet[i].start;
  147.         edges_bet_end[i] = edges_bet[i].end;
  148.         edges_bet_cost[i] = edges_bet[i].cost;
  149.     }
  150.     for(i = 0; i < edges_ground_num; i++){
  151.         edges_ground_start[i] = edges_ground[i].start;
  152.         edges_ground_end[i] = edges_ground[i].end;
  153.         edges_ground_cost[i] = edges_ground[i].cost;
  154.     }
  155.    
  156.    
  157. //    for(i = 0; i < edges_bet_num; i++){
  158. ////        printf("edge between [%d, %d, %d]\n", edges_bet_start[i], edges_bet_end[i], edges_bet_cost[i]);
  159. //    }
  160. //    for(i = 0; i < edges_ground_num; i++){
  161. //        printf("edge between [%d, %d, %d]\n", edges_ground_start[i], edges_ground_end[i], edges_ground_cost[i]);
  162. //    }
  163.    
  164. //    printf("starting recursive\n");
  165.     recursive(edges_bet_num, bet_num);
  166.    
  167.    
  168.     printf("%d", best_cost);
  169.     return (EXIT_SUCCESS);
  170. }
  171.  
  172. int cruscal(int arr[]){
  173. //    printf("STARTING CRUSCAL\n");
  174. //    print_arr(arr, bet_num);
  175.     int i, j, start, end, c_start, c_end;
  176.     int cost_total = 0, used_edges = 0, starting_idx = 0, starting = 1, used_vertices_num = 0;
  177.     int component_num = 0;
  178.     int edge_idx = 0;
  179.     for(i = 0; i < v_num; i++) {components[i] = -3;}
  180.     for(i = 0; i < v_num; i++) {used_vertices[i] = -2;}
  181.    
  182. //    printf("edges_ground_num %d\n", edges_ground_num);
  183.    
  184.     struct Edge * edge;
  185.     while(used_edges < v_num - 1){
  186. //        printf("--%d, used edges %d / %d, st idx %d, st %d, c %d -- \n", edge_idx, used_edges, edges_ground_num, starting_idx, starting, cost_total);
  187. //        print_arr(components, v_num);
  188. //        print_arr(used_vertices, v_num);
  189.        
  190.         if(starting_idx >= bet_num) starting = 0;
  191.         if(starting){
  192. //            printf("starting true\n");
  193. //                e = betEdgesPossible.get(arr[starting_idx]);
  194.             edge = &edges_bet[arr[starting_idx]];  // check
  195.             starting_idx++;
  196.         } else{
  197.             if(edge_idx == edges_ground_num) {
  198. //                printf("NOT FEASIBLE SOLUTION");
  199.                 return INT_MAX;
  200.             }
  201.             edge = &edges_ground[edge_idx];   // check
  202.             edge_idx++;
  203.         }
  204.         start = edge->start;
  205.         end = edge->end;
  206. //        printf("chosen [%d, %d, %d], %p\n", start, end, edge->cost, edge);
  207.         c_start = (components[start] >= 0) ? 1 : 0;
  208.         c_end = (components[end] >= 0) ? 1 : 0;
  209. //        printf("[%d, %d]\n", start, end);
  210.        
  211.         if(c_start && c_end){ // if edges are both in existing components
  212.             if(components[start] == components[end]){
  213.                 if(starting){
  214.                     cost_total += edge->cost;
  215.                 }
  216. //                printf("skipping\n");
  217.                 continue;
  218.             } else{
  219.                 int end_comp = components[end];
  220.                 int start_comp = components[start];
  221.                 int idx;
  222. //                printf("adding edge [%d %d %d] connecting %d and %d\n", start, end, edge->cost, start_comp, end_comp);
  223.                 for(j = 0; j < used_vertices_num; j++){
  224.                     idx = used_vertices[j];
  225.                     if(components[idx] == end_comp) components[idx] = start_comp;
  226.                 }
  227.                 used_edges++;
  228.             }
  229.         } else if(c_start && !c_end){
  230. //            printf("adding edge [%d %d %d] 1sided1\n", start, end, edge->cost);
  231.             components[end] = components[start];
  232.             used_edges++;
  233.             used_vertices[used_vertices_num] = end;
  234.             used_vertices_num++;
  235.         } else if(!c_start && c_end){
  236. //            printf("adding edge [%d %d %d] 1sided2\n", start, end, edge->cost);
  237. //            printf("x\n");
  238. //            printf("x4\n");
  239. //            printf("component start %d end %d\n", components[start], components[end]);
  240.             int tmp = components[end];
  241.             components[start] = tmp;
  242.             used_edges++;
  243.             used_vertices[used_vertices_num] = start;
  244.             used_vertices_num++;
  245.         } else{
  246. //            printf("adding edge [%d %d %d] alone\n", start, end, edge->cost);
  247.            
  248.             components[start] = component_num;
  249.             components[end] = component_num;
  250.  
  251.             used_edges++;
  252.             component_num++;
  253.             used_vertices[used_vertices_num] = start;
  254.             used_vertices[used_vertices_num+1] = end;
  255.             used_vertices_num += 2;
  256.         }
  257.         cost_total += edge->cost;
  258.     }
  259.        
  260.     for(i = 0; i < e_num; i++) {used_vertices[i] = -1;}
  261.     //clear chosen_vertices
  262. //    printf("cost %d\n", cost_total);
  263.     return cost_total;
  264. }
  265.  
  266.  
  267.  
  268. int recursive(int n, int k){
  269.     int arr[k];
  270.     int index = 0;      
  271.     int i = 0;
  272.  
  273.     while(index >= 0){
  274.         if(i > (n + (index - k))){
  275.             index--;
  276.             if(index <= 0){
  277.                 i = arr[0]+1;
  278.             } else {
  279.                 i = arr[index]+1;
  280.             }
  281.         } else{
  282.             arr[index] = i;
  283.             if(index == k-1){
  284.                 int cost = cruscal(arr);
  285.                 best_cost = (cost < best_cost) ? cost : best_cost;
  286.                 i++;                
  287.             }
  288.             else{
  289.                 i = arr[index]+1;
  290.                 index++;                                        
  291.             }
  292.         }          
  293.     }
  294. }
  295.  
  296. int print_arr(int arr[], int k){
  297.     int i;
  298.     printf("array: [");
  299.     for(i = 0; i < k; i++){
  300.         printf("%d ", arr[i]);
  301.     }printf("]\n");
  302. }
  303.  
  304. int my_compare(struct Edge * e1, struct Edge * e2){
  305.     return e1->cost - e2->cost;
  306. }
Advertisement
Add Comment
Please, Sign In to add comment