선형 계획 설정하기, 문제 기반
문제를 솔버 형식으로 변환하기
이 예제에서는 문제 기반 접근법을 사용하여 선형 문제를 수학적 형식에서 Optimization Toolbox™ 솔버 구문으로 변환하는 방법을 보여줍니다.
문제에 사용된 변수와 표현식은 에드거(Edgar) 및 힘멜블라우(Himmelblau)의 문헌 [1]에 나오는 예제에서 화학 공장을 가동하는 모델을 나타냅니다. 문제를 설명하는 2개의 관련 비디오가 있습니다.
Mathematical Modeling with Optimization, Part 1에서는 문제를 그림 형식으로 소개하고 모델 설명의 수학 표현식을 생성하는 방법을 보여줍니다.
Optimization Modeling, Part 2: Problem-Based Solution of a Mathematical Model에서는 이러한 수학 표현식을 Optimization Toolbox 솔버 구문으로 변환하는 방법을 다룹니다. 이 비디오에서는 문제를 푸는 방법과 결과를 해석하는 방법을 보여줍니다.
Part 2 비디오와 매우 유사한 이 예제에서는 문제를 솔버 구문으로 변환하는 데 초점을 맞춥니다.
모델 설명
Part 1 비디오에서는 문제를 수학적 형식으로 변환하는 방법에 대해 다음 접근법을 제안합니다.
문제를 전반적으로 파악합니다.
목표를 식별합니다(최대화 또는 최소화).
변수를 식별(이름 지정)합니다.
제약 조건을 식별합니다.
제어할 수 있는 변수를 확인합니다.
모든 수량을 수학 표기법으로 지정합니다.
모델이 완전하고 정확한지 확인합니다.
이 섹션에서 변수가 가지는 의미에 대해서는 Part 1 비디오를 참조하십시오.
최적화 문제는 목적 함수를 최소화하는 것이며, 다른 모든 표현식이 제약 조건으로 적용됩니다.
목적 함수는 다음과 같습니다.
0.002614 HPS + 0.0239 PP + 0.009825 EP
.
제약 조건은 다음과 같습니다.
2500
≤ P1
≤ 6250
I1
≤ 192,000
C
≤ 62,000
I1 - HE1
≤ 132,000
I1 = LE1 + HE1 + C
1359.8 I1 = 1267.8 HE1 + 1251.4 LE1 + 192 C + 3413 P1
3000
≤ P2
≤ 9000
I2
≤ 244,000
LE2
≤ 142,000
I2 = LE2 + HE2
1359.8 I2 = 1267.8 HE2 + 1251.4 LE2 + 3413 P2
HPS = I1 + I2 + BF1
HPS = C + MPS + LPS
LPS = LE1 + LE2 + BF2
MPS = HE1 + HE2 + BF1 - BF2
P1 + P2 + PP
≥ 24,550
EP + PP
≥ 12,000
MPS
≥ 271,536
LPS
≥ 100,623
모든 변수는 양수입니다.
첫 번째 풀이 방법: 각 문제 변수에 대한 최적화 변수 생성
첫 번째 풀이 방법에서는 각 문제 변수에 대한 최적화 변수를 만들어야 합니다. 변수를 만들 때 변수의 범위를 포함하십시오.
P1 = optimvar('P1','LowerBound',2500,'UpperBound',6250); P2 = optimvar('P2','LowerBound',3000,'UpperBound',9000); I1 = optimvar('I1','LowerBound',0,'UpperBound',192000); I2 = optimvar('I2','LowerBound',0,'UpperBound',244000); C = optimvar('C','LowerBound',0,'UpperBound',62000); LE1 = optimvar('LE1','LowerBound',0); LE2 = optimvar('LE2','LowerBound',0,'UpperBound',142000); HE1 = optimvar('HE1','LowerBound',0); HE2 = optimvar('HE2','LowerBound',0); HPS = optimvar('HPS','LowerBound',0); MPS = optimvar('MPS','LowerBound',271536); LPS = optimvar('LPS','LowerBound',100623); BF1 = optimvar('BF1','LowerBound',0); BF2 = optimvar('BF2','LowerBound',0); EP = optimvar('EP','LowerBound',0); PP = optimvar('PP','LowerBound',0);
문제 및 목적 함수 만들기
최적화 문제 컨테이너를 만듭니다. 문제에 목적 함수를 포함시킵니다.
linprob = optimproblem('Objective',0.002614*HPS + 0.0239*PP + 0.009825*EP);
선형 제약 조건을 만들고 포함시키기
문제 표현식은 다음과 같은 3개의 선형 부등식을 포함합니다.
I1 - HE1 ≤ 132,000 EP + PP ≥ 12,000 P1 + P2 + PP ≥ 24,550 | (1) |
다음과 같은 부등식 제약 조건을 만들어 문제에 포함시킵니다.
linprob.Constraints.cons1 = I1 - HE1 <= 132000; linprob.Constraints.cons2 = EP + PP >= 12000; linprob.Constraints.cons3 = P1 + P2 + PP >= 24550;
문제에는 다음과 같은 8개의 선형 등식이 있습니다.
I2 = LE2 + HE2 LPS = LE1 + LE2 + BF2 HPS = I1 + I2 + BF1 HPS = C + MPS + LPS I1 = LE1 + HE1 + C MPS = HE1 + HE2 + BF1 - BF2 1359.8 I1 = 1267.8 HE1 + 1251.4 LE1 + 192 C + 3413 P1 1359.8 I2 = 1267.8 HE2 + 1251.4 LE2 + 3413 P2 . | (2) |
다음과 같은 제약 조건도 포함시킵니다.
linprob.Constraints.econs1 = LE2 + HE2 == I2; linprob.Constraints.econs2 = LE1 + LE2 + BF2 == LPS; linprob.Constraints.econs3 = I1 + I2 + BF1 == HPS; linprob.Constraints.econs4 = C + MPS + LPS == HPS; linprob.Constraints.econs5 = LE1 + HE1 + C == I1; linprob.Constraints.econs6 = HE1 + HE2 + BF1 == BF2 + MPS; linprob.Constraints.econs7 = 1267.8*HE1 + 1251.4*LE1 + 192*C + 3413*P1 == 1359.8*I1; linprob.Constraints.econs8 = 1267.8*HE2 + 1251.4*LE2 + 3413*P2 == 1359.8*I2;
문제 풀기
문제 정식화가 완료되었습니다. solve
를 사용하여 문제를 풉니다.
linsol = solve(linprob);
Optimal solution found.
해 검토하기
목적 함수를 실행합니다. ([linsol,fval] = solve(linprob)
를 호출하여 다음 값을 가져올 수도 있습니다.)
evaluate(linprob.Objective,linsol)
ans = 1.2703e+03
가장 저렴한 공장 운영 방법의 경우 비용은 $1,207.30입니다.
해 변수 값을 검토합니다.
tbl = struct2table(linsol)
tbl = 1×16 table BF1 BF2 C EP HE1 HE2 HPS I1 I2 LE1 LE2 LPS MPS P1 P2 PP ___ ___ ______ ______ __________ __________ __________ __________ ________ ___ __________ __________ __________ ____ ______ _____ 0 0 8169.7 760.71 1.2816e+05 1.4338e+05 3.8033e+05 1.3633e+05 2.44e+05 0 1.0062e+05 1.0062e+05 2.7154e+05 6250 7060.7 11239
이 표는 너무 넓어서 내용을 쉽게 볼 수 없습니다. 내용이 세로로 정렬되도록 변수를 배치합니다.
vars = {'P1','P2','I1','I2','C','LE1','LE2','HE1','HE2',... 'HPS','MPS','LPS','BF1','BF2','EP','PP'}; outputvars = stack(tbl,vars,'NewDataVariableName','Amt','IndexVariableName','Var')
outputvars = 16×2 table Var Amt ___ __________ P1 6250 P2 7060.7 I1 1.3633e+05 I2 2.44e+05 C 8169.7 LE1 0 LE2 1.0062e+05 HE1 1.2816e+05 HE2 1.4338e+05 HPS 3.8033e+05 MPS 2.7154e+05 LPS 1.0062e+05 BF1 0 BF2 0 EP 760.71 PP 11239
BF1
,BF2
,LE1
은0
, 즉 하한입니다.I2
는244,000
, 즉 상한입니다.목적 함수의 0이 아닌 성분(비용)은 다음과 같습니다.
HPS
—380,328.74
PP
—11,239.29
EP
—760.71
Part 2 비디오에서는 원래 문제 측면에서 이러한 특성을 해석합니다.
두 번째 풀이 방법: 하나의 최적화 변수와 인덱스 생성
또 다른 방법으로, 문제 변수의 이름을 가진 인덱스를 포함하는 하나의 최적화 변수만 사용하여 문제를 풀 수도 있습니다. 이 방법을 사용하면 하한 0을 모든 문제 변수에 한 번에 지정할 수 있습니다.
vars = {'P1','P2','I1','I2','C','LE1','LE2','HE1','HE2',... 'HPS','MPS','LPS','BF1','BF2','EP','PP'}; x = optimvar('x',vars,'LowerBound',0);
변수 범위 설정하기
점 표기법을 사용하여 변수에 범위를 포함시킵니다.
x('P1').LowerBound = 2500; x('P2').LowerBound = 3000; x('MPS').LowerBound = 271536; x('LPS').LowerBound = 100623; x('P1').UpperBound = 6250; x('P2').UpperBound = 9000; x('I1').UpperBound = 192000; x('I2').UpperBound = 244000; x('C').UpperBound = 62000; x('LE2').UpperBound = 142000;
문제를 만들고 선형 제약 조건을 포함시키고 해 구하기
문제 설정의 나머지 단계는 별도의 변수를 사용하여 설정하는 것과 유사합니다. 차이점은 변수를 부를 때 P1
과 같은 이름 대신 인덱스 x('P1')
을 사용한다는 것입니다.
문제 객체를 만들고 선형 제약 조건을 포함시킨 다음에 문제를 풉니다.
linprob = optimproblem('Objective',0.002614*x('HPS') + 0.0239*x('PP') + 0.009825*x('EP')); linprob.Constraints.cons1 = x('I1') - x('HE1') <= 132000; linprob.Constraints.cons2 = x('EP') + x('PP') >= 12000; linprob.Constraints.cons3 = x('P1') + x('P2') + x('PP') >= 24550; linprob.Constraints.econs1 = x('LE2') + x('HE2') == x('I2'); linprob.Constraints.econs2 = x('LE1') + x('LE2') + x('BF2') == x('LPS'); linprob.Constraints.econs3 = x('I1') + x('I2') + x('BF1') == x('HPS'); linprob.Constraints.econs4 = x('C') + x('MPS') + x('LPS') == x('HPS'); linprob.Constraints.econs5 = x('LE1') + x('HE1') + x('C') == x('I1'); linprob.Constraints.econs6 = x('HE1') + x('HE2') + x('BF1') == x('BF2') + x('MPS'); linprob.Constraints.econs7 = 1267.8*x('HE1') + 1251.4*x('LE1') + 192*x('C') + 3413*x('P1') == 1359.8*x('I1'); linprob.Constraints.econs8 = 1267.8*x('HE2') + 1251.4*x('LE2') + 3413*x('P2') == 1359.8*x('I2'); [linsol,fval] = solve(linprob);
Optimal solution found.
인덱싱된 해 검토하기
세로로 된 표로 해를 검토합니다.
tbl = table(vars',linsol.x')
tbl = 16×2 table Var1 Var2 _____ __________ 'P1' 6250 'P2' 7060.7 'I1' 1.3633e+05 'I2' 2.44e+05 'C' 8169.7 'LE1' 0 'LE2' 1.0062e+05 'HE1' 1.2816e+05 'HE2' 1.4338e+05 'HPS' 3.8033e+05 'MPS' 2.7154e+05 'LPS' 1.0062e+05 'BF1' 0 'BF2' 0 'EP' 760.71 'PP' 11239
참고 문헌
[1] Edgar, Thomas F., and David M. Himmelblau. Optimization of Chemical Processes. New York: McGraw-Hill, 1987.