주요 콘텐츠

선형 계획 설정하기, 문제 기반

문제를 솔버 형식으로 변환하기

이 예제에서는 문제 기반 접근법을 사용하여 선형 문제를 수학적 형식에서 Optimization Toolbox™ 솔버 구문으로 변환하는 방법을 보여줍니다.

문제에 사용된 변수와 표현식은 Edgar와 Himmelblau의 문헌[1]에 나오는 예제에서 화학 공장을 가동하는 모델을 나타냅니다. 문제를 설명하는 2개의 관련 비디오가 있습니다.

Part 2 비디오와 매우 유사한 이 예제에서는 문제를 솔버 구문으로 변환하는 데 초점을 맞춥니다.

모델 설명

Part 1 비디오에서는 문제를 수학적 형식으로 변환하는 방법에 대해 다음 접근법을 제안합니다.

  1. 문제를 전반적으로 파악합니다.

  2. 목표를 식별합니다(최대화 또는 최소화).

  3. 변수를 식별(이름 지정)합니다.

  4. 제약 조건을 식별합니다.

  5. 제어할 수 있는 변수를 확인합니다.

  6. 모든 수량을 수학 표기법으로 지정합니다.

  7. 모델이 완전하고 정확한지 확인합니다.

이 섹션에서 변수가 가지는 의미에 대해서는 Part 1 비디오를 참조하십시오.

최적화 문제는 목적 함수를 최소화하는 것이며, 다른 모든 표현식이 제약 조건으로 적용됩니다.

목적 함수는 다음과 같습니다.

0.002614 HPS + 0.0239 PP + 0.009825 EP.

제약 조건은 다음과 같습니다.

2500P16250
I1192,000
C62,000
I1 - HE1132,000
I1 = LE1 + HE1 + C
1359.8 I1 = 1267.8 HE1 + 1251.4 LE1 + 192 C + 3413 P1
3000P29000
I2244,000
LE2142,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 + PP24,550
EP + PP12,000
MPS271,536
LPS100,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 - HE1132,000
EP + PP12,000
P1 + P2 + PP24,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);
Solving problem using linprog.

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, LE10, 즉 하한입니다.

  • I2244,000, 즉 상한입니다.

  • 목적 함수의 0이 아닌 성분(비용)은 다음과 같습니다.

    • HPS380,328.74

    • PP11,239.29

    • EP760.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);
Solving problem using linprog.
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.

참고 항목

도움말 항목