Main Content

Configurar un programa lineal, basado en problemas

Convertir un problema a formato de solver

Este ejemplo muestra cómo convertir un problema lineal de una forma matemática a un solver de Optimization Toolbox™ utilizando el enfoque basado en problemas.

Las variables y expresiones en el problema representan un modelo de explotación de una planta química, tomado de un ejemplo en Edgar y Himmelblau [1]. Dos vídeos asociados describen el problema.

Este ejemplo, que sigue de cerca el vídeo de la parte 2, se centra en transformar el problema en sintaxis de solver.

Descripción del modelo

El vídeo de la parte 1 sugiere el siguiente enfoque para convertir un problema a forma matemática:

  1. Entienda la idea general del problema.

  2. Identifique la meta (maximizar o minimizar algo).

  3. Identifique (nombre) las variables.

  4. Identifique las restricciones.

  5. Determine qué variables puede controlar.

  6. Especifique todas las cantidades en notación matemática.

  7. Compruebe que el modelo está completo y es correcto.

Para averiguar el significado de las variables en esta sección, vea el vídeo de la parte 1.

El problema de optimización es minimizar la función objetivo, sujeta a todo el resto de expresiones como restricciones.

La función objetivo es:

0.002614 HPS + 0.0239 PP + 0.009825 EP.

Las restricciones son:

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
Todas las variables son positivas.

Primer método de solución: crear una variable de optimización para cada variable del problema

El primer método de solución implica crear una variable de optimización para cada variable del problema. A medida que cree las variables, incluya sus límites.

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);

Crear un problema y un objetivo

Cree un contenedor de problemas de optimización. Incluya la función objetivo en el problema.

linprob = optimproblem('Objective',0.002614*HPS + 0.0239*PP + 0.009825*EP);

Crear e incluir restricciones lineales

Las expresiones del problema contienen tres desigualdades lineales:

I1 - HE1132,000
EP + PP12,000
P1 + P2 + PP24,550
(1)

Cree estas restricciones de desigualdad e inclúyalas en el problema.

linprob.Constraints.cons1 = I1 - HE1 <= 132000;
linprob.Constraints.cons2 = EP + PP >= 12000;
linprob.Constraints.cons3 = P1 + P2 + PP >= 24550;

El problema tiene ocho igualdades lineales:

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)

Incluya estas restricciones también.

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;

Resolver el problema

La formulación del problema está completa. Resuelva el problema con solve.

linsol = solve(linprob);
Optimal solution found.

Examinar la solución

Evalúe la función objetivo. (También puede obtener este valor llamando a [linsol,fval] = solve(linprob)).

evaluate(linprob.Objective,linsol)
ans =

   1.2703e+03

El método de explotación de menor coste de la planta cuesta 1.207,30 dólares.

Examine los valores de las variables de solución.

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

Esta tabla es demasiado amplia para ver su contenido con facilidad. Apile las variables para ordenarlas verticalmente.

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 y LE1 son 0, sus límites inferiores.

  • I2 es 244,000, su límite superior.

  • Los componentes distintos de cero de la función objetivo (coste) son

    • HPS380,328.74

    • PP11,239.29

    • EP760.71

El vídeo de la parte 2 interpreta estas características en términos del problema original.

Segundo método de solución: crear una variable de optimización e índices

También puede resolver el problema utilizando solo una variable de optimización que tenga índices con los nombres de las variables del problema. Este método permite dar un límite inferior de cero a todas las variables del problema al mismo tiempo.

vars = {'P1','P2','I1','I2','C','LE1','LE2','HE1','HE2',...
    'HPS','MPS','LPS','BF1','BF2','EP','PP'};
x = optimvar('x',vars,'LowerBound',0);

Establecer límites de variables

Incluya los límites de las variables utilizando la notación de puntos.

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;

Crear problemas, restricciones lineales y soluciones

El resto de la configuración del problema es similar a la configuración usando variables separadas. La diferencia es que, en lugar de referirse a una variable por su nombre, como P1, se refiere a ella utilizando su índice, x('P1').

Cree el objeto del problema, incluya las restricciones lineales y resuelva el problema.

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.

Examinar la solución indexada

Examine la solución como una tabla vertical.

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

Bibliografía

[1] Edgar, Thomas F., and David M. Himmelblau. Optimization of Chemical Processes. New York: McGraw-Hill, 1987.

Temas relacionados