使用IBM CPLEX python API的分段函数,但无法解决问题

Using the piecewise function of the IBM CPLEX python API, but the problem cannot be solved

我尝试使用 MILP(混合整数线性规划)来计算单元组合问题。 (单位承诺:试图找到发电机最佳调度的优化问题) 因为发电机功率和成本之间的关系是二次函数,所以我用分段函数将功率转换成成本。

enter image description here

我修改本页答案:

简单的程序结构是这样的::

from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')

#after 4 buses, additional buses of a given size are cheaper
f1=mdl.piecewise(0, [(0,0),(4,2000),(10,4400)], 0.8) 
f2=mdl.piecewise(0, [(0,0),(4,1600),(10,3520)], 0.8) 
cost1= f1(nbbus40)
cost2 = f2(nbbus30)

mdl.minimize(cost1+ cost1)
mdl.solve()
mdl.report()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value) 

这给出了

* model buses solved with objective = 3520.000
nbBus40  =  0
nbBus30  =  10.0 

答案很完美,但无法应用我的示例。 我用一个分段函数制定了功率和成本之间的分段线性关系,得到了一个新的对象(cost1),然后计算这个对象的最小值。 以下是我的实际代码(简单): enter image description here(min1,miny1),(pw1_1,pw1_1y),(pw1_2,pw1_2y),(max1,maxy1)上的断点是功率成本曲线

pwl_func_1phase = ucpm.piecewise(0, [(0,0),(min1,miny1), (pw1_1,pw1_1y),(pw1_2,pw1_2y),(max1,maxy1)], 0)
#df_decision_vars_spinning is a dataframe store Optimization variables
df_decision_vars_spinning.at[(units,period),'variable_cost'] = pwl_func_1phase(df_decision_vars_spinning.at[(units,period),'production'] )

total_variable_cost = ucpm.sum((df_decision_vars_spinning.variable_cost))
ucpm.minimize(total_variable_cost )

不知道是什么原因导致这个优化问题无法解决。 这是我的完整代码:https://colab.research.google.com/drive/1JSKfOf0Vzo3E3FywsxcDdOz4sAwCgOHd?usp=sharing

不是答案,只是为了说明我的评论。

假设我们有成本曲线

cost = α + β⋅power^2

此外,我们正在最大限度地降低成本。

我们可以用几条线性曲线来近似。这里我画了几个:

假设每条线性曲线的形式为

cost = a(i) + b(i)⋅power

for i=1,...,nn=线性曲线数)。

很容易看出我们写的是:

min cost
cost ≥ a(i) + b(i)⋅power   ∀i

我们对二次成本曲线有很好的近似。这正是我在评论中所说的。

这里没有使用二进制变量。

使用无限制版本的 CPLEX,您的模型可以求解(尽管非常慢)。这里有两个想法可以更好地控制 solve()

中发生的事情
  1. 使用 solve(log_output=True) 打印日志:您会看到差距在缩小
  2. 设置 mip 间隙:将 mip 间隙设置为 5% 在 36 秒停止求解

    ucpm.parameters.mip.tolerances.mipgap = 0.05

    ucpm.solve(log_output=真)