tsp42.gms : 서브투어 제거 기능이 있는 TSP 메가 슬롯

설명

이 모델은 간단한 알고리즘을 사용하여 대칭 TSP를 해결합니다.
이전에서 발견된 하위 투어를 제외하기 위해 컷을 추가합니다.
메가 슬롯. 데이터 세트는 TSPLIB의 dantzig42입니다.

대형 모델 유형 :MIP


카테고리 : 메가 슬롯 모델 라이브러리


메인 파일 : 메가 슬롯.gms

$title 서브투어 제거 기능이 있는 TSP 메가 슬롯(TSP42,SEQ=213)

$onText
이 모델은 간단한 알고리즘을 사용하여 대칭 TSP를 해결합니다.
이전에서 발견된 하위 투어를 제외하기 위해 컷을 추가합니다.
메가 슬롯. 데이터 세트는 TSPLIB의 dantzig42입니다.

Dantzig, GB, Fulkerson 및 Johnson, 대규모 메가 슬롯
여행하는 세일즈맨 문제. 운영 연구 2 (1954), 393-410.

최적의 메가 슬롯: 699

키워드: 혼합 정수 선형 계획법, 여행하는 외판원 문제, 반복
          서브투어 제거, 컷 생성
$offText

$eolCom //

옵션 optCr = 0, limRow = 0, limCol = 0, solPrint = off;

내가 '도시'로 설정
      / c1 '맨체스터, NH', c2 '몬트필리어, 버몬트', c3 '디트로이트, 미시간'
        c4 '오하이오주 클리블랜드', c5 'W.Va.찰스턴', c6 '켄터키주 루이빌'
        c7 '인디애나주 인디애나폴리스', c8 '일리노이주 시카고', c9 '위스콘신주 밀워키'
        c10 '미네소타주 미니애폴리스', c11 '피에르, S.D.', c12 '비스마르크, N.D.'
        c13 '몬트주 헬레나', c14 '워싱턴주 시애틀', c15 '오리건주 포틀랜드'
        c16 '아이다호주 보이시', c17 '유타주 솔트레이크시티', c18 '네바다주 카슨시티'
        c19 '캘리포니아주 로스앤젤레스', c20 '애리조나주 피닉스', c21 '뉴멕시코주 산타페'
        c22 '콜로나주 덴버', c23 '와이오밍주 샤이엔', c24 '네브라스카주 오마하'
        c25 '아이오와주 디모인', c26 '미주리주 캔자스시티', c27 '캔스주 토피카'
        c28 '오클라호마주 오클라호마시티', c29 '텍사스주 댈러스', c30 '아칸소주 리틀록'
        c31 '테네시주 멤피스', c32 '미시시피주 잭슨', c33 '루이지애나주 뉴올리언스'
        c34 '앨라배마주 버밍엄', c35 '조지아주 애틀랜타', c36 '플로리다주 잭슨빌'
        c37 '컬럼비아, S.C.', c38 '롤리, N.C.', c39 '리치먼드, 버지니아'
        c40 '워싱턴 D.C.', c41 '매사추세츠주 보스턴', c42 '나주 포틀랜드'      /;

별칭(i,j,k);

