cubesoln.gms : 3차원 삼차원 다중 솔루션

설명

흰색과 검은색 공은 1 대 1의 큐브로 배열되어야 합니다.
볼이 있는 라인의 수를 최소화하는 방식으로 셀
동일한 색상입니다. 이 예에서는 큐브의 길이가 3입니다.
3x3x3의 큐브에는 총 49개의 선이 존재합니다. 변경하면 27줄
단 하나의 좌표, 평면 내 대각선 18개, 대각선 4개
비행기를 타고 이동합니다.

이 모델 변형은 간단한 "이진 컷"을 사용하여 솔루션을 제거합니다.
따라서 후속 해결에서는 대체 솔루션이 생성됩니다. 이 작업은 루프에서 수행됩니다.
대체 솔루션을 생산합니다. 또한 Cplex의 솔루션 풀 기능을 사용하여
여러 솔루션을 생성합니다.

큐브 모델에는 많은 대칭이 있으므로 두 프로시저 모두 여러 개의 대칭을 찾습니다.
최적의 솔루션입니다.

소형 모델 유형 :MIP


카테고리 : 슬롯 머신 모델 라이브러리


메인 파일 : cubesoln.gms

$title 3차원 3차원 다중 솔루션(CUBESOLN,SEQ=371)

$onText
흰색 공과 검정색 공을 큐브 모양으로 배열합니다.
볼이 있는 라인의 수를 최소화하는 방식으로 셀
동일한 색상입니다. 이 예에서는 큐브의 길이가 3입니다.
3x3x3의 큐브에는 총 49개의 선이 존재합니다. 변경하면 27줄
단 하나의 좌표, 평면 내 대각선 18개, 대각선 4개
비행기를 타고 이동합니다.

이 모델 변형은 간단한 "이진 컷"을 사용하여 솔루션을 제거합니다.
따라서 후속 해결에서는 대체 솔루션이 생성됩니다. 이 작업은 루프에서 수행됩니다.
대체 솔루션을 생산합니다. 또한 Cplex의 솔루션 풀 기능을 사용하여
여러 솔루션을 생성합니다.

큐브 모델에는 많은 대칭이 있으므로 두 프로시저 모두 여러 개의 대칭을 찾습니다.
최적의 솔루션.

Williams, H P, 정수 프로그래밍 공식화 실험
문제. 수학적 프로그래밍 연구 2(1974).

키워드: 혼합 정수 선형 프로그래밍, 수학, CPLEX 솔루션 풀,
          수학 게임, 삼목, 틱택토, 컷 생성
$offText

세트
   s '라인 식별을 위한 도메인' / a, b, c, incr, decr /
   x(s) '좌표 라벨' / a, b, c /
   d(s) '방향' / 증가, 감소 /
   b '경계' / 낮음, 높음 /;

별칭 (x,y,z), (d,dp), (s,sp,spp);

ld(s,sp,spp) '라인 정의'를 설정합니다.
ld("incr",y,z) = 예;
ld(x,"incr",z) = 예;
ld(x,y,"incr") = 예;
ld("incr",d,z) = 예;
ld(x,"incr",d) = 예;
ld(d,y,"incr") = 예;
ld("incr",d,dp) = 예;
디스플레이 ld;

매개변수
   ls(b) '선 정의에 대한 부호' / low 1, high -1 /
   lr(b) '라인 정의를 위한 rhs' / 낮음 2, 높음 -1 /
   df(x,s) '선 정의 함수';

df(x,y) = ord(y) - ord(x);
df(x,"decr") = 1 + 카드(x) - 2*ord(x);
디스플레이 df;

변수
   core(x,y,z) '공 배치(흰색 0 검정색 1)'
   line(s,sp,spp) '라인 식별'
   num '동일한 색상의 줄 수';

바이너리 가변 코어;
양수 변수 라인;

방정식
   nbb '총 공 정의 수'
   ldef(s,sp,spp,b) '라인 정의'
   ndef '줄 수 정의';

넵..
   sum((x,y,z), core(x,y,z)) =e= 바닥(카드(x)**3/2);

ldef(s,sp,spp,b)$ld(s,sp,spp)..
   ls(b)*sum(x, 코어(x+df(x,s),x+df(x,sp),x+df(x,spp))) =l= 라인(s,sp,spp) + lr(b);

엔데프..
   num =e= sum((s,sp,spp)$ld(s,sp,spp), line(s,sp,spp));

모델 큐브 / 모두 /

옵션 optCr = 0, resLim = 10, limRow = 0, limCol = 0, solPrint = 자동;

mip를 사용하여 큐브 최소화 num을 해결합니다.

* 바이너리 솔루션을 차단하기 위한 컷
세트
   컷 / c1*c5 /
   cc(cuts) '동적 컷';

매개변수 sol '차단할 솔루션';

방정식 잘라내기(절단);

컷(cc).. 합계((x,y,z)$sol(cc,x,y,z), 코어(x,y,z))
       + 합계((x,y,z)$(sol(cc,x,y,z) = 0), 1 - 코어(x,y,z))
      =l= 카드(x)*카드(y)*카드(z) - 1;

모델 큐브컷/모두/;

루프(잘라내기,
   sol(컷,x,y,z) = round(core.l(x,y,z));
   sol(cuts,'','','obj') = num.l;
   cc(컷) = 예;
   mip를 사용하여 num을 최소화하는 CubeCut을 해결합니다.
   abort.noerror$(cubeCut.modelStat <> %modelStat.optimal% 및
                  CubeCut.modelStat <> %modelStat.integerSolution%) sol;
);
'사용 가능한 추가 솔루션' 표시, sol, core.l, num.l;
옵션 클리어 = sol;

* Cplex 솔루션 풀 시설
$onEcho > cplex.opt
solnPool solnpool.gdx
solnPoolPop 2
solnPool강도 4
populateLim 41
solnPoolGap 0.03
$offEcho

큐브.opt파일 = 1;
옵션 mip = cplex;

mip를 사용하여 큐브 최소화 num을 해결합니다.

코어.l, num.l을 표시합니다.

세트
   soln '솔루션 풀의 가능한 솔루션' / file1*file40 /
   solnpool(soln) '실제 솔루션';

Execute_load 'solnpool.gdx', solnpool = index;
루프(solnpool(soln),
   put_utility 'gdxin' / solnpool.te(soln);
   실행_로드포인트;
   sol(soln,x,y,z) = round(core.l(x,y,z));
   sol(soln,'','','obj') = num.l;
);
display$(card(solnpool) = 카드(soln)) '사용 가능한 더 많은 솔루션';
디스플레이 솔;