circpack.gms : 가능한 가장 작은 직사각형으로 원을 채우세요

설명

주어진 원 세트에 대해 호스트하는 최소 직사각형 영역을 결정합니다.
모든 서클.

이 문제에는 전역 솔버가 필요합니다.

소형 모델 유형 :NLP


카테고리 : 피망 슬롯 모델 라이브러리


메인 파일 : circpack.gms

$title 가능한 가장 작은 직사각형의 원 묶음(CIRCPACK,SEQ=401)

$onText
주어진 원 세트에 대해 호스트하는 최소 면적 직사각형을 결정합니다.
모든 서클.

이 문제에는 전역 솔버가 필요합니다.

Kallrath, J. 면적 최소화 직사각형에서 원 및 다각형 절단.
글로벌 최적화 저널 43 (2009), 299-328

키워드: 비선형 프로그래밍, 전역 최적화, 절단 재고 문제,
          원 채우기 문제, 모양 제약, 비중첩 제약,
          디자인 문제
$offText

세트
   d '차원' / 1, 2 /
   i '항목=원' / i1*i6 /;

매개변수
   sizeLB(d) '직사각형 크기의 하한' / 1 1, 2 1 /
   sizeUB(d) '직사각형 크기의 상한' / 1 4, 2 8 /
   R(i) '원의 반경' / i1 1.2, i2 0.6, i3 0.8
                                   i4 1.7, i5 1.3, i6 0.5 /;

*-----------------------------------------
* 원 채우기 문제를 해결하기 위한 NLP 모델
*-----------------------------------------
별칭(i,ii);

변수
   '직사각형의 영역'
   xP(d) '직사각형의 너비(d=1)와 길이(d=2)'
   x(i,d) '원 i의 중심'
   z '목적 함수';

양수 변수 a, xP, x;

방정식
   목표 '트림로스'
   면적 '직사각형의 면적'
   disjun(i,ii) '원이 겹치지 않는 조건'
   ULx(i,d) 'x(i) le w - R(i)의 상한';

목표.. z =e= a - sum(i, pi*sqr(R(i)));

* 디자인 직사각형의 면적 계산(쌍선형 버전)
면적.. a =e= prod(d, xP(d));

* 원 중심 좌표의 상한
ULx(i,d).. x(i,d) =l= xP(d) - R(i);

* DISJUN(i,ii)$(동일하지 않음(i,ii))..
disjun(i,ii)$(i.pos > ii.pos).. sum(d, sqr(x(i,d)-x(ii,d))) =g= sqr(R(i)+R(ii));

모델 Circpack / 모두 /;

* 원 중심의 하한과 상한
x.lo(i,d) = R(i);
x.up(i,d) = sizeUB(d) - R(i);

* 해당 지역의 상한선
a.up = prod(d,sizeUB(d));

* 직사각형의 너비와 길이의 상한
xP.up(d) = sizeUB(d);

* 시작점 설정을 위한 간단한 구성표(예: 아래와 같은)는 그렇지 않습니다.
* 로컬 솔버를 사용하면 실현 가능한 솔루션을 얻을 수 있습니다. 이 문제에는
* 글로벌 코드
x.l(i,d) = 균일(x.lo(i,d), x.up(i,d));
xP.l(d) = sizeUB(d);
a.l = a.up;

옵션 resLim = 60;
z를 최소화하는 nlp를 사용하여 Circpack을 해결합니다.

a.l, xP.l, z.l, x.l을 표시합니다.

* 보기 좋은 출력을 생성합니다.
$ifThen gnuplot 설정
* 출력 파일 생성: GnuPlot에 제공할 수 있는 result.out
   파일 fresultout / result.out /;
   fresultout을 넣어;
   '출력' 넣기 /
       '파라메트릭 설정' /
       '범위 설정 [0:',(2*PI):11:8,']' /
       @21, '플롯';
   루프(나,
       x.l(i,"2"):4:2,'+',R(i):4:2,'*cos(t),', x.l(i,"1"):4:2,'+',R(i):4:2,'*sin(t),';
   );
   놓다 ' ' /;
   놓다 ' ' /;
   ' Verschnitt를 qm에 넣습니다: ', (a.l - sum(i, R(i))):5:2 /;
$endIf

$ifThen 라텍스 설정
* 결과를 표시하기 위해 tex 출력 파일을 생성합니다.
* 출력 파일 생성: graphic.tex
   파일 fgraphics / graphic.tex /;
   그래픽을 넣어라;
$onPut
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% "graphics.tex" %
% Josef Kallrath 및 Steffen Rebennack 작성 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass기사