Pyomo: Ako sa patrí penále vo cieľom funkcia

0

Otázka

Snažím minimalizovať náklady na výrobu výrobku s dvoma strojmi. Náklady na stroj je $30/výrobku a náklady na stroj B je $40/produkt.

Tam sú dve obmedzenia:

  • musíme pokryť dopyt 50 produktov za mesiac (x+y >= 50)
  • lacný stroj (A) možno len vtedy, výroba 40 výrobkov za mesiac (x<=40)

Tak som vytvoril nasledujúce Pyomo kód:

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

Funguje to ok, s zrejmé, riešenie x=40;y=10 (Cena = 1600)

Ak sa však začneme používať stroj B, tam bude stanovená pokuta vo výške 300 $nad nákladmi.

Snažil som sa s

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 ja si nasledujúce chybové hlásenie

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.

Neviem, ako implementovať stav, patrí pokutu do cieľa funkciu prostredníctvom Pyomo kód.

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

Najlepšiu odpoveď

1

Od m.y je Varnie je možné použiť if vyhlásenie s ním. Vždy môžete použiť binárna premenná, pomocou Big M prístup ako Airsquid to povedal. Tento prístup je zvyčajne neodporúča, pretože to zmení problém z LP do MILP, ale je to účinné.

Stačí vytvoriť nový Binary Var:

model.bin_y = Var(domain=Binary)

Potom obmedzenia model.y ak chcete byť nula, ak model.bin_y je nula, alebo iné, mať ľubovoľnú hodnotu medzi jeho medziach. Používam viazaný 100 tu, ale môžete dokonca použiť dopytu:

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

potom, v váš cieľ stačí použiť novú pevnú hodnotu 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

Ďakujeme, že ste @pybegginer, veľmi dobre vysvetlené :-) som sa ísť hlbšie do používania Veľké M.
Hookstark

Pre unbounded Vars budete musieť použiť veľmi veľké hodnoty viazaný, ako 1E6. V tento druh problému, budete musieť skontrolovať riešiteľ tolerancia Binárne, pretože to môže stane, že bin_y je cca. nula, ale y je stále väčší ako nula: napríklad, ak hranice sú stanovené ako 1E6 a binárne tolerancia je 1E-6, bin_y je pridelený na 1E-7(veľmi blízko k nule), ale výsledný obmedzenie y<=5 umožňuje Y byť väčší ako nula. V každom prípade, len skontrolovať tieto hodnoty pri model je vyriešený
pybegginer

V iných jazykoch

Táto stránka je v iných jazykoch

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