提问人:Broly Cjw 提问时间:11/8/2023 最后编辑:Broly Cjw 更新时间:11/9/2023 访问量:74
使用 scipy.optimize.minimize 解决优化问题时出现意外的解决方案
Unexpected solution when using scipy.optimize.minimize to solve a optimization problem
问:
我试图在scipy中表达以下优化问题。
假设 r 是一个已知数组,其值为: [0.96366965, 0.93341242, 0.90676733, 0.88186071, 0.8582291, 0.83472442, 0.80977363, 0.783683, 0.75743122, 0.73259614]
def objective_function(x):
e_t = np.zeros(10)
e_t[0] = 1 - 1 / (1 + r[0])
for t in range(1, 9):
sub = 0
for ti in range(0, t):
sub += np.sum(x[: (ti + 1)]) / (1 + r[ti]) ** (ti + 1)
e_t[t] = 1 - 1 / (1 + r[t]) ** (t + 1) - sub
e_t[9] = 0
return np.sum(e_t**2)
def constraint_function(t):
def calculate_et(x):
sub = 0
for ti in range(0, t):
sub += np.sum(x[: (ti + 1)]) / (1 + r[ti]) ** (ti + 1)
e_t = 1 - 1 / (1 + r[t]) ** (t + 1) - sub
return e_t
return calculate_et
x0 = np.zeros(10)
cons = (
{"type": "ineq", "fun": constraint_function(1)},
{"type": "ineq", "fun": constraint_function(2)},
{"type": "ineq", "fun": constraint_function(3)},
{"type": "ineq", "fun": constraint_function(4)},
{"type": "ineq", "fun": constraint_function(5)},
{"type": "ineq", "fun": constraint_function(6)},
{"type": "ineq", "fun": constraint_function(7)},
{"type": "ineq", "fun": constraint_function(8)},
{"type": "ineq", "fun": constraint_function(9)},
)
result = minimize(
objective_function,
x0,
bounds=Bounds(lb=0),
constraints=cons,
)
alpha = result.x
c = np.zeros(10)
c[0] = alpha[0]
for i in range(1, 10):
c[i] = alpha[i-1] + alpha[i]
但是,我得到的解决方案与预期值相差很大,因此我认为这不是解决问题的正确方法。我目前的方法有什么问题,还有其他方法可以解决吗?
我得到的 c 解决方案是 [9.02212140e-01 9.02212140e-01 2.39808173e-13 1.06359366e-13 4.57411886e-14 1.75415238e-14 6.16173779e-15 2.17534324e-15 4.67095103e-16 1.25975522e-17]
预期解更接近 [0.0318, 0.0318, 0.0318, 0.0318, 0.0318, 0.0318, 0.0320, 0.0325, 0.0336, 0.0353]
答:
0赞
Reinderien
11/9/2023
#1
检查你的数学。对于您当前的目标,“预期解决方案”的目标成本比能够提出的目标成本高得多:minimize
from functools import partial
import numpy as np
from scipy.optimize import minimize, Bounds, NonlinearConstraint
def calculate_e(alpha: np.ndarray, t: np.ndarray, r: np.ndarray) -> np.ndarray:
den = 1/(1 + r[:-1])**t
inner = alpha[:-2].cumsum() * den[:-1]
e19 = 1 - den - np.concatenate(([0], inner.cumsum()))
return np.concatenate((e19, [0]))
def objective_function(alpha: np.ndarray, t: np.ndarray, r: np.ndarray) -> float:
e = calculate_e(alpha, t, r)
return e.dot(e)
def main() -> None:
r = np.array((
0.96366965, 0.93341242, 0.90676733, 0.88186071, 0.85822910,
0.83472442, 0.80977363, 0.78368300, 0.75743122, 0.73259614,
))
n = r.size
t = np.arange(1, n)
c_expected = np.array((
0.0318, 0.0318, 0.0318, 0.0318, 0.0318,
0.0318, 0.0320, 0.0325, 0.0336, 0.0353,
))
alpha_expected = np.concatenate((
c_expected[:1],
np.diff(c_expected),
))
result = minimize(
fun=objective_function,
x0=alpha_expected,
args=(t, r),
bounds=Bounds(lb=0),
constraints=NonlinearConstraint(
fun=partial(calculate_e, t=t, r=r),
lb=0, ub=np.inf,
),
tol=1e-9,
)
assert result.success, result.message
alpha = result.x
c = alpha.cumsum()
print(f' Initial cost: {objective_function(alpha_expected, t, r):.2f}')
print(f'Solution cost: {result.fun:.2f}')
print('α =')
print(alpha)
print('C =')
print(c)
print('e =')
print(calculate_e(alpha, t, r))
if __name__ == '__main__':
main()
Initial cost: 6.71
Solution cost: 0.35
α =
[9.05392583e-01 1.38775468e-16 4.16322395e-17 2.77550652e-17
0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
1.10000000e-03 1.70000000e-03]
C =
[0.90539258 0.90539258 0.90539258 0.90539258 0.90539258 0.90539258
0.90539258 0.90539258 0.90649258 0.90819258]
e =
[4.90749373e-01 2.71411502e-01 1.52473537e-01 8.63851746e-02
4.87947275e-02 2.68482231e-02 1.36020676e-02 5.32970702e-03
2.22044605e-16 0.00000000e+00]
评论
x
r