asyncloop.gms : 비동기 루프 본문 실행 관련 전송 문제

설명

이 문제는 다음을 충족하는 최소 비용 배송 일정을 찾습니다.
시장의 요구사항과 공장의 공급품.

이 모델은 풍부한 루프 본문을 사용하여 여러 시나리오를 실행하는 방법을 보여줍니다.
메가 슬롯 비동기 실행 기능을 사용하여 병렬 방식으로 수행됩니다.

이 모델은 매개변수화될 수 있습니다. 이중 대시 옵션 사용 --driver=no
메가 슬롯는 방금 시나리오를 순서대로 실행했습니다. 이중 대시 없이
옵션 --driver 또는 --driver=yes 모델이 먼저 자신을 재귀적으로 호출합니다.
루프 전에 코드를 실행한 다음 루프 본문을 병렬로 실행합니다.
그런 다음 루프 후에 코드를 실행합니다. 의 결과 병합
루프 본문을 실행한 작업은 다시 시작 및 GDX를 통해 수행됩니다.

소형 모델 유형 :LP


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


메인 파일 : asyncloop.gms

$title 비동기 루프 본문 실행 관련 전송 문제(ASYNCLOOP,SEQ=411)

$onText
이 문제는 다음을 충족하는 최소 비용 배송 일정을 찾습니다.
시장의 요구사항과 공장의 공급품.

이 모델은 풍부한 루프 본문을 사용하여 여러 시나리오를 실행하는 방법을 보여줍니다.
메가 슬롯 비동기 실행 기능을 사용하여 병렬 방식으로 수행됩니다.

이 모델은 매개변수화될 수 있습니다. 이중 대시 옵션 사용 --driver=no
메가 슬롯는 방금 시나리오를 순서대로 실행했습니다. 이중 대시 없이
옵션 --driver 또는 --driver=yes 모델이 먼저 자신을 재귀적으로 호출합니다.
루프 전에 코드를 실행한 다음 루프 본문을 병렬로 실행합니다.
그런 다음 루프 후에 코드를 실행합니다. 의 결과 병합
루프 본문을 실행한 작업은 다시 시작 및 GDX를 통해 수행됩니다.

Dantzig, GB, 3.3장. 선형 프로그래밍 및 확장.
프린스턴 대학 출판부, 뉴저지주 프린스턴, 1963년.

키워드: 선형 계획법, 운송 문제, 스케줄링, 메가 슬롯
          언어 기능, 비동기 실행 기능
$offText

$드라이버를 설정하지 않은 경우 $set 드라이버 예
$if set before_loop $goTo before_loop
$if set run_loop $goTo run_loop
$if set after_loop $goTo after_loop
$ifI %driver%==yes $goTo 드라이버

* 일반 순차 실행
$set 조건

$라벨 before_loop
세트
   i '통조림 식물' / 시애틀, 샌디에이고 /
   j 'markets' / 뉴욕, 시카고, 토피카 /;

매개변수
   a(i) '경우에 따라 식물 i의 용량'
        /시애틀 350
          샌디에이고 600 /

   b(j) '경우에 따라 시장 j의 수요'
        / 뉴욕 325
          시카고 300
          토피카 275 /;

테이블 d(i,j) '거리(천 마일)'
              뉴욕 시카고 토피카
   시애틀 2.5 1.7 1.8
   샌디에고 2.5 1.8 1.4;

스칼라 f '1,000마일당 케이스당 운임(달러)' / 90 /;

매개변수 c(i,j) '케이스당 운송 비용(단위: 수천 달러)';
c(i,j) = f*d(i,j)/1000;

변수
   x(i,j) '케이스의 선적 수량'
   slack(j) '채워지지 않은 수요에 대한 여유'
   z '총 운송 비용(천 달러)';

양수 변수 x, 여유;

방정식
   비용 '목적 함수 정의'
   Supply(i) '공장 i의 공급 제한을 준수합니다.'
   수요(j) '시장 j의 수요를 충족';

