使用fsolve优化Python scipy.optimize

使用fsolve优化Python scipy.optimize,python,scipy,Python,Scipy,我试图通过python找到19个引号和19个未知变量的解决方案,如下所示: import numpy as np from scipy.optimize import fsolve def f(x) : y = np.zeros(np.size(x)) y[0] = -29.79 + 1.795*x[1] + 6.33*x[0] + -0.305*x[3] - 0.024*x[1]*x[3] + 0.222*x[0]*x[3] -2.063*x[4] + 0.122*x[1]*

我试图通过python找到19个引号和19个未知变量的解决方案,如下所示:

import numpy as np
from scipy.optimize import fsolve

def f(x) :
    y = np.zeros(np.size(x))
    y[0] = -29.79 + 1.795*x[1] + 6.33*x[0] + -0.305*x[3] - 0.024*x[1]*x[3] + 0.222*x[0]*x[3] -2.063*x[4] + 0.122*x[1]*x[4] + 0.864*x[0]*x[4] + x[5] - x[6]
    y[1] = -23.269 + 1.795*x[0] + 4.547*x[2] - 0.342*x[1] - 0.024*x[0]*x[3] + 0.072*x[2]*x[3] - 0.052*x[1]*x[3] - 1.545*x[4] + 0.122*x[0]*x[4] + 0.367*x[2]*x[4] + 0.114*x[1]*x[4] + x[7] - x[8]
    y[2] = 0.587 + 4.547*x[1] + 0.046*x[3] + 0.072*x[1]*x[3] - 0.211*x[4] + 0.367*x[1]*x[4] + x[9] - x[10]
    y[3] = -1.657 - 0.305*x[0] - 0.230*x[1] + 0.046*x[2] - 0.024*x[0]*x[1] + 0.072*x[1]*x[2] + 0.111*x[0]**2.0 - 0.026*x[1]**2.0 + 0.78981 + x[11]**2.0
    y[4] = -0.106 - 2.063*x[0] - 1.545*x[1] - 0.211*x[2] + 0.122*x[0]*x[1] + 0.367*x[1]*x[2] + 0.432*x[0]**2.0 + 0.057*x[1]**2.0 + 1.34744 + x[12]**2.0
    y[5] = x[0] - 0.3 + x[13]**2.0
    y[6] = -x[0] + 0.1 + x[14]**2.0
    y[7] = x[1] - 80 + x[15]**2.0
    y[8] = -x[1] + 30 + x[16]**2.0
    y[9] = x[2] - 230 + x[17]**2.0
    y[10] = -x[2] + 200 + x[18]**2.0
    y[11] = 2*x[3]*x[11]
    y[12] = 2*x[4]*x[12]
    y[13] = 2*x[5]*x[13]
    y[14] = 2*x[6]*x[14]
    y[15] = 2*x[7]*x[15]
    y[16] = 2*x[8]*x[16]
    y[17] = 2*x[9]*x[17]
    y[18] = 2*x[10]*x[18]
    return y

x0 = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
x =fsolve(f, x0)

print ("x     = ", x)
print ("f(x)     = ", f(x))
我收到了以下结果:

C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\minpack.py:161: RuntimeWarning: The iteration is not making good progress, as measured by the 
  improvement from the last five Jacobian evaluations.
  warnings.warn(msg, RuntimeWarning)
x     =  [  9.76123765e-01   5.63951267e-01   1.35631697e+02  -1.60706299e+00
  -1.22811614e+01  -1.75589904e+01  -2.57132821e+01   1.89445174e-02
  -2.20966436e+01  -6.49294303e-03   2.75617457e-01   3.02518539e-01
   2.28775428e-09   9.62647461e-07  -9.50310077e-03   8.91207176e+00
  -7.72046425e-02   1.00080922e+01   5.53841384e-02]
f(x)     =  [ -1.47404306e-01   6.91920501e+00   2.77948881e+00   1.06274971e+01
  -1.69328330e+00   6.76123765e-01  -8.76033456e-01  -1.10256977e-02
   2.94420093e+01   5.79360754e+00   6.43713702e+01  -9.72332696e-01
  -5.61925591e-08  -3.38062351e-05   4.88711821e-01   3.37669797e-01
   3.41192694e+00  -1.29963945e-01   3.05296708e-02]

您能帮我解决这个错误吗?

您的问题看起来是非凸的,这会带来麻烦

关于这项任务,可以找到许多有价值的评论

非凸优化的一个常用思想是从多个初始点开始求解。这实际上改变了这里的情况,但结果仍然有点远离零

多启动fsolve示例 凸性 这个问题可以写成QP。在这种情况下,目标的形式为
c.T*x+0.5*x.T*Q*x

