Pyomo: ¿Cómo incluir una penalización en la función objetivo

0

Pregunta

Estoy tratando de minimizar el costo de fabricación de un producto con dos máquinas. El costo del equipo es de $30/producto y el costo de la máquina B es de $40/producto.

Hay dos limitaciones:

  • debemos de cubrir una demanda de 50 productos por mes (x+y >= 50)
  • los hoteles de la máquina (A) sólo puede fabricar 40 productos por mes (x<=40)

Así que he creado el siguiente Pyomo código:

from pyomo.environ import *
model = ConcreteModel()
model.x = Var(domain=NonNegativeReals)
model.y = Var(domain=NonNegativeReals)

def production_cost(m):
    return 30*m.x + 40*m.y

# Objective
model.mycost = Objective(expr = production_cost, sense=minimize)

# Constraints
model.demand = Constraint(expr = model.x + model.y >= 50)
model.maxA = Constraint(expr = model.x <= 40)

# Let's solve it
results = SolverFactory('glpk').solve(model)

# Display the solution
print('Cost=', model.mycost())
print('x=', model.x())
print('y=', model.y())

Funciona ok, con la obvia solución x=40;y=10 (Costo = 1600)

Sin embargo, si comenzamos a utilizar la máquina B, habrá un fijo multa de $300 sobre el costo.

He probado con

def production_cost(m):
  if (m.y > 0):
    return 30*m.x + 40*m.y + 300
  else:
    return 30*m.x + 40*m.y

Pero me sale el siguiente mensaje de error

Rule failed when generating expression for Objective mycost with index
    None: PyomoException: Cannot convert non-constant Pyomo expression (0  <
    y) to bool. This error is usually caused by using a Var, unit, or mutable
    Param in a Boolean context such as an "if" statement, or when checking
    container membership or equality. For example,
        >>> m.x = Var() >>> if m.x >= 1: ...     pass
    and
        >>> m.y = Var() >>> if m.y in [m.x, m.y]: ...     pass
    would both cause this exception.

Yo no se cómo aplicar la condición de incluir la penalización en la función objetivo a través de la Pyomo código.

optimization pyomo python
2021-11-22 12:46:07
1

Mejor respuesta

1

Desde m.y es un Varusted puede utilizar el if declaración. Siempre se puede utilizar una variable binaria mediante el Big M enfoque como Airsquid dijo. Este enfoque generalmente no se recomienda, ya que convierte el problema de pl en un MILP, pero es efectivo.

Usted sólo tiene que crear una nueva Binary Var:

model.bin_y = Var(domain=Binary)

Luego de la restricción de la model.y a ser cero si model.bin_y es cero, o otra cosa, ser cualquier valor entre sus límites. Yo uso un límite de 100 aquí, pero usted puede incluso utilizar la demanda:

model.bin_y_cons = Constraint(expr= model.y <= model.bin_y*100)   

luego, en su objetivo sólo se aplica el nuevo valor fijo de 300:

def production_cost(m):
    return 30*m.x + 40*m.y + 300*model.bin_y 

model.mycost = Objective(rule=production_cost, sense=minimize)
2021-11-22 15:22:41

Gracias @pybegginer, muy bien explicado :-) voy a profundizar más en el uso de la Gran M.
Hookstark

Para unbounded Vars usted necesidad de utilizar un valor muy grande de obligado, tales como 1E6. En este tipo de problema, deberá de comprobar que el solucionador de tolerancia a Binario, ya que no se puede descartar que bin_y es de aprox. cero, pero y es todavía mayor que cero: por ejemplo, si los límites se establecen como 1E6 y el binario de la tolerancia es 1E-6, bin_y se asigna a 1E-7(muy cercanas a cero), pero el resultado de la restricción es y<=5 permitiendo Y a ser mayor que cero. De todos modos, basta con hacer doble comprobar los valores cuando el modelo es resuelto
pybegginer

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................