Emania

pal hw03

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