如果Q是半正定的,它是一个凸的QP,并且在多项式时间内可以找到一个全局最小值(最小化透视图:l2范数(x))。不确定的情况是一个伤害


也许有更专业的不确定QP解算器。但问题本身通常是NP难的(如果是非凸的)

也许可以尝试使用fun=norm(x)的leastsq,看看解决方案是否能找到零向量。之后,您可以进一步调试潜在的原因。您所说的“使用leastsq with fun=norm(x)”是什么意思?
import numpy as np
from scipy.optimize import fsolve, minimize
np.set_printoptions(suppress=True)

def f(x) :
    y = np.zeros(np.size(x))
    y[0] = -29.79 + 1.795*x[1] + 6.33*x[0] + -0.305*x[3] - 0.024*x[1]*x[3] + 0.222*x[0]*x[3] -2.063*x[4] + 0.122*x[1]*x[4] + 0.864*x[0]*x[4] + x[5] - x[6]
    y[1] = -23.269 + 1.795*x[0] + 4.547*x[2] - 0.342*x[1] - 0.024*x[0]*x[3] + 0.072*x[2]*x[3] - 0.052*x[1]*x[3] - 1.545*x[4] + 0.122*x[0]*x[4] + 0.367*x[2]*x[4] + 0.114*x[1]*x[4] + x[7] - x[8]
    y[2] = 0.587 + 4.547*x[1] + 0.046*x[3] + 0.072*x[1]*x[3] - 0.211*x[4] + 0.367*x[1]*x[4] + x[9] - x[10]
    y[3] = -1.657 - 0.305*x[0] - 0.230*x[1] + 0.046*x[2] - 0.024*x[0]*x[1] + 0.072*x[1]*x[2] + 0.111*x[0]**2.0 - 0.026*x[1]**2.0 + 0.78981 + x[11]**2.0
    y[4] = -0.106 - 2.063*x[0] - 1.545*x[1] - 0.211*x[2] + 0.122*x[0]*x[1] + 0.367*x[1]*x[2] + 0.432*x[0]**2.0 + 0.057*x[1]**2.0 + 1.34744 + x[12]**2.0
    y[5] = x[0] - 0.3 + x[13]**2.0
    y[6] = -x[0] + 0.1 + x[14]**2.0
    y[7] = x[1] - 80 + x[15]**2.0
    y[8] = -x[1] + 30 + x[16]**2.0
    y[9] = x[2] - 230 + x[17]**2.0
    y[10] = -x[2] + 200 + x[18]**2.0
    y[11] = 2*x[3]*x[11]
    y[12] = 2*x[4]*x[12]
    y[13] = 2*x[5]*x[13]
    y[14] = 2*x[6]*x[14]
    y[15] = 2*x[7]*x[15]
    y[16] = 2*x[8]*x[16]
    y[17] = 2*x[9]*x[17]
    y[18] = 2*x[10]*x[18]
    return y

x0 = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
x =fsolve(f, x0)

print('fsolve')
print ("x:")
print(x)
print ("|x|_2:")
print(np.linalg.norm(x))

""" Try more starting-points fsolve """
N = 1000
best_obj = np.inf
best_x = 0
for i in range(N):
    x0 = np.random.uniform(size=x0.shape)
    x = fsolve(f, x0)
    fun = np.linalg.norm(x)
    if fun < best_obj:
        best_obj = fun
        best_x = x

print('-----')
print('multi-start fsolve')
print('x: ')
print(best_x)
print('|x|_2:')
print(np.linalg.norm(best_x))
C:\Miniconda3\lib\site-packages\scipy\optimize\minpack.py:161: RuntimeWarning: The iteration is not making good progress, as measured by the
  improvement from the last five Jacobian evaluations.
  warnings.warn(msg, RuntimeWarning)
fsolve
x:
[   0.97612376    0.56395127  135.63169724   -1.60706299  -12.28116138
  -17.55899044  -25.71328208    0.01894452  -22.09664359   -0.00649294
    0.27561746    0.30251854    0.            0.00000096   -0.0095031
    8.91207176   -0.07720464   10.00809224    0.05538414]
|x|_2:
142.085025055
C:\Miniconda3\lib\site-packages\scipy\optimize\minpack.py:161: RuntimeWarning: The iteration is not making good progress, as measured by the
  improvement from the last ten iterations.
  warnings.warn(msg, RuntimeWarning)
-----
multi-start fsolve
x:
[ 0.35428349  0.2476696   0.18428096  0.13483107  0.83282782  0.75846428
  0.15784569  0.19073984  0.72388253  0.45229748  0.21294132  0.52558176
  0.11637452  0.21832279  0.44927192  0.06217237  0.04219192  0.07791865
  0.07722962]
|x|_2:
1.70295527001