설명
이 모델은 ex3.gms의 모델과 유사합니다. C 및 Fortran 예제에 대한 코드만 포함됩니다. 외부 방정식에 구현 오류가 있습니다. 소스 코드에 **ERROR로 표시되어 있습니다. 이러한 오류를 다음과 비교하십시오. 슬롯 게임 목록 파일의 메시지입니다.
소형 모델 유형 :슬롯 게임
카테고리 : 슬롯 게임 테스트 라이브러리
메인 파일 : er3.gms
$title 외부 방정식 - 오류 예 3 (ER3,SEQ=572)
$offSymList offsymxref
$onText
이 모델은 ex3.gms의 모델과 유사합니다.
C 및 Fortran 예제에 대한 코드만 포함됩니다.
외부 방정식에 구현 오류가 있습니다.
소스 코드에 **ERROR로 표시되어 있습니다. 이러한 오류를 다음과 비교하십시오.
슬롯 게임 목록 파일의 메시지
$offText
세트
i '6개 포인트에 대한 인덱스' /1*6/;
별칭(i,j);
변수
x(i) '점의 x 좌표',
y(i) '점의 y 좌표',
Area(i) "i번째 삼각형의 면적 ( 0 -> p(i) -> p(i++1) -> 0",
totarea '육각형의 전체 면적';
방정식
Areadef(i) '삼각형 i의 면적 정의',
areadefX(i) '삼각형 i의 영역 정의',
maxdist(i,j) 'i와 j 사이의 최대 거리',
maxdistX(i,j) 'i와 j 사이의 최대 거리',
obj '목표 정의';
$onText
외부를 사용하여 방정식 maxdist 및 aredef를 구현합니다.
방정식. 원래 정의는 다음과 같습니다.
$offText
maxdist(i,j)$(ord(i) lt ord(j)).. sqr(x(i)-x(j))+sqr(y(i)-y(j)) =l= 1;
areadef(i)..area(i) =e= 0.5*(x(i)*y(i++1)-y(i)*x(i++1));
$onText
먼저, 외부 방정식은 등식으로 작성되어야 합니다.
따라서 우리는 maxdist 방정식에 명시적인 여유분을 추가해야 합니다.
외부 방정식의 슬롯 게임 공식화.
$offText
양수변수
sl(i,j) 'maxdist 방정식의 느슨함';
$onText
우리는 변수에 대해 다음과 같은 번호 매기기 체계를 사용할 계획입니다.
외부 방정식에 사용됨:
방정식의 번호는 다음과 같습니다.
maxdist(i,j): 아래에 정의된 매개변수 num을 사용하여 정의된 1~15
Areadef(i) : 16 ~ 21 = ord(i) + 15 = ord(i) + 카드(i)*(카드(i)-1)/2;
변수에는 다음과 같이 번호가 매겨져 있습니다.
X(i) : 1 ~ 6 = ord(i)
Y(i) : 7 ~ 12 = ord(i) + 카드(i)
면적(i): 13 ~ 18 = ord(i) + 2*카드(i)
sl(i,j): 19 ~ 33 = 3*card(i) + 1 ~ 15, 다시 아래에 정의된 num을 사용합니다.
$offText
매개변수 num(i,j) 방정식에 사용되는 숫자 maxdist;
매개변수 iplus(i) 변수 x(i++1)에 대한 인덱스;
스칼라 카운트 num / 0 /을 파생하는 데 사용되는 카운터;
루프 (i,j)$(ord(i) lt ord(j)),
개수 = 개수 + 1;
숫자(i,j) = 개수;
;
iplus(i) = ord(i)+1;
iplus(i)$(ord(i) eq 카드(i)) = 1;
디스플레이 번호, iplus;
$onText
이제 희소성 패턴의 정의와 인덱싱을 따릅니다.
외부 방정식의 경우.
방정식 maxdistX에서 ord(i)는 ord(j)가 아니라는 점에 유의하세요.
따라서 계수가 함께 추가될 위험이 없습니다.
(x(i)와 x(j)가 동일한 변수인 경우와 같습니다)
다른 모델에서는 잘못된 색인이 발생할 수 있습니다.
$offText
maxdistX(i,j)$(ord(i) lt ord(j)).. ord(i)*x(i) + ord(j)*x(j) +
(ord(i)+카드(i))*y(i) + (ord(j)+카드(j))*y(j) +
(3*카드(i)+번호(i,j))*sl(i,j)
=X= 숫자(i,j);
AreadefX(i).. ord(i)*x(i) + iplus(i)*x(i++1) +
(카드(i)+ord(i))*y(i) + (카드(i)+iplus(i))*y(i++1) +
(2*카드(i)+ord(i))*면적(i) =X=
카드(i)*(카드(i)-1)/2+ord(i) ;
$onText
마지막 방정식은 두 모델 모두에 대해 슬롯 게임 형식으로 유지됩니다.
$offText
obj..totarea =e= sum(i,area(i));
$ 미리 설정
$ifI %system.filesys%==unix $set pre 'lib'
$ 세트 '64'
$set N er3
$set c_cbN %pre%%N%c_cb%suf%
$set f_cbN %pre%%N%f_cb%suf%
모델 %N% '슬롯 게임 구현' / maxdist, obj,areadef /;
model %c_cbN% '콜백이 포함된 C의 외부 방정식' / maxdistX, obj,areadefX /;
model %f_cbN% '콜백이 포함된 F77의 외부 방정식' / maxdistX, obj,areadefX /;
매개변수 보고서(I,*,*) '해결책 요약';
옵션 보고서:5;
스칼라 totdist /0/;
$onText
이 모델은 다음 모델과 동일한 반복 경로를 사용하지 않습니다.
명시적 슬랙을 사용하기 때문에 CONOPT로 해결된 라이브러리입니다.
동일한 초기 실행 불가능성 합계를 얻으려면 초기화해야 합니다.
maxdist 방정식을 실현 가능하게 만드는 여유 변수(만약
가능). 이는 x & y가 초기화된 후에 수행됩니다.
$offText
$onEchoV > runme.gms
x.fx("1") = 0; y.fx("1") = 0;
x.l("2") = 0.5; y.fx("2") = 0;
x.l("3") = 0.5; y.l("3") = 0.4;
x.l("4") = 0.5; y.l("4") = 0.8;
x.l("5") = 0; y.l("5") = 0.8;
x.l("6") = 0; y.l("6") = 0.4;
sl.l(i,j)$(ord(i) lt ord(j)) =
max(0,1 - (sqr(x.l(i)-x.l(j))+sqr(y.l(i)-y.l(j)) ));
sl.m(i,j)$(ord(i) lt ord(j)) = 0;
면적.l(i) = 0;
토타리아.l = 0;
AreadefX.m(i) = 0;
maxdistX.m(i,j) = 0;
totarea를 최대화하는 nlp를 사용하여 %1을(를) 해결하세요.
$if %1==er3 abort$(%1.solvestat <> 1) '%1 모델 실행에 문제가 있습니다';
$if not %1==er3 abort$(%1.solvestat = 1) '%1 모델 실행에 문제가 있습니다';
실행 오류 = 0;
보고서(i,'X','%1') = x.l(i);
보고서(i,'Y','%1') = y.l(i);
totdist = totdist + sum I, abs(x.l(i) - 보고서(I,'X','er3'));
totdist = totdist + sum I, abs(y.l(i) - 보고서(I,'Y','er3'));
$offEcho
$ 확장 '.dll' 설정
$ifI %system.filesys%==unix $set ext '.so'
$ifI %system.platform%==dex $set ext '.dylib'
$ifI %system.platform%==dax $set ext '.dylib'
$ 세트 eq
$ifI %system.filesys%==unix $set eq "'"
$if set runall $set runC_cb '1' set runF_cb '1'
$ifThen nocomp를 설정하지 않음
$ ifI set runC_cb $call 슬롯 게임 complink lo=%슬롯 게임lo% --lang=c --files=er3c_cb.c --libname=%c_cbN%%ext%
$ 오류 수준 1인 경우 $abort C 라이브러리 컴파일 오류
$ ifI set runF_cb $call 슬롯 게임 complink lo=%슬롯 게임lo% --lang=fortran90 --files=%eq%"gehelper.f90 msg2_f.f90 er3f_cb.f90"%eq% --libname=%f_cbN%%ext%
$ 오류 수준 1인 경우 $abort Fortran90 라이브러리 컴파일 오류
$endIf
$ batInclude runme %N%
$if set runC_cb $batInclude runme %c_cbN%
$if set runF_cb $batInclude runme %f_cbN%
보고서 표시;
if ((totdist < 1.0E-5),
"@@@@ #테스트에 통과했습니다."를 표시합니다.
그렇지 않으면
show totdist, "@@@@ #테스트가 통과되지 않았습니다. 자세한 내용은 er3.lst를 검사하세요.";
);