Pyomo: Come prevedono una penale nella funzione obiettivo

0

Domanda

Sto cercando di ridurre al minimo il costo di produzione di un prodotto con due macchine. Il costo della macchina è di $30/prodotto e il costo della macchina B è di $40/prodotto.

Ci sono due vincoli:

  • dobbiamo coprire un fabbisogno di 50 prodotti al mese (x+y >= 50)
  • il mercato della macchina (Una) può produrre solo 40 prodotti al mese (x<=40)

Così ho creato la seguente Pyomo codice:

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

Funziona bene, con l'ovvia soluzione x=40;y=10 (Costo = 1600)

Tuttavia, se si inizia a utilizzare la macchina B, ci sarà una penalità forfettaria di $300 sul costo.

Ho provato 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

Ma ottengo il seguente messaggio di errore

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.

Io non come implementare la condizione di includere il rigore funzione obiettivo attraverso la Pyomo codice.

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

Migliore risposta

1

Dal m.y è un Varnon è possibile utilizzare il if dichiarazione con esso. È sempre possibile utilizzare una variabile binaria utilizzando il Big M approccio Airsquid detto. Questo approccio è di solito non è raccomandato, poiché si scopre che il problema LP in un MILP, ma è efficace.

Hai solo bisogno di creare un nuovo Binary Var:

model.bin_y = Var(domain=Binary)

Quindi vincolo model.y per essere uguale a zero se model.bin_y è pari a zero, o altro, essere un qualsiasi valore compreso tra i limiti. Io uso un limite di 100, ma è anche possibile utilizzare la domanda:

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

quindi, nel vostro obiettivo, applicare il nuovo valore fisso di 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

Grazie @pybegginer, spiegato molto bene :-) cercherò di approfondire l'uso di Big M.
Hookstark

Per unbounded Vars è necessario utilizzare un molto grande valore del legato, come 1E6. In questo tipo di problema, è necessario controllare due volte il risolutore di tolleranza al Binario, poiché non può escludersi che bin_y è di ca. zero, ma y è ancora maggiore di zero: per esempio, se i limiti sono fissati come 1E6 e il binario di tolleranza è 1E-6, bin_y viene assegnato a 1E-7(molto vicino allo zero), ma il conseguente vincolo è y<=5 consentendo Y maggiore di zero. Comunque, basta un doppio controllo tali valori quando il modello è risolto
pybegginer

In altre lingue

Questa pagina è in altre lingue

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