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


  • 非线性规划是指目标函数或约束条件中包含非线性函数的规划问题,实际就是非线性最优化问题。
  • 从线性规划到非线性规划,不仅是数学方法的差异,更是解决问题的思想方法的转变。
  • 非线性规划问题没有统一的通用方法,我们在这里学习的当然不是数学方法,而是如何建模、如何编程求解。
  • 『Python小白的数学建模课 @ Youcans』带你从数模小白成为国赛达人。


1. 从线性规划到非线性规划

本系列的开篇我们介绍了线性规划 (Linear Programming) 并延伸到整数规划、0-1规划,以及相对复杂的固定费用问题、选址问题。这些问题的共同特点是,目标函数与约束条件都是线性函数。如果目标函数或约束条件中包含非线性函数,则是非线性规划。

通常,非线性问题都比线性问题复杂得多,困难得多,非线性规划也是这样。非线性规划没有统一的通用方法、算法来解决,各种方法都有特定的应用范围和适用条件。另一方面,很多非线性规划问题在实践中不能获得全局最优解,只能得到局部最优解或近似最优解。

这意味着什么?对于数学研究来说,这也许意味着存在新的课题和挑战,可以研究更有效的算法。确实如此,即便线性规划问题的研究也在不断前进,非线性规划问题的研究更是丰富多彩。但热闹是他们的,我什么也没有。

我所想到的,是数学建模学习/课程/竞赛的根本目的是什么?是掌握各种算法的推演,努力编程以实现,还是练习分析问题建立模型的能力,使用软件和工具求解问题的能力?显然是后者。可是,为什么培训课上老师讲的都是算法呢?到了例题例程,不是一带而过,就是跳步骤讲。听课时津津有味,下课了题目还是不会做,程序还是调不通。于是,…

不过,到了非线性规划这一课,我们发现老师也不再不厌其烦地讲算法了,不知道是讲不下去还是讲不过来了: 20世纪50年代,H.W.Kuhn 和 A.W.Tucker 提出了非线性规划的基本定理,为非线性规划奠定了理论基础 ;50、60 年代出现了许多解非线性规划问题的有效算法;80年代后,随着计算机技术的快速发展,非线性规划方法取得了长足进步,在信赖域法、稀疏拟牛顿法、并行计算、内点法和有限存储法等领域取得了丰硕的成果。

所以,没关系的,都一样——参见章北海文集。

这意味着什么呢?这意味着对于学习数学建模的小白,学会把问题简化为非线性规划的标准方程,学会按照本文的方法使用求解工具包的函数,才能求解非线性规划问题,才能完赛。

欢迎关注 『Python小白的数学建模课 @ Youcans』 系列,持续更新
Python小白的数学建模课-01.新手必读
Python小白的数学建模课-02.数据导入
Python小白的数学建模课-03.线性规划
Python小白的数学建模课-04.整数规划
Python小白的数学建模课-05.0-1规划
Python小白的数学建模课-06.固定费用问题
Python小白的数学建模课-07.选址问题
Python小白的数学建模课-09.微分方程模型
Python小白的数学建模课-10.微分方程边值问题
Python小白的数学建模课-12.非线性规划
Python小白的数学建模课-15.图论的基本概念
Python小白的数学建模课-16.最短路径算法
Python小白的数学建模课-17.条件最短路径算法
Python小白的数学建模课-18.最小生成树问题
Python小白的数学建模课-19.网络流优化问题



2. Scipy 库求解非线性规划问题

2.1 非线性规划问题的描述

首先,我们回顾线性规划问题的标准形式:

