flowshop.gms : Flow shop 스케줄링

설명

자동차 산업용 금속 파이프를 주문에 따라 생산하는 작업장
파이프를 구부리고 고정 장치를 납땜하는 세 가지 기계가 있습니다.
그리고 링크를 조립합니다. 작업장은 6개의 품목을 생산해야 합니다.
처리 단계의 기간은 아래와 같습니다. 한 번
시작된 작업은 완료될 때까지 수행되어야 하지만
공작물(항목)이 기계 사이에 대기할 수 있습니다.

모든 기계는 한 번에 하나의 항목만 처리합니다. 공작물(품목)은
다른 것을 추월하지 마십시오.

모든 작업을 완료하는 데 걸리는 총 시간을 최소화하는 순서는 무엇입니까?
항목(makespan)?

소형 모델 유형 :MIP


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


메인 파일 : flowshop.gms

$title Flow Shop 스케줄링 - (FLOWSHOP,SEQ=376)

$onText
자동차 산업의 요구에 따라 금속 파이프를 생산하는 작업장
파이프를 구부리고 고정 장치를 납땜하는 세 가지 기계가 있습니다.
그리고 링크를 조립합니다. 작업장은 6개의 품목을 생산해야 합니다.
처리 단계의 기간은 아래와 같습니다. 한 번
시작된 작업은 완료될 때까지 수행되어야 하지만
공작물(항목)이 기계 사이에 대기할 수 있습니다.

모든 기계는 한 번에 하나의 항목만 처리합니다. 공작물(품목)은
다른 것을 추월하지 마십시오.

모든 작업을 완료하는 데 걸리는 총 시간을 최소화하는 순서는 무엇입니까?
아이템(메이크스팬)?

Gueret, C, Prins, C 및 Sevaux, M, 최적화 응용
Xpress-MP, Susanne Heipcke가 번역하고 개정함. 대시
최적화, 2002.

키워드: 혼합 정수 선형 계획법, 완화된 혼합 정수 계획법,
          시나리오분석, GUSS, Flow Shop Scheduling, 생산계획
$offText

세트
   나는 '항목' / i1*i6 /
   m '기계' / 굽힘, 납땜, 조립 /;

$set 마지막 순위 i6
$set 마지막 기계 어셈블리

테이블 처리 시간(m,i)
              i1 i2 i3 i4 i5 i6
   굽힘 3 6 3 5 5 7
   납땜 5 4 2 4 4 5
   조립 5 2 4 6 3 6;

별칭(i,k);

변수
   Rank(i,k) 'i 항목의 위치는 k입니다.'
   start(m,k) 'm의 k 위치에 있는 작업의 시작 시간'
   comp(m,k) 'm의 k 위치에 있는 작업의 완료 시간'
   totwait '첫 번째 작업 전 시간 + 마지막 시스템의 작업 간 시간';

바이너리 변수 순위;
양수 변수 시작, comp;

방정식
   oneInPosition(k) '모든 직위는 일자리를 얻습니다'
   oneRankPer(i) '모든 직업에는 순위가 할당됩니다'
   onmachrel(m,k) 'm 기계의 작업 순위 k 끝과 m+1 기계의 작업 순위 k 시작 사이의 관계'
   permachrel(m,k) '머신 m의 작업 순위 k 끝과 머신 m의 작업 순위 k+1 시작 사이의 관계'
   defcomp(m,k) '시작 시간과 절차 시간을 기준으로 완료 시간 계산'
   defobj '최종 직급 완료 시간';

oneInPosition(k).. sum(i, Rank(i,k)) =e= 1;

oneRankPer(i).. sum(k, 순위(i,k)) =e= 1;

onmachrel(m,k+1)..start(m,k+1) =g= comp(m,k);

permachrel(m+1,k)..start(m+1,k) =g= comp(m,k);

defcomp(m,k).. comp(m,k) =e= start(m,k) + sum(i, proctime(m,i)*rank(i,k));

defobj..totwait =g= comp('%lastmachine%','%lastrank%');

모델 순서 / 모두 /;

옵션 optCr = 0;

mip min totwait를 사용하여 시퀀스를 해결합니다.

* 어쩌면 다음이 출력하기에 더 좋은 정보일 수도 있습니다.
매개변수 startjob(m,i);
startjob(m,i) = sum(k$(rank.l(i,k)>0.5), start.l(m,k));

옵션 시작작업:0:1:1;
시작작업 표시;

* 작은 데이터의 경우 모든 순열을 열거하고 일정을 평가할 수 있습니다.
$ifE 카드(i)>8 $exit

* 일부 LP 솔버로만 테스트
$ifI %슬롯rmip% == cplex $go계속하려면
$ifI %슬롯rmip% == xpress $go계속하려면
$ifI %슬롯rmip% == 구로비 $go계속하려면
$ifI %슬롯rmip% == soplex $go계속하려면
$exit

$label 계속
$eval pmax 사실(카드(i))
세트
   p / p1*p%pmax% /
   랭콜(p,i,i);

옵션 랭콜 > i;

매개변수
   prankall(p,i,i) 'rankall의 매개변수 버전'
   ptotwait(p) '시나리오 목표';

prankall(rankall) = 1;

* GUSS를 사용하여 모든 시나리오 평가
dict / p를 설정하십시오.      대본. ''
           순위.   결정된.    장난
           totwait.level.    잠깐만요 /;

rmip min totwait 시나리오 dict를 사용하여 시퀀스를 해결합니다.

스칼라 besttotwait / +inf /;

루프(p,
   if(besttotwait > ptotwait(p),
      besttotwait = ptotwait(p);
      Rank.l(i,k) = 1$(rankall(p,i,k));
   );
);
최선을 다해 기다리십시오, 순위.l;