python非线性约束优化

版权声明:本文为博主ouening原创文章,未经博主允许不得恶意复制转载,需要注明出处,尊重知识成果!技术交流请联系[email protected]! https://blog.csdn.net/ouening/article/details/83422337

软件库: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的形式,像前面第二个例子中的不等约束为 x 2 + y 2 < = 6 x^2+y^2<=6 ,则要转化为 x 2 y 2 + 6 > = 0 -x^2-y^2+6>=0 的形式,然后再编写约束函数的代码:

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

猜你喜欢

转载自blog.csdn.net/ouening/article/details/83422337
今日推荐