Pyomo: Jak włączyć grzywny w docelową funkcję

0

Pytanie

Staram się minimalizować koszty produkcji produktu za pomocą dwóch maszyn. Cena maszyny A wynosi 30 usd za produkt, a cena maszyny B wynosi 40 usd za produkt.

Istnieją dwa ograniczenia:

  • musimy pokrywać zapotrzebowanie w wysokości 50 towarów w miesiącu (x+y >= 50).
  • tania maszyna (A) może produkować tylko 40 produktów w miesiącu (x

Dlatego stworzyłem poniższy kod Pyomo:

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

To działa normalnie, z oczywistym rozwiązaniem x=40;y=10 (cena = 1600)

Jeśli jednak zaczniemy korzystać z samochodu B, zostanie zainstalowana grzywnę w wysokości 300 dolarów nadmiernych kosztów.

Próbowałem z

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

Ale pojawia się następujący komunikat o błędzie

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.

Nie wiem, jak zrealizować warunek włączenia grzywny w docelowej funkcji za pomocą kodu Pyomo.

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

Najlepsza odpowiedź

1

Z m.y to Varnie można używać if wniosek z nim. Zawsze możesz skorzystać z binarną zmienną, za pomocą Big M dopasować tak, jak powiedział Airsquid. Takie podejście nie jest zwykle zalecane, ponieważ on sprawia problem z LP w MILP, ale jest skuteczny.

Trzeba tylko utworzyć nowy Binary Var:

model.bin_y = Var(domain=Binary)

Następnie ograniczenia model.y być równy zero, jeśli model.bin_y jest równa zero, czy też powinno być dowolną wartość między jego granicami. Używam tu ograniczenie do 100, ale można nawet użyć wymagania:

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

następnie w swój cel, po prostu zastosuj nową stałą wartość 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

Dziękuję @pybegginer, bardzo dobrze wyjaśnione :-) Ja углублюсь na korzystanie z Dużego M.
Hookstark

Dla nieograniczonej Vars trzeba użyć bardzo duże znaczenie powiązania, np. 1E6. W tego rodzaju problemach trzeba będzie dokładnie sprawdzić tolerancję solver do двоичному kodu, ponieważ może się zdarzyć tak, że bin_y wynosi ok. zero, ale y nadal większa od zera: na przykład, jeśli granice ustawione jak 1E6, a binarny tolerancja wynosi 1E-6, bin_y przypisany 1E-7(bardzo blisko do zera), ale wartość ograniczenia jest równa y<=5 pozwalając Y być większa od zera. W każdym razie, po prostu dwa razy sprawdź te wartości, gdy model zostanie rozwiązany
pybegginer

W innych językach

Ta strona jest w innych językach

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