全部,
我正在编写一些代码,其中要求购买/出售至少100000个数据包。如果不可能,则应将其归零。
我为此尝试了很多东西,包括:
def objective_rule(model):
return sum(model.Prices[ProductCount]*model.Amount[ProductCount]*(model.Amount[ProductCount]>100000) for ProductCount in model.Products)
但这比预期的要慢。我想制定一个明确的约束条件。类似于:
def minTradesize_Constraint(model):
return ((model.Amount[ProductCount]>=100000)|
(model.Amount[ProductCount]==0.00) for ProductCount in model.Products)
我研究过指标函数,但Pyomo连续近似没有帮助。感谢任何帮助/指导。
基本上,您试图实现的是使model.Amount[ProductCount]
项取不连续值(零或更大或等于100000(。要实现这一点,首先,您基本上需要定义一个二进制变量:model.y = pyomo.Var(model.Products, within=pyomo.Binary)
。
然后您需要添加以下约束:
def minTradesize_Constraint1(model):
return (model.Amount[ProductCount] >= 100000 * y[ProductCount] for ProductCount in model.Products)
def minTradesize_Constraint2(model):
return (model.Amount[ProductCount] <= M * y[ProductCount] for ProductCount in model.Products)
其中M是一个足够大的数字(可以是model.Amount[ProductCount]
变量的实际上限(。
作为该公式的结果,如果y[ProductCount]
为零,则model.Amount[ProductCount]
项也将为零。如果模型现在想要使model.Amount[ProductCount]
变量取正值,则必须将二进制y[ProductCount]
设置为1,从而迫使model.Amount[ProductCount]
变得更大或等于100000。
注意:我已经用你在回答中所用的相同风格制定了约束条件。然而,如果我正确理解你的模型,我会说,例如,第一个约束应该是:
def minTradesize_Constraint1(model, ProductCount):
return (model.Amount[ProductCount] >= 100000 * y[ProductCount]
创建Pyomo约束时应添加for ProductCount in model.Products
部分。
以进一步简化解决方案。我添加了一个名为route_selected 的变量
model.route_selected = pe.Var(<a set, for me its routes == r>, domain=pe.Binary, initialize=0, within=pe.Binary)
model.route_selected = pe.Var(model.R, domain=pe.Binary, initialize=0, within=pe.Binary)
这是我的因变量看起来像
# Variable to solve, this is the variable that will be changed by solver to find a solution
# for each route, port, cust, year combination what should be supplied amount
model.x_rpcy = pe.Var(self.model.R, self.model.P, self.model.C, self.model.Y, domain=pe.NonNegativeIntegers, initialize=0)
然后添加这个约束
for y in self.model.Y:
for r in self.model.R:
lhs = sum(self.model.x_rpcy[r, p, c, y] for p in self.model.P for c in self.model.C)
vessel_size = 1000
self.model.const_route.add(lhs == vessel_size * self.model.route_selected[r])
model.const_route.add(lhs == vessel_size * model.route_selected[r])