Pyomo: Como incluir uma penalidade na função objetivo

0

Pergunta

Eu estou tentando minimizar o custo de fabricação de um produto com duas máquinas. O custo da máquina é de $30/produto e o custo da máquina B é de r $40/produto.

Existem duas restrições:

  • temos de cobrir uma demanda de 50 produtos por mês (x+y >= 50)
  • o barato máquina (Um) só pode fabricação de 40 produtos por mês (x<=40)

Então eu criei a seguinte 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())

Ele funciona ok, com a óbvia solução x=40, y=10 (Custo = 1600)

No entanto, se começar a usar a máquina B, haverá uma fixo multa de $300 mais o custo.

Eu tentei com o

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

Mas eu recebo a seguinte mensagem de erro

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.

Eu não como implementar a condição de incluir a penalidade na função objetivo através da Pyomo código.

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

Melhor resposta

1

Desde m.y é um Var, você não pode usar o if instrução com ele. Você sempre pode usar uma variável binária usando o Big M abordagem Airsquid disse ele. Esta abordagem é geralmente não é recomendado, pois transforma o problema de LP em um MILP, mas é eficaz.

Você só precisa criar uma nova Binary Var:

model.bin_y = Var(domain=Binary)

Em seguida, restrição de model.y para ser igual a zero se model.bin_y é zero, ou outra coisa, ser qualquer valor entre os seus limites. Eu uso um limite de 100 aqui, mas você ainda pode usar o seguinte pedido:

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

em seguida, no seu objetivo apenas de aplicar o novo valor fixo 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

Obrigado @pybegginer, muito bem explicado :-) vou aprofundar-se na utilização de Grande M.
Hookstark

Para unbounded Vars você precisa usar um valor muito grande de dependente, tais como 1E6. Neste tipo de problema, você vai precisar de verificar a solver a tolerância para Binário, pois pode acontecer que bin_y é de aprox. zero, mas y ainda é maior do que zero: por exemplo, se os limites são definidos como 1E6 e o binário de tolerância é de 1E-6, bin_y é atribuído a 1E-7(muito perto de zero), mas a resultante de restrição é y<=5 permitindo que Y seja maior do que zero. De qualquer maneira, apenas verifique esses valores quando o modelo é resolvido
pybegginer

Em outros idiomas

Esta página está em outros idiomas

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