Python 使用具有大型等式约束矩阵的Scipy最小化(Scipy.optimize.minimize)

Python 使用具有大型等式约束矩阵的Scipy最小化(Scipy.optimize.minimize),python,python-2.7,scipy,mathematical-optimization,Python,Python 2.7,Scipy,Mathematical Optimization,我需要最小化一个函数,比如五个变量(x[0]到x[4]) 要最小化的标量函数由X'*H*X给出。目标函数与此类似: def objfun(x): H = 0.1*np.ones([5,5]) f = np.dot(np.transpose(x),np.dot(H,x))[0][0] return f 它将返回单个标量值 问题是,如何实现由以下公式给出的约束方程: A*X - b = 0 其中A和b在每次运行中可能会发生变化。一个随机的例子是: A = array([

我需要最小化一个函数,比如五个变量(x[0]到x[4])

要最小化的标量函数由
X'*H*X
给出。目标函数与此类似:

def objfun(x):
    H = 0.1*np.ones([5,5])
    f = np.dot(np.transpose(x),np.dot(H,x))[0][0]
    return f
它将返回单个标量值

问题是,如何实现由以下公式给出的约束方程:

A*X - b = 0
其中A和b在每次运行中可能会发生变化。一个随机的例子是:

A = 
array([[ 1,  2,  3,  4,  5],
       [ 2,  1,  3,  4,  5],
       [-1,  2,  3,  0,  0],
       [ 0, -5,  6,  3,  2],
       [-3,  5,  6,  2,  8]])

B = 
array([[ 0],
       [ 2],
       [ 3],
       [-2],
       [-7]])
A和B不能硬编码到约束函数中,因为它们在每次运行中可能不同。变量没有界限,无需指定优化方法

编辑

我意识到,对于一个有5个变量的优化问题,有5个约束方程就可以通过解方程得到唯一的解。 那么,如果a可以定义为:

A = 
array([[ 1,  2,  3,  4,  5],
       [ 2,  1,  3,  4,  5],
       [-1,  2,  3,  0,  0],
       [ 0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0]])


B = 
array([[ 0],
       [ 2],
       [ 3],
       [ 0],
       [ 0]])

因此,我们有一个5变量优化问题,有3个线性约束。

您可以尝试使用
scipy.optimize.fmin_cobyla
函数,我不知道数值细节,所以您应该使用您知道预期答案的值进行检查,看看它是否适合您的需要,使用容差参数
rhoend
rhobeg
,看看您是否得到了预期的答案,示例程序可能类似于:

import numpy as np
import scipy.optimize

A = \
np.array([[ 1,  2,  3,  4,  5],
          [ 2,  1,  3,  4,  5],
          [-1,  2,  3,  0,  0],
          [ 0,  0,  0,  0,  0],
          [ 0,  0,  0,  0,  0]])

B = \
np.array([[0],
          [2],
          [3],
          [0],
          [0]])

def objfun(x):
    H = 0.1*np.ones([5,5])
    f = np.dot(np.transpose(x),np.dot(H,x))
    return f

def constr1(x):
    """ The constraint is satisfied when return value >=0 """
    sol = A*x
    if np.allclose(sol, B):
        return 0.01
    else:
        # Return the negative distance between the expected solution
        # and the actual solution for a somehow meaningful value
        return -np.linalg.norm(B-sol)

scipy.optimize.fmin_cobyla(objfun, [0.0, 0.0, 0.0, 0.0,0.0], [constr1])
#np.linalg.solve(A, b)
请注意,这个给定的示例没有解决方案,请尝试解决方案。我不完全确定约束函数是否正确定义,请尝试找到适合您的约束函数。您应该尝试提供一个初始猜测,即它是一个实际的解决方案,而不是
[0.0,0.0,0.0,0.0]
,以获得更好的结果

有关更多详细信息,请查看官方文档:

编辑:还取决于您正在寻找的解决方案类型,您可能会形成一个更好的约束函数,允许与预期解决方案存在一定公差距离的值,即使不完全精确,返回大于0的值越接近公差,而不是始终为0.1,以此类推

提到了一个简洁的通用方法:
Ax=b
的所有解决方案的形式均为
xany+nullspace(A)z

其中
xany
是一种解决方案,而
dim(z)

因此,在无约束的
z
上最小化
f(xany+nullspace(A)z)

例如,在3d中,约束
x0+x1+x2=1
具有零空间矩阵

[  1  0 ]  : [z0 z1] -> [z0, -z0 + z1, -z1]  -- sum 0
[ -1  1 ]
[  0 -1 ]

(“在数值计算零空间时需要注意…)

实际的目标函数和约束有点不同。关于给予宽容的建议是好的。谢谢