软件库:scipy.optimize, numpy
相关函数:scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
这部分内容为scipy官方文档翻译过来,但官方文档对带约束的最优化问题介绍的比较少,其引用了一本书籍的内容,下面记录之。
(1)根据文档所知,参考书籍为Nocedal, J, and S J Wright. 2006. Numerical Optimization. Springer New York.
使用例子来自example16.3(p462),文档有误,问题描述如下:
代码如下:
import numpy as np
from scipy.optimize import minimize
# 目标函数
def objective(x):
return (x[0] - 1)**2 + (x[1] - 2.5)**2
# 约束条件
def constraint1(x):
return x[0] - 2 * x[1] + 2 #不等约束
def constraint2(x):
return -x[0] - 2 * x[1] + 6 #不等约束
def constraint3(x):
return -x[0] + 2 * x[1] + 2 #不等约束
# 初始猜想
n = 2
x0 = np.zeros(n)
x0[0] = 2
x0[1] = 0
# show initial objective
print('Initial SSE Objective: ' + str(objective(x0)))
# 边界约束
b = (0.0,None)
bnds = (b, b) # 注意是两个变量都要有边界约束
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'ineq', 'fun': constraint2}
con3 = {'type': 'ineq', 'fun': constraint3}
cons = ([con1,con2,con3]) # 3个约束条件
# 优化计算
solution = minimize(objective,x0,method='SLSQP',\
bounds=bnds,constraints=cons)
x = solution.x
# show final objective
print('Final SSE Objective: ' + str(objective(x)))
# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))
结果如下:
Initial SSE Objective: 7.25
Final SSE Objective: 0.8000000011920985
Solution
x1 = 1.4000000033834283
x2 = 1.7000000009466527
就是当x1=1.4,x2=1.7时在约束条件下目标函数取得最小值。
再举一个例子加深印象,参照https://jingyan.baidu.com/album/6c67b1d69508b52787bb1edf.html?picindex=2,求解下面优化问题:
使用python代码如下:
import numpy as np
from scipy.optimize import minimize
def objective(x):
return x[0]**3-x[1]**3-x[0]*x[1]+2*x[0]**2
def constraint1(x):
return -x[0]**2 - x[1]**2 + 6.0
def constraint2(x):
return 2.0-x[0]*x[1]
# initial guesses
n = 2
x0 = np.zeros(n)
x0[0] = 1
x0[1] = 2
# show initial objective
print('Initial SSE Objective: ' + str(objective(x0)))
# optimize
b = (0.0,3.0)
bnds = (b, b)
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'eq', 'fun': constraint2}
cons = ([con1,con2])
solution = minimize(objective,x0,method='SLSQP',\
bounds=bnds,constraints=cons)
x = solution.x
# show final objective
print('Final SSE Objective: ' + str(objective(x)))
# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))
结果如下:
Initial SSE Objective: -7.0
Final SSE Objective: -11.785844453999744
Solution
x1 = 0.8740320488968586
x2 = 2.288245611271501
和原作者在matlab求解结果一致
特别注意: 使用约束的时候,要转化为形如ax+by>=c
的形式,像前面第二个例子中的不等约束为
,则要转化为
的形式,然后再编写约束函数的代码:
def constraint1(x):
return -x[0]**2 - x[1]**2 + 6.0
接着定义约束类型:
con1 = {'type': 'ineq', 'fun': constraint1}
参考链接:
[1]https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#rdd2e1855725e-5
[2]https://apmonitor.com/pdc/index.php/Main/NonlinearProgramming
[3]https://jingyan.baidu.com/article/6c67b1d69508b52787bb1edf.html