优化模型(二)非线性规划详解,以及例题,Scipy.optimize 求解非线性规划

数学建模系列文章:

以下是个人在准备数模国赛时候的一些模型算法和代码整理,有空会不断更新内容:
评价模型(一)层次分析法(AHP),熵权法,TOPSIS分析 及其对应 PYTHON 实现代码和例题解释
评价模型(二)主成分分析、因子分析、二者对比及其对应 PYTHON 实现代码和例题解释
优化模型(零)总述,分类,解析各类优化模型及普适做题步骤
优化模型(一)线性规划详解,以及例题,用python的Pulp库函数求解线性规划
优化模型(二)非线性规划详解,以及例题,Scipy.optimize 求解非线性规划

3.3 Scipy.optimize 求解非线性规划

非线性规划概述:

当目标函数f(x)或者约束条件中有一个是决策变量X的非线性表达式,那么此时的数学规划问题就属于非线性规划。解决非线性规划要比线性规划困难的多,目前没有通用算法,大多数算法都是在选定决策变量的初始值后,通过一定搜索算法寻求最优的决策变量。而本文使用的方法是基于Scipy库的一些个函数进行求解。

scipy求解流程–编程步骤说明:

  1. 导入 scipy、numpy 包;
  2. 定义目标函数 objf3(x),输入变量 x 表示向量,返回值 fx 是目标函数的计算结果 。 默认是min(若求max,加负号,-min)
  3. 定义边界约束,即优化变量的上下限:
    • minimize() 默认无边界约束条件,即各自变量的取值范围没有限制;
    • 如果设置边界约束,要对每个自变量(决策变量)定义其上下限,注意定义边界约束的格式;
  4. 如果某个自变量没有上限(下限),则表示为 None 。
    定义 x 的初值。
  5. 求解最小化问题 resRosen,其中目标函数 objf3 和搜索的初值点 xIni 是必需的,指定优化方法和边界条件是可选项。如果优化问题是求最大值 maxFx,可以通过 minFx = - maxFx 的变换来实现
  6. 通过调用最小化问题的返回值 resRosen.x 得到最优点 xOpt。

Scipy.optimize一些参数解释:

minimize(fun,x0,method,bounds,constraints) 求解最小化函数

fun: 第一步定义的目标函数;

x0 : 猜测解or初始解,列表或元组形式,一般是N 维数组对象ndarray;;

method : 一般填’SLSQP’(序贯最小二乘规划);

bounds : 变量边界/取值范围; b0 = (0.0, None) # 0.0 <= x[0] <= Inf None == 无穷

constraints : (约束条件)在前面定义,在此处调用。

jac:可选**,**目标函数的雅可比矩阵(目标函数的一阶偏导)。这些方法会用到: CG, BFGS, Newton-CG, L-BfFGS-B, TNC, SLSQP, dogleg, trust-ncg;

cons : 限制函数 cons = ({‘type’:‘eq’,‘fun’: lambda x:f(x)})

cons = ({‘type’:‘eq’,‘fun’: lambda x: x[0]*x[1]*x[2]-12})

type : 约束条件的类型 eq是等式 ineq是不等式 。

lambda : 是约束函数表达式,默认是将变量提取到左边 ,符号是 >= 的不等式 例如 lambda x: x[0]*x[1]*x[2]-12 表示 x*y*z>=12 ;如果需要<= 则提取一个负号即可,比如这个 -(x*y*z)>=-12 表示 (x*y*z) <= 12,如果不取等的话,直接加上一个十分小的数即可比如1e-20。比如lambda x: x[0]*x[1]*x[2]-12-1e-20 可约等于x*y*z>12

代码说明一:

from scipy.optimize import brent, fmin, minimize
import numpy as np

# 多变量边界约束优化问题(Scipy.optimize.minimize)
# 定义目标函数
def objf3(x):  # Rosenbrock 测试函数
    fx = x[0]+2*x[1]+3*x[2]+1
    return fx

cons = ({
    
    'type':'eq','fun': lambda x: x[0]*x[1]*x[2]-12})

