mip06.gms : 컷 및 솔루션 열거

설명

이 모델은 모델 라이브러리의 dice.176 모델을 기반으로 합니다.  만들다
MIP 솔루션 열거의 예로 더 잘 작동합니다.
솔루션과 솔루션을 만들기 위해 정리 및 제약 조건이 추가되었습니다.
대표님 독특해요.  그런 다음 컷이 추가되었습니다.  기본적으로는 중지됩니다.
모든 최적의 솔루션을 찾았을 때 잘라내기/열거하기.

기고자: Steve Dirkse, 2012년 1월

소형 모델 유형 :MIP


카테고리 : 슬롯 사이트 추천 테스트 라이브러리


메인 파일 : mip06.gms

$title 컷 및 솔루션 열거 (MIP06,SEQ=553)

$onText

이 모델은 모델 라이브러리의 dice.176 모델을 기반으로 합니다.  만들다
MIP 솔루션 열거의 예로 더 잘 작동합니다.
솔루션과 솔루션을 만들기 위해 정리 및 제약 조건이 추가되었습니다.
대표님 독특해요.  그런 다음 컷이 추가되었습니다.  기본적으로는 중지됩니다.
모든 최적의 솔루션을 찾았을 때 잘라내기/열거하기.

기고자: Steve Dirkse, 2012년 1월

$offText

* 컷 생성 없이 실행하려면 명령줄에서 --SKIPCUTS=1을 사용하세요.
* 이렇게 하면 문제가 해결되지 않고 기본적으로 해결됩니다.
* 하나의 솔루션만 반환
$설정되지 않은 경우 SKIPCUTS $set SKIPCUTS 0

세트
  f '다이 페이스' /face1*face6 /
  d '주사위 수' / die1*die3 /
  ;
$평가 NV 카드(f)*카드(d)
세트
  v '액면가' / v1*v%NV% /
  pp '이전 솔루션' / p1*p500 /
  피(pp)
  ;
별칭(f,fp),(d,dp);

매개변수
  vals(v) '가능한 액면가'
  pMap(pp,d,f,v) '이전 솔루션의 지도'
  승리Cnt(pp)
  엠
  ;
vals(v) = ord(v);
M = 카드(d)*카드(f);

변수
  xWins
  faceVal(d,f) '다이 면의 값 - 정수가 됩니다.'
  ;
이진 변수
  win(d,f,fp) 'faceVal(d,f)가 FaceVal(d++,fp)보다 크면 true입니다.'
  map(d,f,v) '주사위 면을 값에 매핑'
  ;

FaceVal.lo(d,f) = 1;
FaceVal.up(d,f) = 카드(d)*카드(f);

FaceVal.fx('die1','face1') = 1;

방정식
  winBnd(d) 'd 대 d++의 승리를 결정했습니다.'
  winDefA(d,f,fp) 'win(d,f,fp)는 (d++,fp)에 대한 (d,f)의 우위를 의미합니다.'
  winDefB(d,f,fp) 'win(d,f,fp)가 아님은 (d,f)에 대한 (d++,fp)의 우위를 의미합니다.'
  faceDef(d,f) '액면값 정의'
  오더(d,f) '각 주사위의 액면가를 정렬하세요'
  Unique(v) '각 값은 한 번만 사용됩니다.'
  cuts(pp) '이전 솔루션 잘라내기'
  ;

winBnd(d) .. sum(f,fp), win(d,f,fp) =g= xWins;

winDefA(d,f,fp)..faceVal(d,f) + M*(1-win(d,f,fp)) =g= faceVal(d++1,fp) + 1;

winDefB(d,f,fp)..faceVal(d++1,fp) + M*win(d,f,fp) =g= faceVal(d,f) + 1;

faceDef(d,f) ..faceVal(d,f) =e= sumv, vals(v)*map(d,f,v);

ordered(d,f-1) ..faceVal(d,f-1) + 1 =l=faceVal(d,f);

고유(v) .. sum(d,f), map(d,f,v) =e= 1;

cuts(p) .. sum(d,f,v), map(d,f,v) $[not pMap(p,d,f,v)] +
                            (1-맵(d,f,v))$[ pMap(p,d,f,v)]
                  =g= 1;

모델 주사위 / 모두 /;

옵션 optcr = 0.0;
p(pp) = 아니오;
pMap(p,d,f,v) = 0;

Execute_unload 'diceDef', f, d, v, vals;

xWins를 최대화하는 밉을 사용하여 주사위를 푼다.

옵션면Val:0; 디스플레이 페이스Val.l;

매개변수 rep1 다음 상대에 대한 승리 확률;
rep1(d,f) = 100*sum(fp, win.l(d,f,fp)) / 카드(f);
담당자1(d,'기회') = 합계(f, 담당자1(d,f))/카드(f);
옵션 담당자1:0; 담당자1 표시;

$if %SKIPCUTS% == 1 $종료

스칼라
  컷오프
  nSols '발견된 솔루션 수'
  ;
컷오프 = 20.5;

옵션 limrow=0, limcol=0, solprint=off;
옵션solveLink = %solveLink.loadLibrary%;
루프pp$(dice.solvestat=%solveStat.normalCompletion% 및
         dice.modelstat=%modelStat.optimal% 및
         라운드(xWins.l)>=컷오프),

   p(pp) = 그렇습니다;
   winCnt(pp) = round(xWins.l);
   pMap(pp,d,f,v) = round(map.l(d,f,v));
   밉을 사용하여 xWins를 최대화하는 주사위를 푼다.
;
nSols = 카드(p);
nSol을 표시합니다.
Execute_unload 'diceSolsCuts', f, d, v, vals, p, pMap, winCnt;
abort$[card(p) eq 카드(pp)] 'pp를 너무 작게 설정';
파일 로그 /''/;
putclose log // '테스트 완료 OK' / ' cutoff = ', cutoff / ' nSols = ', nSols //;