【问题标题】:Differential evolution multiple constraints for beginners初学者的差分进化多重约束
【发布时间】:2021-07-02 16:31:52
【问题描述】:

我正在尝试使用 scipy optimize different_evolution 优化以下功能:

def obj_fun_cal(x,df_TZ_input,df_TZ_target):
v=(x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15],x[16],x[17],x[18],x[19],x[20])
prodmx=df_TZ_input*v
sum_vector=prodmx.sum(axis=1)
MAE=np.mean(np.absolute(df_TZ_target-sum_vector))
penalty=0
if x[1]<=x[0]:
    penalty+=1000
if x[2]<=x[1]:
    penalty+=1000
if x[3]<=x[2]:
    penalty+=1000
if x[4]<=x[3]:
    penalty+=1000
if x[5]<=x[4]:
    penalty+=1000
if x[6]<=x[5]:
    penalty+=1000
if x[7]<=x[6]:
    penalty+=1000
if x[8]<=x[7]:
    penalty+=1000
if x[9]<=x[8]:
    penalty+=1000
if x[10]<=x[9]:
    penalty+=1000
if x[11]<=x[10]:
    penalty+=1000
if x[12]<=x[11]:
    penalty+=1000
if x[13]<=x[12]:
    penalty+=1000
if x[14]<=x[13]:
    penalty+=1000
if x[15]<=x[14]:
    penalty+=1000
if x[16]<=x[15]:
    penalty+=1000
if x[17]<=x[16]:
    penalty+=1000
if x[18]<=x[17]:
    penalty+=1000
if x[19]<=x[18]:
    penalty+=1000
if x[20]<=x[19]:
    penalty+=1000

     
eval_num=MAE+penalty
return eval_num

代码在 DE 上运行良好,但我正在寻找一种更智能的方法来强制每个变量必须大于前一个。 我想使用 Constraint 参数,但我不知道如何在正确的 sintax 中编写线性约束。我见过人们使用字典,其他人使用专用功能(总是使用最小化......不幸的是没有 DE 的例子),我很困惑......并且卡住了:P

如果有人能提供一段适合这个问题的代码,那将是巨大的帮助。

谢谢

PS:使用建议的方法编辑结果为 f(x)=inf

【问题讨论】:

    标签: python optimization constraints scipy-optimize differential-evolution


    【解决方案1】:

    您可以将约束写成矩阵形式-infty &lt;= B @ x &lt;= 0,其中@ 表示矩阵乘法,B 是矩阵

    ( -1  1  0  0 0 .... 0  0)
    ( 0  -1  1  0 0 .... 0  0)
    ( 0   0 -1  1 0 .... 0  0)
    ( .                      )
    ( .                      )
    ( .                      )
    ( 0   0  0  0 0 .... -1 1)
    ( 0   0  0  0 0 ....  0 0)
    

    那么你只需要传递一个约束:

    from scipy.optimize import NonlinearConstraint, differential_evolution
    
    # Assuming (n,) is the shape of x and v
    B = np.eye(n, k = 1) - np.eye(n)
    B[-1,-1] = 0.0
    
    # Define the constraint: -np.inf <= B @ x <= 0.0
    def constr_fun(x): return B @ x
    nlc = NonlinearConstraint(constr_fun, -np.inf, 0.0)
    
    # Your objective function
    def obj_fun_cal(x,df_TZ_input,df_TZ_target):
        v = (x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15],x[16],x[17],x[18],x[19],x[20])
        prodmx = df_TZ_input*v
        sum_vector = prodmx.sum(axis=1)
        MAE = np.mean(np.absolute(df_TZ_target-sum_vector))
        return MAE
    
    # Pass the constraint..
    result = differential_evolution(obj_fun_cal, args=(df_TZ_input, df_TZ_target), constraints=nlc)
    

    【讨论】:

    • 非常感谢@joni,不幸的是我不太热衷于使用 lambda。没有它有可能吗?
    • @Steve 当然,我编辑了我的答案。请注意,lambda 只是一个匿名函数,即 f = lambda x: x**2def f(x): return x**2 相同。
    • 谢谢,我已经使用了您的代码,它可以正常工作,但现在 DE 在每一步都返回 f(x)=inf。我该如何处理?
    • 请提供MWE。不知道df_TZ_inputdf_TZ_target 就很难提供帮助
    • 我认为问题在于 B = np.eye(n, k = 1) - np.eye(n) 创建一个平方矩阵,其中最后一个元素 n,n 是 -1 而不是 1你在开头说的。
    猜你喜欢
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 2015-08-03
    相关资源
    最近更新 更多