테이블 d(i,j)
        c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21
   c2 8
   c3 39 45
   c4 37 47 9
   c5 50 49 21 15
   c6 61 62 21 20 17
   c7 58 60 16 17 18 6
   c8 59 60 15 20 26 17 10
   c9 62 66 20 25 31 22 15 5
   c10 81 81 40 44 50 41 35 24 20
   c11 103 107 62 67 72 63 57 46 41 23
   c12 108 117 66 71 77 68 61 51 46 26 11
   c13 145 149 104 108 114 106 99 88 84 63 49 40
   c14 181 185 140 144 150 142 135 124 120 99 85 76 35
   c15 187 191 146 150 156 142 137 130 125 105 90 81 41 10
   c16 161 170 120 124 130 115 110 104 105 90 72 62 34 31 27
   c17 142 146 101 104 111 97 91 85 86 75 51 59 29 53 48 21
   c18 174 178 133 138 143 129 123 117 118 107 83 84 54 46 35 26 31
   c19 185 186 142 143 140 130 126 124 128 118 93 101 72 69 58 58 43 26
   c20 164 165 120 123 124 106 106 105 110 104 86 97 71 93 82 62 42 45 22
   c21 137 139 94 96 94 80 78 77 84 77 56 64 65 90 87 58 36 68 50 30
   c22 117 122 77 80 83 68 62 60 61 50 34 42 49 82 77 60 30 62 70 49 21
   c23 114 118 73 78 84 69 63 57 59 48 28 36 43 77 72 45 27 59 69 55 27
   c24 85 89 44 48 53 41 34 28 29 22 23 35 69 105 102 74 56 88 99 81 54
   c25 77 80 36 40 46 34 27 19 21 14 29 40 77 114 111 84 64 96 107 87 60
   c26 87 89 44 46 46 30 28 29 32 27 36 47 78 116 112 84 66 98 95 75 47
   c27 91 93 48 50 48 34 32 33 36 30 34 45 77 115 110 83 63 97 91 72 44
   c28 105 106 62 63 64 47 46 49 54 48 46 59 85 119 115 88 66 98 79 59 31
   c29 111 113 69 71 66 51 53 56 61 57 59 71 96 130 126 98 75 98 85 62 38
   c30 91 92 50 51 46 30 34 38 43 49 60 71 103 141 136 109 90 115 99 81 53
   c31 83 85 42 43 38 22 26 32 36 51 63 75 106 142 140 112 93 126 108 88 60
   c32 89 91 55 55 50 34 39 44 49 63 76 87 120 155 150 123 100 123 109 86 62
   c33 95 97 64 63 56 42 49 56 60 75 86 97 126 160 155 128 104 128 113 90 67
   c34 74 81 44 43 35 23 30 39 44 62 78 89 121 159 155 127 108 136 124 101 75
   c35 67 69 42 41 31 25 32 41 46 64 83 90 130 164 160 133 114 146 134 111 85
   c36 74 76 61 60 42 44 51 60 66 83 102 110 147 185 179 155 133 159 146 122 98
   c37 57 59 46 41 25 30 36 47 52 71 93 98 136 172 172 148 126 158 147 124 121
   c38 45 46 41 34 20 34 38 48 53 73 96 99 137 176 178 151 131 163 159 135 108
   c39 35 37 35 26 18 34 36 46 51 70 93 97 134 171 176 151 129 161 163 139 118
   c40 29 33 30 21 18 35 33 40 45 65 87 91 117 166 171 144 125 157 156 139 113
   c41 3 11 41 37 47 57 55 58 63 83 105 109 147 186 188 164 144 176 182 161 134
   c42 5 12 55 41 53 64 61 61 66 84 111 113 150 186 192 166 147 180 188 167 140

   + c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c35 c36 c37 c38 c39 c40 c41
   c23 5
   c24 32 29
   c25 40 37 8
   c26 36 39 12 11
   c27 32 36 9 15 3
   c28 36 42 28 33 21 20
   c29 47 53 39 42 29 30 12
   c30 61 62 36 34 24 28 20 20
   c31 64 66 39 36 27 31 28 28 8
   c32 71 78 52 49 39 44 35 24 15 12
   c33 76 82 62 59 49 53 40 29 25 23 11
   c34 79 81 54 50 42 46 43 39 23 14 14 21
   c35 84 86 59 52 47 51 53 49 32 24 24 30 9
   c36 105 107 79 71 66 70 70 60 48 40 36 33 25 18
   c37 97 99 71 65 59 63 67 62 46 38 37 43 23 13 17
   c38 102 103 73 67 64 69 75 72 54 46 49 54 34 24 29 12
   c39 102 101 71 65 65 70 84 78 58 50 56 62 41 32 38 21 9
   c40 95 97 67 60 62 67 79 82 62 53 59 66 45 38 45 27 15 6
   c41 119 116 86 78 84 88 101 108 88 80 86 92 71 64 71 54 41 32 25
   c42 124 119 90 87 90 94 107 114 77 86 92 98 80 74 77 60 48 38 32 6;

lt(i,j) '하삼각형'을 설정합니다.
lt(i,j)$(ord(i) > ord(j)) = 예;

자유변수 z;
이진변수 x(i,j);

방정식 twomatch(i), obj;

obj.. z =e= sum(lt(i,j), d(i,j)*x(i,j));

twomatch(k).. sum(lt(i,k), x(i,k)) + sum(lt(k,j),x(k,j)) =e= 2;

모델 일치 / obj, twomatch /;

mip를 사용하여 z를 최소화하는 일치 문제를 해결합니다.

* 디스플레이 x.l;

* 동적 컷 수
세트
   주기 / 주기1*주기50 /
   t '투어' / t1*t100 /
   cutindex(cycle,t) '컷 주소 지정을 위한 동적 집합';

