설명
이 예는 확률론적 Bender 구현을 보여줍니다.
간단한 운송 예.
이것은 확률론적 벤더 시퀀스의 다섯 번째 예입니다.
마스터 문제를 해결하기 위해 다양한 방법을 사용하여 구현
하위 문제.
이 다섯 번째 예는 다음을 사용하여 확률론적 벤더 알고리즘을 구현합니다.
개별 모델(마스터)이 있는 MPI를 사용한 병렬 구현
또는 하위 문제) 슬롯 사이트 작업의 Python OO-API로 구현됩니다.
GamsModelInstance 객체. 장점은 모델이 필요하다는 것입니다.
한 번만 생성되고 다양한 데이터로 해결됩니다. 모델 림부터
GamsModelInstance는 변경할 수 없습니다. 마스터 모델에는 모든 항목이 포함됩니다.
처음에는 바인딩되지 않은 제약 조건이 있는 컷이 가능합니다.
합계(j, eps*수신(j)) =l= bigM. 알고리즘이 실행되는 동안
오른쪽과 수신된(j)에 대한 계수는 다음과 같이 업데이트됩니다.
실제 컷 데이터.
이 예에서 모델은 다음과 같이 명령줄에서 시작됩니다.
mpiexec -n 4 게임 spbenders5 fileStemApFromEnv=PMI_RANK lo=2
다른 플랫폼에서는 이 명령이 약간 다르게 보일 수 있습니다. HPC에서
종종 Linux를 실행하고 특수 MPI를 사용하는 시스템의 경우 더 많을 수 있습니다.
Python 버전과 다른 Python 버전을 사용하는 것이 효율적(또는 필수)
슬롯 사이트가 함께 제공됩니다. /latest/docs/API_PY_GETTING_STARTED.html에 설명된 대로
이 Python에는 슬롯 사이트 Python API 패키지도 설치되어 있어야 합니다.
또한 PMI_RANK 변수가 다르게 호출될 수도 있습니다. 어쨌든 슬롯 사이트에는 다음이 필요합니다.
외부 Python 설치를 사용하도록 지시하려면
환경 변수 GMSPYTHONLIB를 외부 Python 라이브러리에 추가합니다.
mpirun -n 4 GMSPYTHONLIB=/path/to/python/lib/libpython3.12.so 슬롯 사이트 spbenders5 fileStemApFromEnv=OMPI_COMM_WORLD_RANK lo=2
이 명령은 카드 + 1개(작은 예에서는 4개)의 복사본을 생성합니다.
spbenders4 모델과 환경 변수 PMI_RANK가 어느 부분을 결정했는지
특정 인스턴스가 재생됩니다. PMI_RANK=0인 슬롯 사이트 작업은 다음을 구현합니다.
master 및 슬롯 사이트 작업 PMI_RANK=1 ~ PMI_RANK=s는 하위 문제를 구현합니다.
수신된 마스터 변수와 컷 정보의 통신
Python 패키지 mpi4py 및 슬롯 사이트 임베디드 코드 기능을 통해 발생합니다.
키워드: 선형 계획법, 확률론적 벤더 알고리즘, 교통
문제, 슬롯 사이트 임베디드 코드 기능, Python, 병렬 컴퓨팅,
메시지 전달 인터페이스
소형 모델 유형 :LP
카테고리 : 슬롯 사이트 모델 라이브러리
메인 파일 : spbenders5.gms
$title 확률적 벤더 - GAMSModelInstance를 사용한 병렬 MPI(SPBENDERS5,SEQ=422)
$onText
이 예는 확률론적 Bender 구현을 보여줍니다.
간단한 운송 예.
이것은 확률론적 벤더 시퀀스의 다섯 번째 예입니다.
마스터 문제를 해결하기 위해 다양한 방법을 사용하여 구현
하위 문제.
이 다섯 번째 예는 다음을 사용하여 확률론적 벤더 알고리즘을 구현합니다.
개별 모델(마스터)이 있는 MPI를 사용한 병렬 구현
또는 하위 문제) 슬롯 사이트 작업의 Python OO-API로 구현됩니다.
GamsModelInstance 객체. 장점은 모델이 필요하다는 것입니다.
한 번만 생성되고 다양한 데이터로 해결됩니다. 모델 림부터
GamsModelInstance는 변경할 수 없습니다. 마스터 모델에는 모든 항목이 포함됩니다.
처음에는 바인딩되지 않은 제약 조건이 있는 컷이 가능합니다.
합계(j, eps*수신(j)) =l= bigM. 알고리즘이 실행되는 동안
오른쪽과 수신된(j)에 대한 계수는 다음과 같이 업데이트됩니다.
실제 컷 데이터.
이 예에서 모델은 다음과 같이 명령줄에서 시작됩니다.
mpiexec -n 4 게임 spbenders5 fileStemApFromEnv=PMI_RANK lo=2
다른 플랫폼에서는 이 명령이 약간 다르게 보일 수 있습니다. HPC에서
종종 Linux를 실행하고 특수 MPI를 사용하는 시스템의 경우 더 많을 수 있습니다.
Python 버전과 다른 Python 버전을 사용하는 것이 효율적(또는 필수)
슬롯 사이트가 함께 제공됩니다. /latest/docs/API_PY_GETTING_STARTED.html에 설명된 대로
이 Python에는 슬롯 사이트 Python API 패키지도 설치되어 있어야 합니다.
또한 PMI_RANK 변수가 다르게 호출될 수도 있습니다. 어쨌든 슬롯 사이트에는 다음이 필요합니다.
외부 Python 설치를 사용하도록 지시하려면
환경 변수 GMSPYTHONLIB를 외부 Python 라이브러리에 추가합니다.
mpirun -n 4 GMSPYTHONLIB=/path/to/python/lib/libpython3.12.so 슬롯 사이트 spbenders5 fileStemApFromEnv=OMPI_COMM_WORLD_RANK lo=2
이 명령은 카드 + 1개(작은 예에서는 4개)의 복사본을 생성합니다.
spbenders4 모델과 환경 변수 PMI_RANK가 어느 부분을 결정했는지
특정 인스턴스가 재생됩니다. PMI_RANK=0인 슬롯 사이트 작업은 다음을 구현합니다.
master 및 슬롯 사이트 작업 PMI_RANK=1 ~ PMI_RANK=s는 하위 문제를 구현합니다.
수신된 마스터 변수와 컷 정보의 통신
Python 패키지 mpi4py 및 슬롯 사이트 임베디드 코드 기능을 통해 발생합니다.
키워드: 선형 계획법, 확률론적 벤더 알고리즘, 교통
문제, 슬롯 사이트 임베디드 코드 기능, Python, 병렬 컴퓨팅,
메시지 전달 인터페이스
$offText
$set MPI_RANK notSet
$if setenv PMI_RANK $set MPI_RANK %sysEnv.PMI_RANK%
$if setenv OMPI_COMM_WORLD_RANK $set MPI_RANK %sysEnv.OMPI_COMM_WORLD_RANK%
$if %MPI_RANK%==notSet $abort.noError 이 모델은 mpiexec/mpirun으로 시작해야 합니다. 자세한 내용은 모델 소스의 서문을 참조하세요.
$set MPI_SIZE notSet
$if setenv PMI_SIZE $set MPI_SIZE %sysEnv.PMI_SIZE%
$if setenv OMPI_COMM_WORLD_RANK $set MPI_SIZE %sysEnv.OMPI_COMM_WORLD_SIZE%
$if %MPI_SIZE%==notSet $abort.noError 이 모델은 mpiexec/mpirun으로 시작해야 합니다. 자세한 내용은 모델 소스의 서문을 참조하세요.
$log --- Python 라이브러리 %sysEnv.GMSPYTHONLIB% 사용
세트
나는 '공장' / f1*f3 /
j '물류 센터' / d1*d5 /;
매개변수
생산 능력(i) '공장의 단위 생산 능력'
/ f1 500, f2 450, f3 650 /
수요(j) '유통센터의 단위수요'
/ d1 160, d2 120, d3 270, d4 325, d5 700 /
prodcost '단위 생산 비용' / 14 /
가격 '판매 가격' / 24 /
wastecost '과잉 재고 제품 제거 비용' / 4 /;
테이블 transcost(i,j) '단위 운송 비용'
d1 d2 d3 d4 d5
f1 2.49 5.21 3.76 4.85 2.07
f2 1.46 2.54 1.83 1.86 4.76
f3 3.26 3.08 2.60 3.76 4.45;
$ifThen 설정되지 않음 useBig
'시나리오' 설정 / lo, mid, hi /;
테이블 ScenarioData(s,*) '수요와 확률에 대한 가능한 결과'
d1 d2 d3 d4 d5 문제
로우 150 100 250 300 600 0.25
중반 160 120 270 325 700 0.50
안녕 170 135 300 350 800 0.25;
$else
$ nrScen을 설정하지 않은 경우 $set nrScen 10
s '시나리오' 설정 / s1*s%nrScen% /;
Parameter ScenarioData(s,*) '수요 + 확률에 대한 가능한 결과';
옵션 시드 = 1234;
ScenarioData(s,'prob') = 1/카드;
ScenarioData(s,j) = 수요(j)*uniform(0.6,1.4);
$endIf
$평가 카드S개 카드+1
$if not %cardS%==%MPI_SIZE% $abort MPI 크기는 %cardS%여야 합니다.
$set 솔버로그
$if set useSolverLog $setsolverlog 출력=sys.stdout
임베디드 코드 Python:
시도해 보세요:
mpi4py 가져오기에서 *
제외:
raise Exception("mpi4py 모듈을 찾을 수 없습니다")
comm = MPI.COMM_WORLD
def 기호2목록(*기호):
반환 목록(map(lambda x: list(슬롯 사이트get(x)), 기호))
def syncData(db_from, db_to, *args):
args의 Sym의 경우:
db_from[sym].copy_symbol(db_to[sym])
defsolvMI(mi, SymIn=[], SymOut=[]):
SymIn의 Sym에 대해:
슬롯 사이트db[sym].copy_symbol(mi.sync_db[sym])
mi.solve(%solverlog%)
SymOut의 Sym에 대해:
시도해 보세요:
슬롯 사이트db[sym].clear() # Sym에 대해 "writerTo" 플래그가 설정되었는지 확인하기 위해 기호를 명시적으로 지웁니다.
mi.sync_db[sym].copy_symbol(슬롯 사이트db[sym])
제외:
통과
일시중지임베디드코드
abort$execerror 'mpy4py 설정에 문제가 있거나 다른 Python 오류가 발생했습니다. 로그를 확인하세요';
매개변수 r(j) / #j 0/, osub(s), cconst(s), ccoeff(s,j);
$ifThen.MPI 0==%MPI_RANK%
* 벤더스 마스터 문제
$maxiter를 설정하지 않은 경우 $set maxiter 25
iter '최대 벤더 반복 횟수' / 1*%maxiter% / 설정;
별칭(iter,it);
매개변수
cutconst(iter) '최적 컷의 상수' / #iter 0 /
cutcoeff(iter,j) '최적 컷의 계수' / #iter.#j 0 /;
변수
ship(i,j) '배송'
제품(i) '생산'
received(j) '시장에 보낸 수량'
zmaster '마스터 문제의 목적 변수'
세타 '미래 이익';
포지티브 가변 선박;
방정식
masterobj '마스터 목적 함수'
Production(i) '각 공장의 생산량을 계산합니다.'
receive(j) '시장에 보낼 수량을 계산합니다'
optcut(iter) '벤더 최적성 감소';
masterobj.. zmaster =e= theta - sum((i,j), transcost(i,j)*ship(i,j))
- sum(i,prodcost*product(i));
receive(j).. received(j) =e= sum(i, ship(i,j));
생산(i).. 제품(i) =e= sum(j, ship(i,j));
옵트컷(iter)..
theta =l= cutconst(iter) + sum(j, cutcoeff(iter,j)*received(j));
product.up(i) = 용량(i);
모델 마스터문제 / 모두 /;
스칼라
rgap '상대적 간격' / 0 /
lowerBound '전역 하한' / -inf /
upperBound '전역 상한' / +inf /
obj마스터 / 0 /
objSub / 0 /;
* 컷을 바인딩되지 않은 상태로 초기화합니다.
cutconst(iter) = 1e15;
cutcoeff(iter,j) = EPS;
$libInclude pyEmbMI miMaster 'lp를 사용하는 masterproblem max zmaster' -all_model_types=cplex cutconst.Accumulate cutcoeff.Accumulate
옵션 limRow = 0, limCol = 0, solPrint = 자동, 솔버 = cplex,solveLink = %solveLink.loadLibrary%;
r(j) = 0;
obj마스터 = 0;
$rtol을 설정하지 않은 경우 $set rtol 0.001
루프(그것,
계속임베디드코드:
comm.bcast([[0], list(슬롯 사이트get('r'))], 루트=0)
cut = comm.gather(없음, 루트=0)[1:]
슬롯 사이트set('osub', [c[0][0] for c in cut])
슬롯 사이트set('cconst', [c[1][0] for c in cut])
슬롯 사이트set('ccoeff', [rec for s in cut for rec in s[2]])
PauseEmbeddedCode osub, cconst, ccoeff
* 아래 컷 데이터의 클리어는 Accumulate updateType과 함께 적용됩니다.
* 업데이트 기호. Clear 및 updateType BaseCase 없이도 작동합니다.
* 그러나 매 반복마다 통신하기 때문에 훨씬 더 많은 데이터 교환이 필요합니다.
* 지금까지 생성된 모든 컷의 데이터
옵션 클리어 = cutconst, 클리어 = cutcoeff;
objSub = 합계(들, osub(들));
cutconst(it) = eps + sum(s, cconst(s));
cutcoeff(it,j) = eps + sum(s, ccoeff(s,j));
if(lowerBound < objMaster + objSub, lowerBound = objMaster + objSub);
rgap = (상한 - 하한)/(1 + abs(상한));
break$(rgap < %rtol%);
계속임베디드코드:
solvMI(miMaster,['cutconst','cutcoeff'],['received','zmaster','theta'])
PauseEmbeddedCode 수신됨, zmaster, theta
upperBound = zmaster.l;
objMaster = zmaster.l - theta.l;
r(j) = 수신됨.l(j);
);
* 하위 작업 종료
계속임베디드코드:
comm.bcast([[1],[]], 루트=0)
endEmbeddedCode
abort$(rgap >= %rtol%) '추가 반복 필요', 하한, 상한;
'최적 솔루션' 표시, 하한, 상한;
$else.MPI
* 벤더스의 하위 문제
변수
sales(j) '판매량(실제 판매됨)'
waste(j) '과잉 제품'
zsub '하위 문제의 목적 변수';
긍정적인 변동판매, 낭비;
방정식
subobj '하위 문제 목적 함수'
Selling(j) '수취한 부분이 판매되었습니다'
market(j) '매출 상한선';
subobj.. zsub =e= sum(j, 가격*판매(j)) - sum(j, wastecost*waste(j));
판매(j)..판매(j) + 폐기물(j) =e= r(j);
시장(j)..매출(j) =l= 수요(j);
모델 하위 문제 / 하위 개체, 판매, 시장 /;
* 무한 루프
싱글톤 세트 ss(s);
ss(들) = ord(들)=%MPI_RANK%;
수요(j) = 시나리오데이터(ss,j);
스칼라 완료;
$libInclude pyEmbMI miSub 'lp를 사용하는 하위 문제 최대 zsub' -all_model_types=cplex r.Zero
옵션 limRow = 0, limCol = 0, solPrint = 자동, 솔버 = cplex,solveLink = %solveLink.loadLibrary%;
동안(1,
계속임베디드코드:
rx = comm.bcast(없음, 루트=0)
슬롯 사이트set('완료', rx[0])
miSub.sync_db['r'].clear()
rx[0][0]이 아닌 경우:
rx[1]의 Rec에 대해:
miSub.sync_db['r'].add_record(rec[0]).value = Rec[1]
miSub.solve(%solverlog%)
syncData(miSub.sync_db,슬롯 사이트db,'시장','판매','zsub')
PauseEmbeddedCode 완료, 시장, 판매, zsub
abort.noerror$done '하위 프로세스 종료 중';
osub(ss) = eps + ScenarioData(ss,'prob')*zsub.l;
cconst(ss) = eps + ScenarioData(ss,'prob')*sum(j, market.m(j)*demand(j));
ccoeff(ss,j) = eps + ScenarioData(ss,'prob')*판매.m(j);
계속임베디드코드:
comm.gather(symbols2List('osub', 'cconst', 'ccoeff'), root=0 )
일시중지임베디드코드
);
$endIf.MPI