Как написать ограничения, чтобы проверить, ограничена ли переменная двумя значениями

Кто-нибудь знает, что является хорошим способом указать, ограничена ли переменная модели определенными значениями? Например, индикатор1 = 1, когда 0‹= переменная x ‹=200, иначе 0, индикатор2 = 1, когда 200‹= переменная x ‹= 300.

Одним из вариантов использования этого является расчет стоимости доставки в зависимости от веса, например. если посылка весит менее 200 фунтов, то она стоит z$ за фунт; если посылка весит более 200 фунтов и менее 300 фунтов, то она стоит y долларов за фунт.

Минимизировать W1*z + W2*y

Вес = W1 + W2

0 <= W1 <= 200*X1

200*X2 <= W2 <= 300*X2

X1+ X2 = 1

X1, X2 binary

Вес, П1, П2 >= 0

Выше приведена формулировка, которую я придумал для этой ситуации. Однако теперь мне нужно проверить более 200 блоков значений, так что эта формулировка кажется недостаточно эффективной. Мне интересно, есть ли лучшие способы смоделировать это?


person Ivy Yiling Jiang    schedule 05.07.2018    source источник
comment
В этой формулировке нет ничего плохого: она может работать лучше, чем вы думаете (при условии, что вы используете способный решатель MIP).   -  person Erwin Kalvelagen    schedule 06.07.2018


Ответы (1)


Эту проблему также можно смоделировать как обобщенную дизъюнктивную программу (GDP). Он более подробный, но более описательный.

from pyomo.environ import *
from pyomo.gdp import *
m = ConcreteModel()
m.total_weight_cost = Var(domain=NonNegativeReals)
m.weight = Var(domain=NonNegativeReals)
m.weight_buckets = RangeSet(2)
m.weight_bucket_lb = Param(m.weight_buckets, initialize={1: 0, 2: 200})
m.weight_bucket_ub = Param(m.weight_buckets, initialize={1: 200, 2: 300})
m.weight_bucket_cost = Param(m.weight_buckets, initialize={1: z, 2: y})
m.weight_bucket_disjunction = Disjunction(expr=[
    [m.total_weight_cost == m.weight_bucket_cost[bucket] * m.weight,
     m.weight_bucket_lb[bucket] <= m.weight,
     m.weight <= m.weight_bucket_ub[bucket]
    for bucket in m.weight_buckets]
])
TransformationFactory('gdp.bigm').apply_to(m)
SolverFactory('gurobi').solve(m, tee=True)
m.display()
person Qi Chen    schedule 07.07.2018