差分进化对初学者的多重约束



我正试图用scipy优化微分进化来优化以下函数:

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

您可以用矩阵形式-infty <= B @ x <= 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)

最新更新