【发布时间】:2018-10-12 14:40:10
【问题描述】:
我想优化CHP plant 在请求的电源配置文件上的操作。因此,我定义了一个功率配置文件,热电联产工厂应尽可能遵循该配置文件。 必须应用多个界限和约束来表示 CHP 工厂的实际运行。例如,这包括 CHP 可以打开或关闭,并且在打开时,其功率调制只能设置为特定的百分比范围。
下面是一个简短的解释的最小工作示例:
import scipy.optimize as opt
import numpy as np
x = np.arange(200) # dummy x vector
poly_profile = np.array( # 7th degree polynome fit of profile
[-2.14104340e-11, 1.85108903e-08, -6.66697810e-06, 1.29239710e-03,
-1.45110876e-01, 9.40324129e+00, -3.24548750e+02, 4.60006330e+03])
poly_fun = np.poly1d(poly_profile) # make poly fun
profile = poly_fun(x[65:196])
x0 = np.zeros_like(profile) # all zeros as starting values
def optifun(x, profile): # define minimization fun
return - np.sum(profile * x)
bnds_hi = opt.Bounds(0.3, 1) # upper bounds
bnds_lo = opt.Bounds(0, 0) # lower bounds
res = opt.minimize(
optifun, x0, args=(profile), bounds=bnds_hi,
constraints={'type': 'eq', 'fun': lambda x: np.sum(x*40) - 2000},
method='SLSQP')
plt.plot(res.x)
plt.plot(profile)
所以这些是我想要使用的界限:
-
(x == 0) or (0.3 <= x <= 1),对于数组中的任意值x
这意味着总 CHP 功率的调制度 x 可以是 0(关闭)或>0.3和<= 1。但我可以指定下限 OR 上限。仅指定上限就不可能“关闭 CHP”,而将下限设置为bnds_lo = opt.Bounds(0, 1)
将使热电联产工厂能够在不现实的运行点(功率调制的 0% 到 30% 之间)运行。
有没有办法让这个工作在最小工作示例中指定的范围内工作?具体来说:我可以同时设置两种边界,比如bounds=[bnds_lo, bnds_hi]吗?
我想这是一个混合整数线性规划问题,但 COBYLA 或 SLSQP 不应该能够处理这个问题吗?如果没有:是否有任何解决方法?
以及我想使用的约束:
-
np.sum(x*40) - 450
将热输出限制为某些热存储容量。这里 40 是热输出功率,而 450 是剩余存储容量。这很容易实现。 -
限制 CHP 工厂的启动次数。作为一个例子,我们假设
bnds_lo = opt.Bounds(0, 1) # lower bounds res = opt.minimize( optifun, x0, args=(profile), bounds=bnds_lo, constraints={'type': 'eq', 'fun': lambda x: np.sum(x*40) - 1000}, method='SLSQP')这导致热电联产工厂运行 3 个周期。有没有办法限制这个?我正在考虑添加一个特定的约束函数,该函数在前导 0 之后计算正差异,但我无法完成类似的工作(例如,由于大多数
x不完全为 0,因为边界设置为 @987654332 @.但是其他问题也可能是原因)... - 设置 CHP 工厂的最短连续运行时间。这意味着至少有 5 个连续的
x != 0应该是有利的。我想过尝试与上一点类似的东西(限制启动次数),但也无法找到有用的东西。这是迄今为止最不重要的问题。
为了解决这些问题,我也尝试使用
scipy.optimize.LinearConstraings 和 NonlinearConstraings
但是method='trust-constr' 需要一个 jac(据我在 github 上阅读,这似乎是一个错误),因此我无法使其工作。
有什么方法可以让我完成这项工作吗?尤其是指定多个边界很重要。
提前致谢!
真诚地, 斯科蒂
【问题讨论】:
-
由于问题的离散性(开关决策),这些类型的电力调度模型通常使用混合整数规划模型来解决。边界
(x = 0) or (0.3 <= x <= 1)通常被描述为 x 是一个半连续变量。 -
感谢您的回答。我想避免使用像 pyomo 这样的 MILP 工具,以减少我的程序对其他模块的依赖。在一个更大的仿真程序中,每隔几步就会调用这种优化,并将用于设置仿真中的一些变量。因此,我真的很想避免使用过于复杂的优化来保持良好的性能。如果没有直接的方法来实现离散边界,我仍然可以在优化后手动裁剪它们。这当然是最坏的情况,但还是可以的,因为每隔几步就会执行一次优化,因此会出错
-
会很小。但我也无法弄清楚如何限制启动次数。关于如何做到这一点的任何想法?
-
只关注约束
(x == 0) or (0.3 <= x <= 1):scipy 最小化器无法处理这种类型的约束。要为此使用 scipy,您必须进行两次最小化,一次使用x == 0,再次使用0.3 <= x <= 1,然后选择最佳答案。 -
好的,所以我想我只需要使用
0 <= x <= 1或 milp 优化器来完成。谢谢!对处理约束有什么建议吗?
标签: python numpy optimization scipy