설명
이 문제는 다음을 충족하는 최소 비용 배송 일정을 찾습니다. 시장의 요구사항과 공장의 공급품. 이 모델은 풍부한 루프 본문을 사용하여 여러 시나리오를 실행하는 방법을 보여줍니다. 메가 슬롯 비동기 실행 기능을 사용하여 병렬 방식으로 수행됩니다. 이 모델은 매개변수화될 수 있습니다. 이중 대시 옵션 사용 --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 문제';