Pyomo: Nesnel işleve bir ceza nasıl dahil edilir

0

Soru

İki makineyle bir ürünün üretim maliyetini en aza indirmeye çalışıyorum. Makine A'nın maliyeti 30 $/üründür ve makine B'nin maliyeti 40 $ / üründür.

İki kısıtlama vardır:

  • aylık 50 ürün talebini karşılamalıyız (x + y > = 50)
  • ucuz makine (A) ayda sadece 40 ürün üretebilir (x

Bu yüzden aşağıdaki Pyomo kodunu oluşturdum:

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

Bariz çözüm x = 40 ile iyi çalışıyor; y = 10 (Maliyet = 1600)

Bununla birlikte, B makinesini kullanmaya başlarsak, maliyetin üzerinde 300 dolarlık sabit bir ceza olacaktır.

Ben denedim

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

Ancak aşağıdaki hata iletisini alıyorum

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.

Cezayı Pyomo kodu aracılığıyla nesnel işleve dahil etmek için koşulu nasıl uygulayacağımı bilmiyorum.

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

En iyi cevabı

1

Dan beri m.y is a Var kullanamazsınız kullanın if onunla ifade ver. Her zaman kullanarak bir ikili değişken kullanabilirsiniz Big M Airsquid'in dediği gibi yaklaşın. Bu yaklaşım genellikle önerilmez, çünkü sorunu lp'den mılp'ye dönüştürür, ancak etkilidir.

Sadece yeni bir tane oluşturmanız gerekiyor Binary Var:

model.bin_y = Var(domain=Binary)

Sonra kısıtlama model.y eğer sıfır olmak model.bin_y sıfırdır veya sınırları arasında herhangi bir değer olabilir. Burada 100'lük bir sınır kullanıyorum, ancak talebi bile kullanabilirsiniz:

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

ardından, hedefinizde sadece 300'ün yeni sabit değerini uygulayın:

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

Teşekkürler @ pybegginer, çok iyi açıklandı: -) Büyük M'nin kullanımına daha derine ineceğim.
Hookstark

Sınırsız için Vars aşağıdaki gibi çok büyük bir bound değeri kullanmanız gerekir 1E6. Bu tür bir problemde, çözücünün İkili toleransını iki kez kontrol etmeniz gerekecektir, çünkü bu gerçekleşebilir bin_y yaklaşık. sıfır, ama y hala sıfırdan büyük: örneğin, sınırlar 1E6 olarak ayarlanmışsa ve ikili tolerans 1E-6 ise, bin_y 1E-7'ye(sıfıra çok yakın) atanır, ancak sonuçta ortaya çıkan kısıtlama y<=5 y'nin sıfırdan büyük olmasına izin vermek. Her neyse, model çözüldüğünde bu değerleri iki kez kontrol edin
pybegginer

Diğer dillerde

Bu sayfa diğer dillerde

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