如何在scipy优化中定义变量之间的相互依赖(python 2.7)?

2 投票
1 回答
524 浏览
提问于 2025-04-18 12:37

我需要优化一个复杂的函数,这个函数由几个相互依赖的元素组成,像是要求这些元素的和等于1,并且每个元素的值都在0到1之间。

为此,我使用了scipy库里的优化工具来最小化这个函数,并设置了边界条件。

但是我不知道怎么指定这些元素之间的相互依赖关系。我使用了一个额外的变量(x100),并为它设置了边界条件(0, 0),同时在一个函数里规定了x100=1-x1-x2-x3-x4-x5。

可惜的是,结果并没有正常工作。我需要修改def arg,但我不知道该怎么做。

我该如何指定这些元素之间的相互依赖关系,以确保sum_x等于1呢?

from scipy.optimize import minimize
from numpy import random, mean, var, std

def arg(x1,x2,x3,x4,x5,x100):
    x100=1-x1-x2-x3-x4-x5
    r = mean(x1*x2*x3*x4*x5)*std(x1+x2-x3+x4-x5)
    return r

def new_arg(x):
    return -arg(*x)


fun = new_arg
x0 = (0.5, 0.5, 0.5, 0.5, 0.5,\
    0.0)
res = minimize(fun, x0, method='SLSQP', bounds = ((0, 1),(0, 1), (0, 1),\
                                             (0, 1),(0, 1),(0, 0)))
kpi_opt = res.x
sum_x=res.x[0]+res.x[1]+res.x[2]+res.x[3]+res.x[4]

print 'kpi_opt',kpi_opt
print 'sum of xi = ',sum_x

1 个回答

1

在你的情况下,我觉得你需要进一步定义一个等式函数,这个函数由 f_eqcons 参数来约束。这个函数需要是可以调用的,并且在成功优化的问题中,它应该返回0(或者一个只包含0的数组)。根据你给出的简单例子:

import scipy.optimize as ss
def f(x):
    x1, x2, x3, x4, x5=x
    return -np.mean(x1*x2*x3*x4*x5)*np.std(x1+x2-x3+x4-x5)

x0=(0.5, 0.5, 0.5, 0.5, 0.5)

def eq_f(x):
    x1, x2, x3, x4, x5=x
    return sum(x)

res=ss.fmin_slsqp(f, x0, f_eqcons=eq_f, bounds = ((0, 1),(0, 1), (0, 1),(0, 1),(0, 1)))

结果:

Optimization terminated successfully.    (Exit mode 0)
            Current function value: -0.0
            Iterations: 1
            Function evaluations: 8
            Gradient evaluations: 1
In [11]:

res
Out[11]:
array([  0.00000000e+00,   5.55111512e-17,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00])

撰写回答