Как написать ограничения, чтобы проверить, ограничена ли переменная между двумя значениями - PullRequest
0 голосов
/ 05 июля 2018

Кто-нибудь знает, как правильно указать, ограничена ли переменная модели между определенными значениями? Например, индикатор1 = 1, когда 0 <= переменная x <= 200, иначе 0, индикатор2 = 1, когда 200 <= переменная x <= 300. </p>

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

Свернуть W1 * z + W2 * y

Вес = W1 + W2

0 <= W1 <= 200 * X1 </p>

200 * X2 <= W2 <= 300 * X2 </p>

X1 + X2 = 1

X1, X2 двоичный

Вес, W1, W2> = 0

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

1 Ответ

0 голосов
/ 07 июля 2018

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

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