首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有多个界、约束和连续域的scipy.optimize

具有多个界、约束和连续域的scipy.optimize
EN

Stack Overflow用户
提问于 2018-10-12 14:40:10
回答 1查看 4.6K关注 0票数 1

我想优化热电联产厂在请求的电源配置文件上的操作。因此,我定义了一个电力概况,应该尽可能多地遵循热电联产厂的要求。必须应用多个边界和约束来表示CHP工厂的实际操作。例如,CHP可以打开或关闭,同时它的功率调制只能设置为一个特定的百分比范围。

下面是一个包含简短解释的最低工作示例:

代码语言:javascript
运行
复制
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中的任何值 这意味着x,即总CHP功率的调制度,既可以是0(关闭),也可以是>0.3<= 1。但我可以指定下界上界。只有指定上界,才不可能“关闭CHP”,同时将下界设置为bnds_lo = opt.Bounds(0, 1)。 将使热电联产厂能够在非实际操作点(功率调制的0%至30%之间)运行。 是否有任何方法使此工作与最低工作示例中指定的界限?具体而言:我可以同时设置两种边界,比如bounds=[bnds_lo, bnds_hi]吗? 我想这是一个混合整数线性规划问题,但COBYLA或SLSQP不应该处理这个问题吗?如果没有,有什么解决办法吗?

我想使用的约束是:

  • np.sum(x*40) - 450 将热输出限制在一定的蓄热能力之内。这里40是热输出功率,450是剩余存储容量。这是相当容易实现的。
  • 限制热电联产厂的开工次数。举个例子,让我们假设 bnds_lo = opt.Bounds(0,1) #下界res = opt.minimize( optifun,x0,args=(profile),bounds=bnds_lo,constraints={'type':'eq',‘args=’:lambda x: np.sum(x*40) - 1000},方法=‘SLSQP’) 这就导致了三个阶段的热电联产厂的运行。有什么办法限制这件事吗?我正在考虑添加一个特定的约束函数,该函数在前导0之后计算正差,但我无法完成类似的工作(例如,因为大多数x都不是0,因为边界设置为(0, 1) )。但其他问题也可能是原因).
  • 设置热电联产厂的最低连续运行时间。这意味着它应该是有利的,至少,比如说5,连续的x != 0。我想尝试类似于我在最后一点(限制开始的次数),但也无法找到一些有用的东西。这是迄今为止最不重要的问题。

为了解决这些问题,我也尝试使用scipy.optimize.LinearConstraingsNonlinearConstraings,但是method='trust-constr'需要一个jac (就我在github上读到的内容而言,这似乎是一个bug),因此我无法使它工作。

有什么办法能让这件事成功吗?特别是指定多个边界非常重要。

提前感谢!

真的,斯科蒂

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-12 11:19:32

代码中的profile * x0给出了

"ValueError:操作数不能与形状(131,) (200 )一起广播“。

猜测一下,x_t是一个产品onoff_t * xon_t吗?

onoff_t =0或1

0.3 <= xon_t <= 10 .. T的每个t

对于T = 5,有2^5个可能的onoff序列,00000,00001,00010 .11111?

如果是这样的话,使用固定权重函数sum 0:T w_t * onoff_t * xon_t最大化w_t是很简单的:

其中w_t <= 0onoff_t = 0,off

其中w_t > 0onoff_t = 1,on,xon_t = 1,max。

所以这不可能是你的问题--请澄清。

如果onoff_t被进一步限制只能切换两次,0.1...0.,那么可能的序列的数量就足够小,只需尝试所有这些序列,如下所示:

代码语言:javascript
运行
复制
def pulse_generator( T=200, minwidth=5 ):
    """ -> arrays of T floats, 0... 1... 0... """
    for t0 in xrange( 1, T ):
        for t1 in xrange( t0 + minwidth, T ):
            pulse = np.zeros( T )
            pulse[t0:t1] = 1
            yield pulse

for pulse in pulse_generator( T ):
    print "pulse:", pulse
    optimize myfunction( pulse * xon ), 0.3 <= xon <= 1

转换4次,0.1...0..1...0.很相似。(对于给定的T,有多少这样的脉冲?见维基百科星条旗

补充说:我不是专家,但是开着aka的爆炸控制是不是对微小的变化非常敏感,早一点还是晚些?一个程序(Mer)可以花很多时间在噪音中抖动。两个阶段,粗网格然后细网格

  1. 将时间0:T分成10段,运行所有2^10 = 1024个开断序列。 1a.仔细看看最好的--有什么模式吗?
  2. 移动他们的边缘半步,T/ 20。

另见:谷歌“离散优化”多重网格..。和网格搜索

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52781901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档