使用 scipy.optimize.minimize 解决优化问题时出现意外的解决方案

Unexpected solution when using scipy.optimize.minimize to solve a optimization problem

提问人:Broly Cjw 提问时间:11/8/2023 最后编辑:Broly Cjw 更新时间:11/9/2023 访问量:74

问:

我试图在scipy中表达以下优化问题。

enter image description here

假设 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]

python 数学 scipy-优化

评论

3赞 Scott Hunter 11/8/2023
你得到了什么结果,你期待什么,你为什么期待它?
0赞 Reinderien 11/8/2023
似乎你已经命名了 alpha ,这是一个坏主意。此外,alpha 实际上应该派生自 C。你能提供值吗?xr
0赞 Reinderien 11/8/2023
C 是否已知?
0赞 Broly Cjw 11/8/2023
我们试图求解 alpha,而 C 可以从 alpha 派生出来。r 的值:[0.96366965 0.93341242 0.90676733 0.88186071 0.8582291 0.83472442 0.80977363 0.783683 0.75743122 0.73259614]
0赞 Broly Cjw 11/8/2023
更新了问题以包括预期的 C 和已知的 R

答:

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]