Guest User

Untitled

a guest
Dec 6th, 2014
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.17 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. #define VSIZE 6
  5.  
  6. int minimum(int* find_D, int cnt, int* min_ind ){
  7.     int mini=find_D[0];
  8.     for(int i=0; i<cnt; i++){
  9.         if(mini>find_D[i]){
  10.             mini=find_D[i];
  11.             *min_ind=i;
  12.         }
  13.     }
  14.     return mini;
  15. }
  16.  
  17. void travel(int n, int W[VSIZE][VSIZE], int **P){
  18.     int j, cnt;
  19.     int *find_D = (int*)malloc(sizeof(int)*n);
  20.     int *find_P = (int*)malloc(sizeof(int)*n);
  21.     int set = 0;
  22.     int minLength = 0;
  23.     int min_ind = 0;
  24.     int max = 1 << n;
  25.  
  26.     int **D;
  27.     D = (int**)malloc(sizeof(int*)*n);
  28.     for(int i=0; i<n; i++)
  29.         D[i] = (int*)malloc(sizeof(int)*max);
  30.  
  31.     // 부분집합 만들기
  32.     int** sub;
  33.     sub = (int**)malloc(sizeof(int*)*n);
  34.     for(int i=0; i<n; i++)
  35.         sub[i] = (int*)malloc(sizeof(int)*max);
  36.  
  37.     int* num=(int*)malloc(sizeof(int)*n);
  38.     for(int i=0; i<n; i++)
  39.         num[i]=0;
  40.  
  41.     for(int i=1; i<max; i++){
  42.         if(i%2==1)          continue;   // V1을 포함하는 경우
  43.         int temp=i/2;
  44.         int c=0;
  45.         while(1){
  46.             if(temp==0)     break;
  47.             if(temp%2==1)   c++;
  48.             temp = temp/2;
  49.         }
  50.         sub[c-1][num[c-1]]=i;
  51.         num[c-1]++;
  52.     }
  53.  
  54.     // A가 공집합인 경우
  55.     for(int i = 1; i < n; i++ )
  56.         D[i][0] = W[i][0];
  57.  
  58.     for(int k = 1; k <= n - 2; k++ ){   // k=집합 A에 포함되는 정점의 개수
  59.         for(int l=0; l<num[k-1]; l++){
  60.             set=sub[k-1][l];            // 부분집합 저장
  61.             for(int i=1; i<n; i++ ){
  62.                 if( (set & (1<<i))>0 )  // 집합에 포함되는 Vi은 실행하지 않는다
  63.                     continue;
  64.                 for(j=1, cnt=0; cnt<k; j++ ){
  65.                     if( (set & (1<<j))>0 ){ // set의 원소 Vj
  66.                         find_D[cnt] = W[i][j] + D[j][set^(1<<j)];
  67.                         find_P[cnt] = j;
  68.                         cnt++;
  69.                     }
  70.                 }
  71.                 D[i][set] = minimum(find_D, cnt, &min_ind);
  72.                 P[i][set] = find_P[min_ind];
  73.             }
  74.         }
  75.     }
  76.  
  77.     // V1을 제외한 모든 정점을 포함하는 집합
  78.     set=(max-1)-1;
  79.  
  80.     for(int i=1, cnt=0; cnt<n-1; i++ ){
  81.         if( (set & (1<<i)) > 0 ){
  82.             find_D[cnt] = W[0][i] + D[i][set^(1<<i)];
  83.             find_P[cnt] = i;
  84.             cnt++;
  85.         }
  86.     }
  87.     D[0][set] = minimum(find_D, cnt, &min_ind);
  88.     P[0][set] = find_P[min_ind];
  89.     minLength = D[0][set];
  90.  
  91.  
  92.     //메모리해제
  93.     free(find_D);
  94.     free(find_P);
  95.     free(num);
  96.     for(int i=0; i<n; i++)
  97.         free(sub[i]);
  98.     free(sub);
  99.     for(int i=0; i<n; i++)
  100.         free(D[i]);
  101.     free(D);
  102. }
  103.  
  104. int main(){
  105.     int W[VSIZE][VSIZE];
  106.     int r1, r2;
  107.     int n = VSIZE;
  108.     int max = 1<<n;
  109.  
  110.     int **P=(int**)malloc(sizeof(int*)*n);
  111.     for(int i=0; i<n; i++)
  112.         P[i]=(int*)malloc(sizeof(int)*max);
  113.  
  114.     int M[VSIZE][VSIZE]={
  115.         {   0,      556600, 595600, 933100, 781400, 2011700 },  // 한국
  116.         {   719000, 0,      92426,  849764, 968538, 1562927 },  // 영국
  117.         {   687477, 114695, 0,      743700, 1281868,1562927 },  // 스위스
  118.         {   606631, 456119, 458768, 0,      648926, 2508514 },  // 남아공
  119.         {   764054, 751741, 667857, 966518, 0,      842861  },  // 워싱턴
  120.         {   1867523,1788451,1349493,1223562,1013584,0       }   //파라과이
  121.     };
  122.     int T[VSIZE][VSIZE]={
  123.         {0,     2195,   975,    2470,   992,    1685},  // 한국
  124.         {1650,  0,      100,    910,    660,    1540},  // 영국
  125.         {995,   110,    0,      1085,   1568,   1540},  // 스위스
  126.         {1200,  1145,   1430,   0,      2700,   2570},  // 남아공
  127.         {995,   645,    1450,   2338,   0,      732},   // 워싱턴
  128.         {2340,  1390,   2345,   3020,   1184,   0   }   //파라과이
  129.     };
  130.  
  131.     while(1){
  132.         printf("비용: ");
  133.         scanf("%d", &r1);
  134.         printf("시간: ");
  135.         scanf("%d", &r2);
  136.         if(r1+r2==100)
  137.             break;
  138.         printf("잘못된 값입니다.\n");
  139.     }
  140.  
  141.     // 최대값 찾기
  142.     float max_m=0;
  143.     float max_t=0;
  144.     for(int i=0; i<n; i++){
  145.         for(int j=0; j<n; j++){
  146.             if(max_m<M[i][j])   max_m=M[i][j];
  147.             if(max_t<T[i][j])   max_t=T[i][j];
  148.         }
  149.     }
  150.     // % 변환
  151.     for(int i=0; i<n; i++){
  152.         for(int j=0; j<n; j++){
  153.             M[i][j]=M[i][j]/max_m*100;
  154.             T[i][j]=T[i][j]/max_t*100;
  155.         }
  156.     }
  157.     // 각각의 비율이 적용된 배열 W 저장
  158.     for(int i=0; i<n; i++)
  159.         for(int j=0; j<n; j++)
  160.             W[i][j]=r1*M[i][j]+r2*T[i][j];
  161.  
  162.     // 외판원 함수 실행
  163.     travel(n, W, P);
  164.  
  165.     int A = max-1;
  166.     int path[VSIZE+1];
  167.     int temp = 0;
  168.  
  169.     // 경로 저장
  170.     path[0]=0;
  171.     path[n]=0;
  172.     for(int i=1; i<n; i++){
  173.         A = A-(1<<temp);
  174.         temp = P[temp][A];
  175.         path[i] = temp;
  176.     }
  177.  
  178.     // 경로 출력
  179.     printf("Path : [ ");
  180.     for(int i=0; i<n+1; i++)
  181.         printf("v%d ", path[i]+1);
  182.     printf("]\n");
  183.  
  184.     // 동적할당 해제
  185.     for(int i=0; i<n; i++)
  186.         free(P[i]);
  187.     free(P);
  188.  
  189.     return 0;
  190. }
Advertisement
Add Comment
Please, Sign In to add comment