# 定义没一个变量边界约束(优化变量的上下限)
b0 = (0.0, None)  # 0.0 <= x[0] <= Inf
b1 = (0.0, None)  # 0.0 <= x[1] <= Inf
b2 = (0.0, None)  # 0.0 <= x[2] <= Inf
bnds = (b0, b1, b2)  # 边界约束

# 优化计算
xIni = np.array([1., 2., 3.]) # 定义初始值
resRosen = minimize(objf3, xIni, method='SLSQP',constraints = cons ,bounds=bnds)
xOpt = resRosen.x

print("xOpt = {:.4f}, {:.4f}, {:.4f}".format(xOpt[0],xOpt[1],xOpt[2]))
print("min f(x) = {:.4f}".format(objf3(xOpt)))

代码说明二:

求解下列优化函数:
在这里插入图片描述

from scipy.optimize import brent, fmin, minimize
import numpy as np

# 约束非线性规划问题(Scipy.optimize.minimize)
def objF6(args):  # 定义目标函数
    a,b,c,d = args
    fx = lambda x: a*x[0]**2 + b*x[1]**2 + c*x[2]**2 + d
    return fx

def constraint2(args):
    xmin0, xmin1, xmin2 = args
    cons = ({
    
    'type': 'ineq', 'fun': lambda x: (x[0]**2 - x[1] + x[2]**2)},  # 不等式约束 f(x)>=0
            {
    
    'type': 'ineq', 'fun': lambda x: -(x[0] + x[1]**2 + x[2]**3 - 20)},  # 不等式约束 转换为标准形式
            {
    
    'type': 'eq', 'fun': lambda x: (-x[0] - x[1]**2 + 2)},  # 等式约束
            {
    
    'type': 'eq', 'fun': lambda x: (x[1] + 2*x[2]**2 - 3)},  # 等式约束
            {
    
    'type': 'ineq', 'fun': lambda x: (x[0] - xmin0)},  # x0 >= xmin0
            {
    
    'type': 'ineq', 'fun': lambda x: (x[1] - xmin1)},  # x1 >= xmin1
            {
    
    'type': 'ineq', 'fun': lambda x: (x[2] - xmin2)})  # x2 >= xmin2
    return cons

# 求解优化问题
args1 = (1,2,3,8)  # 定义目标函数中的参数
args2 = (0.0, 0.0, 0.0)  # xmin0, xmin1, xmin2
cons2 = constraint2(args2)

x0 = np.array([1., 2., 3.])  # 定义搜索的初值
res2 = minimize(objF6(args1), x0, method='SLSQP', constraints=cons2)

print("Optimization problem (res2):\t{}".format(res2.message))  # 优化是否成功
print("xOpt = {}".format(res2.x))  # 自变量的优化值
print("min f(x) = {:.4f}".format(res2.fun))  # 目标函数的优化值

约束条件也可以这样定义:

# 定义约束条件函数
def constraint1(x):  # 不等式约束 f(x)>=0
    return x[0]** 2 - x[1] + x[2]**2
def constraint2(x):  # 不等式约束 转换为标准形式
    return -(x[0] + x[1]**2 + x[2]**3 - 20)
def constraint3(x):  # 等式约束
    return -x[0] - x[1]**2 + 2
def constraint4(x):  # 等式约束
    return x[1] + 2*x[2]**2 -3

# 定义边界约束
b = (0.0, None)
bnds = (b, b, b)

# 定义约束条件
con1 = {
    
    'type': 'ineq', 'fun': constraint1}
con2 = {
    
    'type': 'ineq', 'fun': constraint2}
con3 = {
    
    'type': 'eq', 'fun': constraint3}
con4 = {
    
    'type': 'eq', 'fun': constraint4}
cons = ([con1, con2, con3,con4])  # 3个约束条件

参考文献:

Python小白的数学建模课-12.非线性规划

猜你喜欢

转载自blog.csdn.net/m0_63669388/article/details/132703640
今日推荐