0

我正在尝试使用 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

4

1 回答 1

0

您可以以矩阵形式编写约束-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)
于 2021-04-07T07:06:27.113 回答