我试图解决一个简单的优化问题,但无法绕过错误“线性的正方向导数”,我想知道这里发生了什么,我没有看到任何问题的梯度,问题是凸的,但非线性。请参阅下面的代码作为参考:
import numpy as np
bounds = [(6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (6.274329865160556e-06, 14.919501068721157), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.0005248360152365689, 27.172072902944304), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635), (0.00014238207960809104, 60.130237219435635)]
maxcovers = {'x1;cost': 2.5, 'x2;cost': 2.5, 'x3;cost': 2.5}
maxjumps = {'x1;cost': 2.5, 'x2;cost': 2.5, 'x3;cost': 2.5}
paramvaluemappings = {"saturations": {0: np.full((1, 31), 0.234835),
1: np.full((1, 31), 0.339884),
2: np.full((1, 31), 0.583774)},
"timevariables": {0: np.full((1, 31), -1.206971),
1: np.full((1, 31), 0.36720),
2: np.full((1, 31), 1.0164)},
"adstock": {0: np.zeros((1)),
1: np.zeros((1)),
2: np.zeros((1))},
"intercept": np.full((1, 31), 0.7899)}
totalbudget = 194
x0 = [0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01000627432986516, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.01052483601523657, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091, 0.010142382079608091]
from scipy.optimize import minimize
cons = []
totalbudgetconstraint = {'type': 'ineq',
'fun': lambda x: totalbudget - sum(x)}
cons.append(totalbudgetconstraint)
def newobjective2(x, *args):
paramvaluemappingsordered = args[0]
horizon = args[3]
channels = args[4]
lookbackadstock = 4
previousxs = {0: np.array([0.06926, 0.70988, 0.00676, 1.4556, 0.0006, 0.0006]),
1: np.array([0.64502, 0.56519, 2.38517, 0.05514, 2.65093, 0.00538]),
2: np.array([0.15333, 0.01496, 0.00146, 1.57163, 1.84324, 5.86636])}
summed = 0
for idx, channel in enumerate(channels):
saturationentries = paramvaluemappingsordered['saturations'][idx]# .data[firstdimension,seconddimension, :]
timevariableentries = paramvaluemappingsordered['timevariables'][idx] #.data[firstdimension, seconddimension, :]
expenditurechannel = np.append(previousxs[idx],
x[idx * horizon: idx * horizon + horizon])
channelentry = timevariableentries * np.power(expenditurechannel, saturationentries)
summed += channelentry
intercept = paramvaluemappingsordered['intercept'] #.data[firstdimension, seconddimension,:]
summed += intercept
summed = summed[:, lookbackadstock:]
meanvalue = np.mean(summed, axis=0)
return -np.sum(meanvalue)
args = [paramvaluemappings, None, None, 25, ["x1;cost", "x2;cost", "x3;cost"]]
res = minimize(fun=newobjective2,
x0=x0,
args=(paramvaluemappings, None, None, 25, ["x1;cost", "x2;cost", "x3;cost"]),
constraints=cons,
method='SLSQP', # 'trust-constr', # 'SLSQP', # method='trust-constr',
bounds=bounds,
options={'maxiter': 500_0,
# 'xtol': 1e-20,
'disp': True, # ,
'xtol': 1e-5,
# 'verbose': 2
# ,
'ftol': 1e-8
}
)
print(res)
字符串
这是一个简单的分配问题,线性约束和非线性奖励函数,应该是可解的SLSQP,并应导致全局最优,因为问题是凸的。
将x 0更改为e.g += 1工作...我想想出一种自动设置x 0的方法,但不需要使用它。...也理解为什么会出现这个问题。
注意,初始x 0满足约束。
增加ftol也工作。。为xtol > 1 e-7。。我想知道为什么。
1条答案
按热度按时间w3nuxt5m1#
我发现我可以通过两个变化成功地优化这个函数。
1.将预算改写为线性约束。
字符串
这要求x的总和小于totalbudget。
1.**删除截距。**此函数在取均值之前向输出添加一个常数截距。
型
由于优化函数g(x)= f(x)+ c与优化f(x)相同,因此可以将这一行注解掉。
我认为这是有帮助的,因为
summed
包含了一堆相对于截距来说很小的数字,将一个大的数字添加到一个小的数字会导致组合数字失去精度。或者,如果您出于其他原因需要此截取,您可以将截取设置为有条件的,并且仅包含它而不优化函数。示例:
型
通过这些修改,我得到了以下结果:
型
我没有看到任何问题的梯度,问题是凸,但非线性
看看这个函数的梯度,我看到前25个变量相对于其他变量有很大的梯度。
型
这是minimize不能很好地容忍的事情,但是我不太了解你正在优化的函数的细节,不知道如何改进它。还有一点值得怀疑的是,有些变量具有完全相同的梯度-这表明你可以将其重新参数化为更少的变量。