Python——使用scipy求解带约束的最优化问题

76 篇文章 1 订阅

我们要求解的最优化问题的形式如下:
m i n   f ( x ) s . t . g i ( x ) > 0 , i = 1 , . . . , m h j ( x ) = 0 , j = 1 , . . . , n \begin{aligned} min \ f(x) \\ s.t.\quad g_i(x)& \gt 0, i = 1,...,m\\ \quad h_j(x)& = 0, j = 1,...,n \end{aligned} min f(x)s.t.gi(x)hj(x)>0,i=1,...,m=0,j=1,...,n
其中 x x x 是一个向量, g i ( x ) g_i(x) gi(x) 是非等式约束, h j ( x ) h_j(x) hj(x) 是等式约束。

示例

x , y , z > 0 , x y z = 1 x,y,z>0,xyz=1 x,y,z>0xyz=1 的条件下,求解 ( x − 2 / 3 ) / ( x + y + z − 2 ) (x-2/3)/(x+y+z-2) (x2/3)/(x+y+z2) 的最小值。

from scipy.optimize import minimize
import numpy as np
e = 1e-10 # 非常接近0的值
fun = lambda x : (x[0] - 0.667) / (x[0] + x[1] + x[2] - 2) # 约束函数
cons = ({'type': 'eq', 'fun': lambda x: x[0] * x[1] * x[2] - 1}, # xyz=1
        {'type': 'ineq', 'fun': lambda x: x[0] - e}, # x>=e,即 x > 0
        {'type': 'ineq', 'fun': lambda x: x[1] - e},
        {'type': 'ineq', 'fun': lambda x: x[2] - e}
       )
x0 = np.array((1.0, 1.0, 1.0)) # 设置初始值
res = minimize(fun, x0, method='SLSQP', constraints=cons)
print('最小值:',res.fun)
print('最优解:',res.x)
print('迭代终止是否成功:', res.success)
print('迭代终止原因:', res.message)

输出:

最小值: -0.18814357989751096
最优解: [0.29250894 1.84897232 1.84897233]
迭代终止是否成功: True
迭代终止原因: Optimization terminated successfully.

备注:

  • 若是求一个函数的最大值,则改为求其相反数的最小值。
  • 因为ineq的约束是表示非负,所以 x > 0 x>0 x>0 的条件可以写为 x − e ≥ 0 x-e\ge0 xe0,其中 e e e是一个尽可能小的值。
  • 其实,在本题中,可以直接让 x > 0 x\gt0 x>0,因为有约束 x y z = 1 xyz=1 xyz=1,所以不必担心最后解为 x = 0 x=0 x=0

函数介绍

scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)

求取一个函数的最小值。函数的参数可以是多个,但函数值只能是标量。

参数

  • fun : callable
    目标函数
  • x0 : ndarry
    初始值
  • args : tuple, optional
    额外的参数,传给目标函数和它的导数。
  • method : str or callable, optional
    求解问题的算法名,下面选其一:
    Nelder-Mead, Powell, CG, BFGS, Newton-CG, L-BFGS-B, TNC, COBYLA, SLSQP, dogleg, trust-ncg
    默认是 BFGS, L-BFGS-B, SLSQP 之一,根据问题是否含有约束和界限自动选择。
  • jac : bool or callable, optional
    目标函数的梯度矩阵。只适用于 CG, BFGS, Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg。如果jac是一个 Boolean 且为 True,则 fun 被认为是梯度与目标函数一起返回。如果是False,则梯度会被自动地计算。jac也可以是一个函数,返回目标函数的梯度,且参数必须与fun相同。
  • hess, hessp : callable, optional
    目标函数的二阶导矩阵,或者二阶导矩阵乘以一个随机向量p。只适用于Newton-CG,dogleg, trust-ncghesshessp只需要给出一个即可。如果提供了hess,则hessp会被忽略。如果两者都没有提供,则二阶导矩阵会被自动计算。
  • bounds : sequence, optional
    bounds 是参数的界限,只适用于L-BFGS-B, TNCSLSQP,每个参数对应一个 (min, max),表示参数的上下限。如果只有一边界限,则另一边置为None。当约束是针对 x x x 中的单个元素的上下限时,就可以用 bounds 参数来设置。
  • constraints : dict or sequence of dict, optional
    约束定义,只适用于 COBYLASLSQP。每个约束定义为一个词典,键值对包括:
    • fun : callable。定义了约束函数。
    • type : str。约束类型: eq’ 表示等式约束(fun等于0),ineq 表示不等式约束(fun大于等于0)。COBYLA只支持不等式约束。
    • jac : callable, optional。fun 的梯度矩阵,只适用于SLSQP
    • args : sequence, optional。传递给funjac的额外参数。
  • tol : float, optional
    迭代终止的允许误差。
  • options : dict, optional
    求解器的选项字典。所有的算法都接受以下的通用选项:
    • maxiter : int。迭代的最大次数。
    • disp : bool。如果是True则打印出收敛信息。
  • callback : callable, optional
    每次迭代之后调用的函数,参数为xk,表示当前的参数向量。

返回值

res:优化结果。

优化结果是OptimizeResult对象,重要属性如下:

  • fun 是最优值。
  • x 是最优解。
  • success 表示求解器是否成功退出。
  • message 描述了求解器退出的原因。
  • 62
    点赞
  • 298
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值