如何编写约束以检查变量是否在两个值之间界定

时间:2018-07-05 20:38:52

标签: linear-programming pyomo integer-programming

有人知道什么是指示模型变量是否在某些值之间界定的好方法吗?例如,当0 <=变量x <= 200时,指标1 = 1,否则为0,当200 <=变量x <= 300时,indicator2 =1。

一个用例是计算重量相关的运输成本,例如如果货物重量不足200磅,则成本为z / lb美元;如果货物重量超过200磅且小于300磅,则成本为y / lb。

最小化W1 * z + W2 * y

重量= W1 + W2

0 <= W1 <= 200 * X1

200 * X2 <= W2 <= 300 * X2

X1 + X2 = 1

X1,X2二进制

重量,W1,W2> = 0

以上是我针对这种情况提出的表述。但是,现在我要检查200多个值的存储桶,因此此公式似乎不够有效。我想知道是否有更好的方法对此建模?

1 个答案:

答案 0 :(得分:0)

此问题也可以建模为广义析取程序(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()