【发布时间】:2022-09-17 23:55:33
【问题描述】:
我正在尝试使用解决多元优化问题python 与 scipy. 让我定义我工作的环境:
搜索参数:
和问题本身:
(在我的情况下日志L功能很复杂,所以我将用微不足道的功能代替它,从而产生类似的问题。因此,在这个例子中,我没有完全使用函数参数,但为了问题的一致性,我将它们包括在内)。
我使用以下约定将参数存储在单个平面数组中:
这是脚本,应该可以解决我的问题。
import numpy as np
from scipy import optimize as opt
from pprint import pprint
from typing import List
_d = 2
_tmax = 500.0
_T = [[1,2,3,4,5], [6,7,8,9]]
def logL(args: List[float], T : List[List[float]], tmax : float):
# simplified - normaly using T in computation, here only to determine dimension
d = len(T)
# trivially forcing args to go \'out-of constrains\'
return -sum([(args[2 * i] + args[2 * i + 1] * tmax)**2 for i in range(d)])
def gradientForIthDimension(i, d, t_max):
g = np.zeros(2 * d + 2 * d**2)
g[2 * i] = 1.0
g[2 * i + 1] = t_max + 1.0
return g
def zerosWithOneOnJth(j, l):
r = [0.0 for _ in range(l)]
r[j] = 1.0
return r
new_lin_const = {
\'type\': \'ineq\',
\'fun\' : lambda x: np.array(
[x[2 * i] + x[2 * i + 1] * (_tmax + 1.0) for i in range(_d)]
+ [x[j] for j in range(2*_d + 2*_d**2) if j not in [2 * i + 1 for i in range(_d)]]
),
\'jac\' : lambda x: np.array(
[gradientForIthDimension(i, _d, _tmax) for i in range(_d)]
+ [zerosWithOneOnJth(j, 2*_d + 2*_d**2) for j in range(2*_d + 2*_d**2) if j not in [2 * i + 1 for i in range(_d)]]
)
}
最后优化
logArgs = [2 for _ in range(2 * (_d ** 2) + 2 * _d)]
# addditional bounds, not mentioned in a problem, but suppose a\'priori knowledge
bds = [(0.0, 10.0) for _ in range(2 * (_d ** 2) + 2 * _d)]
for i in range(_d):
bds[2*i + 1] = (-10.0, 10.0)
res = opt.minimize(lambda x, args: -logL(x, args[0], args[1]),
constraints=new_lin_const, x0 = logArgs, args=([_T, _tmax]), method=\'SLSQP\', options={\'disp\': True}, bounds=bds)
但是在检查结果时,我得到:
pprint(res)
# fun: 2.2124712864600578e-05
# jac: array([0.00665204, 3.32973738, 0.00665204, 3.32973738, 0. ,
# 0. , 0. , 0. , 0. , 0. ,
# 0. , 0. ])
# message: \'Optimization terminated successfully\'
# nfev: 40
# nit: 3
# njev: 3
# status: 0
# success: True
# x: array([ 1.66633206, -0.00332601, 1.66633206, -0.00332601, 2. ,
# 2. , 2. , 2. , 2. , 2. ,
# 2. , 2. ])
特别是:
print(res.x[0] + res.x[1]*(501.0))
# -3.2529534621517087e-13
所以结果超出了限制区域...... 我试图遵循文档,但对我来说它不起作用。我很乐意听到任何关于哪里出了问题的建议。
标签: python optimization scipy scipy-optimize