优化模型(二)非线性规划详解,以及例题,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.非线性规划

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SciPy 中提供了多种优化算法来解决非线性 0-1 模型,其中最常用的是基于梯度下降的优化算法和基于全局最优化优化算法。 一种基于梯度下降的优化算法是 BFGS 算法,它使用逆 Hessian 矩阵来近似目标函数的阶导数,并通过一系列迭代来寻找最优解。另一种基于全局最优化优化算法是差分进化算法(Differential Evolution),它在参数空间中搜索最优解,不需要计算梯度,因此适合解决非光滑和高维度的问题。 你可以使用 SciPy 中的 optimize 模块来实现这些算法。例如,使用 BFGS 算法求解非线性 0-1 模型的最优解的代码如下: ```python from scipy.optimize import minimize # 定义目标函数 def objective(x): return x[0]**2 + x[1]**2 - 2*x[0]*x[1] - 4*x[0] + 5 # 定义约束条件 def constraint(x): return x[0] + x[1] - 1 # 定义初始值 x0 = [0, 0] # 定义边界条件 bounds = [(0, 1), (0, 1)] # 使用 BFGS 算法求解最优解 result = minimize(objective, x0, method='BFGS', bounds=bounds, constraints={'type': 'eq', 'fun': constraint}) print(result) ``` 该代码使用 BFGS 算法求解以下非线性 0-1 模型的最优解: ``` minimize x1^2 + x2^2 - 2*x1*x2 - 4*x1 + 5 subject to x1 + x2 = 1 0 <= x1, x2 <= 1 ``` 输出结果为: ``` fun: 1.5 jac: array([-2., 0.]) message: 'Optimization terminated successfully.' nfev: 20 nit: 4 njev: 4 status: 0 success: True x: array([1., 0.]) ``` 其中,`fun` 表示最优解的目标函数值,`x` 表示最优解的参数值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

herry_drj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值