방정식 cut(cycle,t) '실제 컷';

매개변수
   cutcoeff(cycle,t,i,j) '컷의 계수'
   cutlength(cycle,t) '절단을 위한 rhs';

cut(cutindex).. sum((i,j), cutcoeff(cutindex,i,j)*x(i,j)) =l= cutlength(cutindex) - 1;

모델 tsp / obj, twomatch, cut /;

* 투어를 찾고 표시하는 데 사용됩니다.
세트
   s(i,j) '현재 메가 슬롯'
   투어(t,i,j) '하위 투어'
   tt(t) '현재 하위 투어'
   first(i,j) 'S의 첫 번째 (i,j)'
   reach(i,j) "(i,j)가 투어(tt)에 연결되었습니다.";

스칼라
   진행하다
   완료 / 0 /;

매개변수 결과;  // 보고용
results('relaxed','obj') = z.l;
results('relaxed','total equs') = match.numEqu;

매개변수 메가 슬롯(*,i,j);
Solutions('relaxed',i,j) = x.l(i,j);

루프(주기,
* 초기화
   투어(t,i,j) = 아니오;
   s(i,j) = 아니오;
   첫 번째(i,j) = 아니요;
   도달(i,j) = 아니오;
   완료 = 0;
   tt(t) = 아니요;
   tt(t)$(ord(t) = 1) = 1;         // 초기화 tt(1) = 예
   s(i,j) = 예$(x.l(i,j) > 0.5);  // 현재 메가 슬롯으로 초기화

   동안(완료되지 않음,
* 나머지 메가 슬롯에서 임의의 (i,j)를 선택합니다.
      첫 번째(i,j) = 아니요;
      loop((i,j)$(card(first) = 0), first(i,j) = s(i,j););
* 먼저 표시;

* 이것은 새로운 하위 투어의 시작입니다
      투어(tt,first) = 예;
      s(첫 번째) = 아니요;

      진행 = 1;
      동안(계속,
* find(i,j)가 투어(tt)에 연결됨
* tt에 대한 루프는 단지 구문일 뿐입니다. tt는 하나의 요소를 포함합니다.
         도달(i,j) = 아니오;
         루프((tt,k),
            도달(s(i,j))$tour(tt,k,j) = 예;
            도달(s(i,j))$tour(tt,i,k) = 예;
            도달(s(i,j))$tour(tt,k,i) = 예;
            도달(s(i,j))$tour(tt,j,k) = 예;
         );
* 디스플레이 투어, s, 도달;

* 도달 = 비어 있으면 while 루프를 중지할 수 있습니다.
         if(card(reach) = 0, 진행 = 0;);

* 현재 하위 투어에 추가
* tt에 대한 루프는 단지 구문일 뿐입니다. tt는 하나의 요소를 포함합니다.
         loop(tt,tour(tt,reach) = yes;);
         s(도달) = 아니오;
      );
* 디스플레이 투어;

* 남은 메가 슬롯이 없으면 완료됩니다.
      if(카드(들) = 0, 완료 = 1;);

* 새로운 하위 투어
      tt(t) = tt(t-1);   // 티 := 티 + 1
   );
   cutindex(cycle,t)$(sum(tour(t,i,j),1) > 0.5) = 예;

* 확인
   옵션 둘러보기:0:1:1;
* 디스플레이 투어;
   루프(컷인덱스(사이클,t),
      abort$(sum(tour(t,i,j),1) < 2.5) "1 또는 2점으로 하위 투어";
   );
   if(sum(cutindex(cycle,t),1) > 1.5,
      cutcoeff(cycle,tour(t,i,j))$cutindex(cycle,t) = 1;
      cutlength(cutindex(cycle,t)) = sum(tour(t,i,j),1);

      옵션 cutindex:0:1:1, cutcoeff:0:1:1;
* cutindex, cutcoeff, cutlength를 표시합니다.

      mip를 사용하여 z를 최소화하는 tsp를 해결합니다.
* 디스플레이 x.l;

      결과(사이클,'obj') = z.l;
      results(cycle,'cuts added') = sum(cutindex(cycle,t), 1);
      results(cycle,'total equs') = tsp.numEqu;
* 결과 표시;

      메가 슬롯(사이클,i,j) = x.l(i,j);
   그렇지 않으면
      "최적의 메가 슬롯을 찾았습니다!"를 표시합니다.
      완료 = 1;
      메가 슬롯('최적',i,j) = x.l(i,j);
   );
);

옵션 x:0:0:1;

x.l, 결과 표시;