스칼라 펜 / 1000 /;

비용.. z =e= sum((i,j), c(i,j)*x(i,j)) + pen*sum(j, slack(j));

공급(i).. sum(j, x(i,j)) =l= a(i);

수요(j).. sum(i, x(i,j)) =g= b(j) + slack(j);

모델 운송 / 모두 /;

s '시나리오' 설정 / scen1*scen10 /;

매개변수 bsave(j), bmult(s), obj(s);
bsave(j) = b(j);
bmult(s) = 균일(0.9,1.1);

$if set before_loop $exit

$라벨 run_loop
$if set run_loop $set cond $sameas(s,'%myscen%')
루프(s%cond%,
   z를 최소화하는 lp를 사용하여 전송을 해결합니다.
   obj(들) = z.l;
);
$if set run_loop $exit

$라벨 after_loop
$ifThen after_loop 설정
   루프(s$(ord(s) <> 1),
     put_utility 'gdxin' / s.tl:0 '.gdx';
     Execute_loadpoint obj;
   );
$endIf
디스플레이 객체;
$exit

$라벨 드라이버
* 루프 본문을 비동기적으로 실행하는 논리를 구현합니다.
* 루프 전 첫 번째 실행 코드
$call 메가 슬롯 "%메가 슬롯input%" --before_loop=1 lo=%메가 슬롯lo% o=before_loop.lst lf=before_loop.log s=before_loop gdx=before_loop
$ifE errorLevel<>0 before_loop의 $abort 문제

* 다음 실행 루프 본문 코드를 비동기식으로 수행
'루프 시나리오'를 설정합니다.

$gdxIn before_loop
$로드
$gdxIn

$eolCom //

세트
   submit(s) '제출할 작업 목록'
   done(s) '완료된 작업 목록';

매개변수
   h(s) '인스턴스 핸들을 저장합니다'
   maxS '최대 활성 작업 수' / 4 /
   t'타임 스탬프' 시작;

tStart = jnow;
완료 = 아니요;
h(s) = 0;

파일 FX;
반복하다
   제출 = 아니요;
   loop(s$(not (done(s) 또는 h(s)))), submit(s) = yes$(card(submit) + card(h) < maxS););
   루프(제출,
      put_utility fx 'log' / 'submit myscen=' s.tl:0;
      put_utility$(ord(s) = 1) 'exec.async' / '메가 슬롯 "%메가 슬롯input%" --run_loop=1 lo=2 r=before_loop --myscen=' s.tl:0 ' lf=' s.tl:0 '.log o=' s.tl:0 '.lst gdx=' s.tl:0 '.gdx s=run_loop';
      put_utility$(ord(s) > 1) 'exec.async' / '메가 슬롯 "%메가 슬롯input%" --run_loop=1 lo=2 r=before_loop --myscen=' s.tl:0 ' lf=' s.tl:0 '.log o=' s.tl:0 '.lst gdx=' s.tl:0 '.gdx';
      h(s) = 작업 핸들;
   );
   루프(s$(JobStatus(h(s))) = 2),
      put_utility 'log' / 'collect myscen=' s.tl:0;
      abort$errorLevel '루프 작업 중 하나에 문제가 있습니다.';
      완료 = 예;
      h(s) = 0;
   );
   display$sleep(card(h)*0.05) '잠깐만 자세요';
카드(완료) = 카드 또는 경과 시간 > 100까지;  // 모든 작업이 완료될 때까지 대기
tStart = (jnow - tStart)*3600*24;
'모든 루프 실행 시간:', tStart를 표시합니다.

* 루프 작업의 결과를 병합하는 사후 루프 코드 실행
'메가 슬롯 "%메가 슬롯input%" --after_loop=1 r=run_loop o=after_loop.lst lf=after_loop.log lo=%메가 슬롯lo%'를 실행합니다.
abort$errorLevel 'after_loop 문제';