minf(x)=∑j=1ncjxjs.t.:{∑j=1naijxj=bi,xj≥0min\;f(x) = \sum_{j=1} ^n c_j x_j\\ s.t.:\begin{cases} \sum_{j=1} ^n a_{ij} x_j = b_i, \\ x_j \geq 0 \end{cases} minf(x)=j=1ncjxjs.t.:{j=1naijxj=bi,xj0

类似地,可以写出非线性规划的一般形式:

minf(x)s.t.:{hj(x)≤0,j=1,qgi(x)=0,i=1,pmin\;f(x) \\ s.t.:\begin{cases} h_j(x) \leq 0, &j=1,q\\ g_i(x) = 0, &i=1,p \end{cases} minf(x)s.t.:{hj(x)0,gi(x)=0,j=1,qi=1,p

其中:x=[x1,...,xn]Tx=[x_1,...,x_n]^Tx=[x1,...,xn]T 为决策变量,f(x)f(x)f(x) 为目标函数,hj(x)h_j(x)hj(x)gi(x)g_i(x)gi(x) 为约束条件。

由此可见,非线性规划问题,实际上就是带有约束条件的非线性函数优化问题。

按照我们的学习模式,非线性规划问题的建模和求解与线性规划问题是类似的,按照以下步骤进行:

  1. 问题定义,确定决策变量、目标函数和约束条件;
  2. 模型构建,由问题描述建立数学方程,并转化为标准形式的数学模型;
  3. 模型求解,用标准模型的优化算法对模型求解,得到优化结果。

2.2 Scipy 求解非线性规划问题的函数

Scipy 是 Python 算法库和数学工具包,包括最优化、线性代数、积分、插值、特殊函数、傅里叶变换、信号和图像处理、常微分方程求解等模块。

本文推荐和讲解使用 Scipy 工具包中的 optimize 模块求解常见的非线性规划问题。

scipy.optimize 模块中提供了多个用于非线性规划问题的方法,适用于不同类型的问题。

  • brent():单变量无约束优化问题,混合使用牛顿法/二分法。

  • fmin():多变量无约束优化问题,使用单纯性法,只需要利用函数值,不需要函数的导数或二阶导数。

  • leatsq():非线性最小二乘问题,用于求解非线性最小二乘拟合问题。

  • minimize():约束优化问题,使用拉格朗日乘子法将约束优化转化为无约束优化问题。


2.3 scipy.optimize.brent() 求解单变量无约束优化问题

非线性规划最简单的形式是一维搜索,一维搜索的常用方法是函数逼近法和区间收缩法。

brent() 函数是 SciPy.optimize 模块中求解单变量无约束优化问题最小值的首选方法。这是牛顿法和二分法的混合方法,既能保证稳定性又能快速收敛。

scipy.optimize.brent(func, args=(), brack=None, tol=1.48e-08, full_output=0, maxiter=500)

optimize.brent() 的主要参数:

  • *func: callable f(x,args)   目标函数 f(x)f(x)f(x),以函数形式表示,可以通过 *args 传递参数
  • args: tuple  可选项,以 f(x,*args) 的形式将可变参数 p 传递给目标函数 f(x,p)f(x,p)f(x,p)
  • brack: tuple  可选项,搜索算法的开始区间(不是指 x 的上下限)

optimize.brent() 的主要返回值:

  • **xmin: **   返回函数达到最小值时的 x(注意是局部最优,不一定是全局最优)。
  • **fval: **   返回函数的最优值(默认不返回,仅当 full_output 为 1 时返回)。

optimize.brent() 的使用例程:

from scipy.optimize import brent, fmin_ncg, minimize
import numpy as np# 1. Demo1:单变量无约束优化问题(Scipy.optimize.brent)
def objf(x):  # 目标函数fx = x**2 - 8*np.sin(2*x+np.pi)return fxxIni = -5.0
xOpt= brent(objf, brack=(xIni,2))
print("xIni={:.4f}\tfxIni={:.4f}".format(xIni,objf(xIni))
print("xOpt={:.4f}\tfxOpt={:.4f}".format(xOpt,objf(xOpt)))

例程运行结果:

xIni=-5.0000	fxIni=29.3522
xOpt=-0.7391	fxOpt=-7.4195

在这里插入图片描述


2.4 scipy.optimize.fmin() 求解多变量无约束优化问题

多变量无约束优化问题的算法很多,分类方式也很多。从使用者的角度来说可以分为:只使用目标函数值、使用导数(梯度下降法)、使用二阶导数。大体来说,使用导数的算法收敛较快,使用二阶导数收敛更快,但是收敛快也容易陷入局部最优。

fmin() 函数是 SciPy.optimize 模块中求解多变量无约束优化问题(最小值)的首选方法,采用下山单纯性方法。下山单纯性方法又称 Nelder-Mead 法,只使用目标函数值,不需要导数或二阶导数值,是最重要的多维无约束优化问题数值方法之一。

scipy.optimize.fmin(func, x0, args=(), xtol=0.0001, ftol=0.0001, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, initial_simplex=None)

optimize.fmin() 的主要参数:

  • *func: callable f(x,args)   目标函数 f(x)f(x)f(x),以函数形式表示,可以通过 *args 传递参数。
  • x0: nadarray  搜索算法的初值。
  • args: tuple  可选项,以 f(x,*args) 的形式将可变参数 p 传递给目标函数 f(x,p)f(x,p)f(x,p)

optimize.fmin() 的主要返回值:

  • **xopt: **   返回最小值时的 x 值。
  • **fopt: **   返回最小值时的目标函数值,fopt=func(xopt)。

optimize.fmin() 的使用例程:

from scipy.optimize import brent, fmin, minimize
import numpy as np# 2. Demo2:多变量无约束优化问题(Scipy.optimize.brent)
# Rosenbrock 测试函数
def objf2(x):  # Rosenbrock benchmark functionfx = sum(100.0 * (x[1:] - x[:-1] ** 2.0) ** 2.0 + (1 - x[:-1]) ** 2.0)return fxxIni = np.array([-2, -2])
xOpt = fmin(objf2, xIni)
print("xIni={:.4f},{:.4f}\tfxIni={:.4f}".format(xIni[0],xIni[1],objf2(xIni)))
print("xOpt={:.4f},{:.4f}\tfxOpt={:.4f}".format(xOpt[0],xOpt[1],objf2(xOpt)))

例程运行结果:

xIni=-2.0000,-2.0000	fxIni=3609.0000
xOpt=1.0000,1.0000		fxOpt=0.0000

在这里插入图片描述



3. scipy.optimize.minimize() 求解非线性规划问题

3.1 scipy.optimize.minimize() 函数说明

minimize() 函数是 SciPy.optimize 模块中求解多变量优化问题的通用方法,可以调用多种算法,支持约束优化和无约束优化。

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

optimize.minimize() 的主要参数:

  • *fun: callable f(x,args)   目标函数 f(x)f(x)f(x),以函数形式表示,可以通过 *args 传递参数。
  • x0: nadarray, shape(n,)  搜索算法的初值,n 是决策变量个数。
  • args: tuple  可选项,将可变参数传递给目标函数 fun、导数函数 jac 和二阶导数函数 hess。
  • method: str  可选项,选择优化算法。默认算法为 BFGS, L-BFGS-B, SLSQP(取决于问题有没有边界条件和约束条件)
  • **jac: **  可选项,梯度计算方法。可以以函数形式表示,或选择 ‘2-point’, ‘3-point’, ‘cs’。该选项只能用于 CG, BFGS, Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg, trust-krylov, trust-exact 和 trust-constr 算法。
  • **hess: **  可选项,Hessian 矩阵计算方法。可以以函数形式表示,或选择 ‘2-point’, ‘3-point’, ‘cs’。该选项只能用于 Newton-CG, dogleg, trust-ncg, trust-krylov, trust-exact 和 trust-constr 算法。
  • **bounds: **  可选项,变量的边界条件(上下限,lb<=x<=ub)。该选项只能用于 Nelder-Mead, L-BFGS-B, TNC, SLSQP, Powell 和 trust-constr 算法。
  • **constraints: **  可选项,定义约束条件 f(x)>=0。该选项只能用于 COBYLA, SLSQP 和 trust-constr 算法,注意不同算法中对于约束条件的定义是不同的。

optimize.minimize() 的主要返回值:

  • **res: **   返回优化结果,以对象方式表示,主要包括优化是否成功、决策变量的优化值 xOpt。

optimize.minimize() 的优化算法选项:

optimize.minimize() 的默认算法为 BFGS, L-BFGS-B, SLSQP(取决于问题有没有边界条件和约束条件),可以通过 “method=None” 选项调用多种算法:

无约束问题优化算法

  • **method=‘CG’ **:  非线性共轭梯度算法,只能处理无约束优化问题,需要使用一阶导数函数。

  • **method=‘BFGS’ **:  BFGS 拟牛顿法,只能处理无约束优化问题,需要使用一阶导数函数。BFGS 算法性能良好,是无约束优化问题的默认算法。

  • **method=‘Newton-CG’ **:  截断牛顿法,只能处理无约束优化问题,需要使用一阶导数函数,适合处理大规模问题。

  • **method=‘dogleg’ **:  dog-leg 信赖域算法,需要使用梯度和 Hessian(必须正定),只能处理无约束优化问题,

  • **method=‘trust-ncg’ **:  采用牛顿共轭梯度信赖域算法,需要使用梯度和 Hessian(必须正定),只能处理无约束优化问题,适合大规模问题。

  • method=‘trust-exact’:  求解无约束极小化问题的信赖域方法,需要梯度和Hessian(不需要正定)。

  • method=‘trust-krylov’:  使用Newton-GLTR 信赖域算法度,需要使用梯度和 Hessian(必须正定),只能处理无约束优化问题,适合中大规模问题。

边界约束条件问题优化算法

  • method=‘Nelder-Mead’:  下山单纯性法,可以处理边界约束条件(决策变量的上下限),只使用目标函数,不使用导数函数、二阶导数,鲁棒性强。

  • **method=‘L-BFGS-B’ **:  改进的 BFGS 拟牛顿法,L- 指有限内存,-B 指边界约束,可以处理边界约束条件,需要使用一阶导数函数。L-BFGS_B 算法性能良好,消耗内存量很小,适合处理大规模问题,是边界约束优化问题的默认算法。

  • method=‘Powell’:  改进的共轭方向法,可以处理边界约束条件(决策变量的上下限)。

  • **method=‘TNC’ **:  截断牛顿法,可以处理边界约束条件

带有约束条件问题优化算法

  • **method=‘COBYLA’ **:  线性近似约束优化方法,通过对目标函数和约束条件的线性逼近处理非线性问题。只使用目标函数,不需要导数或二阶导数值,可以处理约束条件。

  • **method=‘SLSQP’ **:  序贯最小二乘规划算法,可以处理边界约束、等式约束和不等式约束条件。SLSQP 算法性能良好,是带有约束条件优化问题的默认算法。

  • **method=‘trust-constr’ **:  信赖域算法,通用的约束最优化方法,适合处理大规模问题。

由于 optimize.minimize() 实际是多种算法的集成接口,各种算法对于问题、约束条件和参数的定义并不完全相同,对于各种算法的研究和应用已超出本文的内容,有兴趣的读者可以阅读官方文档: scipy.optimize.minimize — SciPy v1.7.0 Manual
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#scipy.optimize.minimize

我们还是针对数学建模的常用需求和小白的特点,结合实际案例来学习基本应用。


3.2 scipy.optimize.minimize() 函数使用例程

编程步骤说明:

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

Python 例程:

from scipy.optimize import brent, fmin, minimize
import numpy as np# 3. Demo3:多变量边界约束优化问题(Scipy.optimize.minimize)
# 定义目标函数
def objf3(x):  # Rosenbrock 测试函数fx = sum(100.0 * (x[1:] - x[:-1] ** 2.0) ** 2.0 + (1 - x[:-1]) ** 2.0)return fx# 定义边界约束(优化变量的上下限)
b0 = (0.0, None)  # 0.0 <= x[0] <= Inf
b1 = (0.0, 10.0)  # 0.0 <= x[1] <= 10.0
b2 = (-5.0, 100.)  # -5.0 <= x[2] <= 100.0
bnds = (b0, b1, b2)  # 边界约束# 优化计算
xIni = np.array([1., 2., 3.])
resRosen = minimize(objf3, xIni, method='SLSQP', bounds=bnds)
xOpt = resRosen.xprint("xOpt = {:.4f}, {:.4f}, {:.4f}".format(xOpt[0],xOpt[1],xOpt[2]))
print("min f(x) = {:.4f}".format(objf3(xOpt)))

例程运行结果:

xOpt = 1.0000, 1.0000, 1.0000
min f(x) = 0.0000


4. 约束非线性规划问题实例

4.1 非线性规划问题的数学模型:

minf(x)=a∗x12+b∗x22+c∗x32+ds.t.:{x12−x2+x32≥0x1+x22+x33≤20−x1−x22+2=0x2+2x32=3x1,x2,x3≥0min\;f(x) = a*x_1^2 + b*x_2^2 + c*x_3^2 + d\\ s.t.:\begin{cases} x_1^2 - x_2 + x_3^2 \geq 0\\ x_1 + x_2^2 + x_3^3 \leq 20\\ -x_1 - x_2^2 + 2 = 0\\ x_2 + 2x_3^2 = 3\\ x_1, x_2, x_3 \geq 0 \end{cases} minf(x)=ax12+bx22+cx32+ds.t.:x12x2+x320x1+x22+x3320x1x22+2=0x2+2x32=3x1,x2,x30

由于 minimize() 函数中对约束条件的形式定义为 f(x)>=0,因此要将问题的数学模型转换为标准形式:
minf(x)=a∗x12+b∗x22+c∗x32+ds.t.:{x12−x2+x32≥0−(x1+x22+x33−20)≥0−x1−x22+2=0x2+2x32−3=0x1,x2,x3≥0min\;f(x) = a*x_1^2 + b*x_2^2 + c*x_3^2 + d\\ s.t.:\begin{cases} x_1^2 - x_2 + x_3^2 \geq 0 \\ -(x_1 + x_2^2 + x_3^3 - 20) \geq 0 \\ -x_1 - x_2^2 + 2 = 0 \\ x_2 + 2x_3^2 - 3 = 0 \\ x_1, x_2, x_3 \geq 0 \end{cases} minf(x)=ax12+bx22+cx32+ds.t.:x12x2+x320(x1+x22+x3320)0x1x22+2=0x2+2x323=0x1,x2,x30


4.2 Python 例程 1:

程序说明:

  1. 在本例程中,目标函数中的参数 a, b, c, d 在子程序中直接赋值,这种实现方式最简单;
  2. 定义边界约束,即优化变量的上下限,与 3.2 中的例程相同,用 minimize() 函数中的选项 bounds=bnds 进行定义。
  3. 定义约束条件:
    • 本案例有 4个约束条件,2个等式约束、2个不等式约束,上节中已写成标准形式;
    • 本例程将每个约束条件作为一个子函数定义,
    • minimize() 函数对约束条件按照字典格式: {‘type’: ‘ineq’, ‘fun’: functionname} 进行定义。‘type’ 的键值可选 ‘eq’ 和 ‘ineq’,分别表示的是约束和不等式约束;functionname是定义约束条件的函数名。
  4. 求解最小化问题 res,其中目标函数 objF4 和搜索的初值点 x0 是必需的,指定优化方法和边界条件、约束条件是可选项。
  5. 通过调用最小化问题的返回值可以得到优化是否成功的说明(res.message)、自变量的优化值(res.x)和目标函数的优化值(res.fun)。

Python 例程:

from scipy.optimize import brent, fmin, minimize
import numpy as np# 4. Demo4:约束非线性规划问题(Scipy.optimize.minimize)
def objF4(x):  # 定义目标函数a, b, c, d = 1, 2, 3, 8fx = a*x[0]**2 + b*x[1]**2 + c*x[2]**2 + dreturn fx# 定义约束条件函数
def constraint1(x):  # 不等式约束 f(x)>=0return 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个约束条件# 求解优化问题
x0 = np.array([1., 2., 3.])  # 定义搜索的初值
res = minimize(objF4, x0, method='SLSQP', bounds=bnds, constraints=cons)print("Optimization problem (res):\t{}".format(res.message))  # 优化是否成功
print("xOpt = {}".format(res.x))  # 自变量的优化值
print("min f(x) = {:.4f}".format(res.fun))  # 目标函数的优化值

例程 1 运行结果:

Optimization problem (res):	Optimization terminated successfully
xOpt = [0.6743061  1.15138781 0.96140839]
min f(x) = 13.8790

4.3 Python 例程 2:

程序说明:

  1. 本例程的问题与 4.2 中的例程 1 是相同的,结果也相同,但编程实现的方法进行了改进;

  2. 本例程中目标函数中的参数 a, b, c, d 在主程序中赋值,通过 args 把参数传递到子程序,这种实现方式使参数赋值更为灵活,特别是适用于可变参数的问题;注意目标函数的定义不是 def objF5(x,args),而是 def objF5(args),要特别注意目标函数的定义和实现方法。

  3. 定义约束条件:

    • 本案例有 4 个约束条件,2个等式约束、2个不等式约束,上节中已写成标准形式;
    • 本例程将 4 个约束条件放在一个子函数中定义,是程序更加简洁。
    • 注意每个约束条件仍然按照字典格式 {‘type’: ‘ineq’, ‘fun’: functionname} 进行定义,但 functionname 并不是函数名,而是一个 lambda 匿名函数。
  4. 通过调用最小化问题的返回值可以得到优化是否成功的说明(res.message)、自变量的优化值(res.x)和目标函数的优化值(res.fun)。

Python 例程 2:

from scipy.optimize import brent, fmin, minimize
import numpy as np# 5. Demo5:约束非线性规划问题(Scipy.optimize.minimize)
def objF5(args):  # 定义目标函数a,b,c,d = argsfx = lambda x: a*x[0]**2 + b*x[1]**2 + c*x[2]**2 + dreturn fxdef constraint1():  # 定义约束条件函数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)})  # 等式约束return cons# 定义边界约束
b = (0.0, None)
bnds = (b, b, b)
# 定义约束条件
cons = constraint1()
args1 = (1,2,3,8)  # 定义目标函数中的参数
# 求解优化问题
x0 = np.array([1., 2., 3.])  # 定义搜索的初值
res1 = minimize(objF5(args1), x0, method='SLSQP', bounds=bnds, constraints=cons)print("Optimization problem (res1):\t{}".format(res1.message))  # 优化是否成功
print("xOpt = {}".format(res1.x))  # 自变量的优化值
print("min f(x) = {:.4f}".format(res1.fun))  # 目标函数的优化值

例程 2 运行结果:

Optimization problem (res1):	Optimization terminated successfully
xOpt = [0.6743061  1.15138781 0.96140839]
min f(x) = 13.8790

4.4 Python 例程 3:

程序说明:

  1. 本例程的问题与 4.3 中的例程 2 是相同的,结果也相同,但编程实现的方法进行了改进;
  2. 本例程中约束条件中的参数在主程序中赋值,通过 args 把参数传递到约束条件定义的子程序,这种实现方式使参数赋值更为灵活,特别是适用于可变参数的问题。
  3. 本例程中将边界约束条件即自变量的取值范围作为不等式约束条件处理,不另作边界条件设置。
  4. 通过调用最小化问题的返回值可以得到优化是否成功的说明(res.message)、自变量的优化值(res.x)和目标函数的优化值(res.fun)。

Python 例程 3:

from scipy.optimize import brent, fmin, minimize
import numpy as np# 6. Demo6:约束非线性规划问题(Scipy.optimize.minimize)
def objF6(args):  # 定义目标函数a,b,c,d = argsfx = lambda x: a*x[0]**2 + b*x[1]**2 + c*x[2]**2 + dreturn fxdef constraint2(args):xmin0, xmin1, xmin2 = argscons = ({'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 >= xmin2return 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))  # 目标函数的优化值

例程 3 运行结果:

Optimization problem (res2):	Optimization terminated successfully
xOpt = [0.6743061  1.15138781 0.96140839]
min f(x) = 13.8790


5. 小结

Scipy 工具包中的 minimize() 函数集成了多种求解线性规划问题的算法,可以处理边界条件和等式、不等式约束,对于常见的非线性规划问题都能获得较好的解。

minimize() 函数对于等式约束、不等式约束条件的编程定义了标准形式和输入格式,通过对比 4.2~4.4 的 3个例程可以帮助读者理解有关的格式要求。

【本节完】



版权说明:

欢迎关注『Python小白的数学建模课 @ Youcans』 原创作品

CSDN 原创作品,转载必须标注原文链接:https://blog.csdn.net/youcans/article/details/118396836。

Copyright 2021 Youcans, XUPT

Crated:2021-06-30


欢迎关注 『Python小白的数学建模课 @ Youcans』 系列,持续更新
Python小白的数学建模课-01.新手必读
Python小白的数学建模课-02.数据导入
Python小白的数学建模课-03.线性规划
Python小白的数学建模课-04.整数规划
Python小白的数学建模课-05.0-1规划
Python小白的数学建模课-06.固定费用问题
Python小白的数学建模课-07.选址问题
Python小白的数学建模课-09.微分方程模型
Python小白的数学建模课-10.微分方程边值问题
Python小白的数学建模课-12.非线性规划
Python小白的数学建模课-15.图论的基本概念
Python小白的数学建模课-16.最短路径算法
Python小白的数学建模课-17.条件最短路径算法
Python小白的数学建模课-18.最小生成树问题
Python小白的数学建模课-19.网络流优化问题
Python小白的数学建模课-A1.国赛赛题类型分析
Python小白的数学建模课-A2.2021年数维杯C题探讨
Python小白的数学建模课-A3.12个新冠疫情数模竞赛赛题及短评
Python小白的数学建模课-B2. 新冠疫情 SI模型
Python小白的数学建模课-B3. 新冠疫情 SIS模型
Python小白的数学建模课-B4. 新冠疫情 SIR模型
Python小白的数学建模课-B5. 新冠疫情 SEIR模型
Python小白的数学建模课-B6. 新冠疫情 SEIR改进模型
Python数模笔记-PuLP库
Python数模笔记-StatsModels统计回归
Python数模笔记-Sklearn
Python数模笔记-NetworkX
Python数模笔记-模拟退火算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序真机如何清除订阅数据

在做小程序订阅消息开发的过程中发现&#xff0c;真机上如果是选择了‘总是保持以上选择’&#xff0c;一旦用户授权后&#xff0c;后面就不会再弹出申请改订阅消息的授权弹窗&#xff0c;这对于开发过程中是很不方便的。 曾试过清除缓存&#xff0c;重进小程序也不能清除掉 解…

Python小白的数学建模课-15.图论的基本概念

图论中所说的图&#xff0c;不是图形图像或地图&#xff0c;而是指由顶点和边所构成的图形结构。图论不仅与拓扑学、计算机数据结构和算法密切相关&#xff0c;而且正在成为机器学习的关键技术。本系列结合数学建模的应用需求&#xff0c;来介绍 NetworkX 图论与复杂网络工具包…

swift面向对象之属性

swift面向对象之属性 swift属性存储属性 可以存储常量和变量 惰性存储属性 语法&#xff1a;lazy var 变量 惰性存储属性只有在用的时候才会完成真正的初始化&#xff0c;刚开始的初始化代码只是类型占位&#xff0c;并没有分配存储空间。 比如 class people{ var name:Strin…

Python小白的数学建模课-16.最短路径算法

最短路径问题是图论研究中的经典算法问题&#xff0c;用于计算图中一个顶点到另一个顶点的最短路径。在图论中&#xff0c;最短路径长度与最短路径距离却是不同的概念和问题&#xff0c;经常会被混淆。求最短路径长度的常用算法是 Dijkstra 算法、Bellman-Ford 算法和Floyd 算法…

虚拟机(centos)磁盘空间不够

磁盘空间不够 1.关机 2.打开设置-->硬盘 --> 扩展 3.搞定一半 4.开机进入终端 4.1 查看 lsblk 4.2 加起来 growpart /dev/sda 3 注1&#xff1a; 如果 growpart 提示没有的话需要安装一下 yum -y install cloud-utils-growpart 注2&#xff1a;3前面有个空格 4.3 再次…

swift面向对象之方法

swift面向对象之方法 1.下标方法 下标方法仅用于实例&#xff0c;可以在类&#xff0c;结构体&#xff0c;枚举中使用&#xff0c;作用简化类型中的访问方式&#xff0c;注意以下几点 下标方法属于三栖方法&#xff0c;可用于类&#xff0c;结构体和枚举 下标方法的格式为subsc…

Python小白的数学建模课-17.条件最短路径算法

条件最短路径问题&#xff0c;指带有约束条件、限制条件的最短路径问题。例如&#xff1a; 顶点约束&#xff0c;包括必经点或禁止点的限制&#xff1b; 边的约束&#xff0c;包括必经路段、禁行路段和单向路段&#xff1b;无权路径长度的限制&#xff0c;如要求经过几步或不超…

Python小白的数学建模课-18.最小生成树问题

Python小白的数学建模课-18.最小生成树问题 最小生成树&#xff08;MST&#xff09;是图论中的基本问题&#xff0c;具有广泛的实际应用&#xff0c;在数学建模中也经常出现。路线设计、道路规划、官网布局、公交路线、网络设计&#xff0c;都可以转化为最小生成树问题&#xf…

Css表格

Css表格 Css表格 css表格属性可以帮助你极大的改善表格的外观 1.表格内间距 2.折叠边框 border-collapse属性设置是否将表格边框折叠为单一边框&#xff1a; table { border-collapse:collapse; } 3.表格边框 下面的例子为table、th以及td设置了蓝色边框&#xff1a; …

Python小白的数学建模课-19.网络流优化问题

流在生活中十分常见&#xff0c;例如交通系统中的人流、车流、物流&#xff0c;供水管网中的水流&#xff0c;金融系统中的现金流&#xff0c;网络中的信息流。网络流优化问题是基本的网络优化问题&#xff0c;应用非常广泛。网络流优化问题最重要的指标是边的成本和容量限制&a…

Python小白的数学建模课-20.网络流优化案例

在实际工作和数模竞赛中&#xff0c;网络最大流问题、最小费用流问题和最小费用最大流问题都有很多延伸和推广的应用。本文介绍了常见的网络最大流问题、最小费用流问题的应用与推广&#xff0c;及其解题方法。本文选择多源多汇物流转运问题、多商品流问题案例&#xff0c;详细…

HTML文档类型

HTML文档类型 HTML5 <!DOCTYPE html> HTML4.01 <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”> XHTML1.0 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w…

Python小白的数学建模课-21.关键路径法

Python小白的数学建模课-21.关键路径法 关键路径法是基于进度网络模型的方法&#xff0c;用网络图表示各项活动之间的相互关系&#xff0c;获得在一定工期、成本、资源约束条件下的最优进度安排。NetworkX 提供了拓扑序列和关键路径的函数&#xff0c;但没有给出计划网络分析的…

swift面向对象之多态与继承

swift面向对象之多态与继承 1.多态 运行时多态 运行时多态的要点 1.要有继承关系的存在 2.子类要重写父类的方法 3.父类类型的引用指向子类实例 2.继承 1.继承的注意 继承可以用于类而不能用于结构体和枚举&#xff0c;继承也可用于协议 swift中不能使用多继承&#xff0c;oc中…

Python小白的数学建模课-22.插值方法

Python小白的数学建模课-22.插值方法 插值、拟合、回归和预测&#xff0c;都是数学建模中经常提到的概念&#xff0c;也经常被混淆。插值&#xff0c;是在离散数据的基础上补插连续函数&#xff0c;使得插值函数通过全部给定的离散数据点&#xff0c;多用于图像处理和缺失数据处…

Python小白的数学建模课-23.数据拟合全集

拟合是用一个连续函数&#xff08;曲线&#xff09;靠近给定的离散数据&#xff0c;使其与给定的数据相吻合。数据拟合的算法相对比较简单&#xff0c;但调用不同工具和方法时的函数定义和参数设置有所差异&#xff0c;往往使小白感到困惑。本文基于 Scipy 工具包&#xff0c;对…

Css背景

Css背景 1.背景图像&#xff1a;background-image 要把图像放入背景&#xff0c;需要使用background-image 属性。background-image属性的默认值是 none&#xff0c;表示背景上没有放置任何图像。 如果需要设置一个背景图像&#xff0c;必须为这个属性设置一个 URL值&#xff…

Python小白的数学建模课-11.偏微分方程数值解法

偏微分方程可以描述各种自然和工程现象&#xff0c; 是构建科学、工程学和其他领域的数学模型主要手段。 偏微分方程主要有三类&#xff1a;椭圆方程&#xff0c;抛物方程和双曲方程。 本文采用有限差分法求解偏微分方程&#xff0c;通过案例讲解一维平流方程、一维热传导方程…

Css语法

Css语法 如果值为若干个单词&#xff0c;加引号 p {font-family: “sans serif”;} 多重声明&#xff1a;分号隔开 如果要定义不止一个声明&#xff0c;则需要用分号把声明隔开。如 p {text-align:center; color:red;} 你应该在每行只描述一个属性&#xff0c;这样可以增强…