python非线性规划用啥模块

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python非线性规划用啥模块相关的知识,希望对你有一定的参考价值。

python非线性规划用什么模块本文使用SciPy的optimize模块来求解非线性规划问题,结合实际例子,引入非线性规划问题的求解算法及相应函数的调用。

本文提纲一维搜索/单变量优化问题

无约束多元优化问题

非线性最小二乘问题

约束优化问题

非线性规划问题的目标函数或约束条件是非线性的。本文使用SciPy的optimize模块来求解非线性规划问题。

目标函数和约束条件是否连续光滑是非常重要的性质,这是因为如果光滑,则所有决策变量可微,多变量函数的偏导数组成的向量为梯度,梯度是指向目标函数增长最快的方向。将目标函数梯度作为搜索方向,对非线性规划问题的求解具有重要的意义。这些函数或其导数\梯度的不连续性给许多现有的非线性优化问题的求解带来了困难。在下文中,我们假设这些函数是连续且光滑的。

# Importing Modules

from scipy import optimize

import matplotlib.pyplot as plt

import numpy as np

import sympy

1、一维搜索/单变量优化问题(Univariate Optimization)

无约束非线性规划最简单的形式是一维搜索。一维搜索通常作为多维优化问题中的一部分出现,比如梯度下降法中每次最优迭代步长的估计。求解一维搜索常用的两类方法是函数逼近法和区间收缩法。其中函数逼近法是指用较简单的函数近似代替原来的函数,用近似函数的极小点来估计原函数的极小点,比如牛顿法;区间收缩法对于一个单谷函数通过迭代以不断缩小该区间的长度,当区间长度足够小时,可将该区间中的一点作为函数的极小点,比如黄金分割法。

e.g. 最小化一个单位体积的圆柱体的表面积。

r, h = sympy.symbols("r, h")

Area = 2 * sympy.pi * r**2 + 2 * sympy.pi * r * h

Volume = sympy.pi * r**2 * h
参考技术A Python中有许多非线性规划模块可供使用,其中包括:
1. scipy.optimize:scipy.optimize包含多个优化算法,其中包括非线性规划的SLSQP、TNC、COBYLA、and L-BFGS-B算法,可以用来求解凸优化问题。
2. PuLP:PuLP是一个Python线性规划框架,可以用来解决线性规划和非线性规划问题。
3. CVXOPT:CVXOPT是一个开源的解决线性和非线性规划问题的Python库,它提供了一组用于解决线性规划,二次规划,半正定规划等问题的算法。
4. Pyomo:Pyomo是一个Python算法建模库,用于解决优化问题,包括线性规划,非线性规划,混合规划,可行性,离散优化等问题。
5. PyGMO:PyGMO是一个用于求解优化问题的Python库,支持非线性规划,混合规划,离散优化等问题。
参考技术B 你可以用Python的scipy模块来实现非线性规划。该模块提供了一系列用于解决数值优化问题和最优化问题的函数,其中一些用于解决非线性规划问题。你可以用Python的scipy模块来实现非线性规划。该模块提供了一系列用于解决数值优化问题和最优化问题的函数,其中一些用于解决非线性规划问题。 参考技术C Python有许多用于非线性规划的模块,包括:scipy.optimize,cvxopt,pyopt,pulp,pyomo,cvxpy,nlopt,pyipopt,pygmo,nloptr,scipy-least-squares,ipopt,pygmo2,pygmo-mpi,gpyopt,pyoptsparse,lmfit,qpsolvers等。 参考技术D Python中有许多用于非线性规划的模块,包括scipy.optimize、cvxopt、pyOpt、pyomo等。

Python之建模规划篇--非线性规划

Python之建模规划篇--非线性规划

基本介绍

如果目标函数或约束条件中包含非线性函数,就称这种规划问题为非线性规划问
题。一般说来,解非线性规划要比解线性规划问题困难得多。而且,也不象线性规划有
单纯形法这一通用方法,非线性规划目前还没有适于各种问题的一般算法,各个方法都
有自己特定的适用范围。
这是一个非线性规划问题的一般形式

对于一个实际问题,在把它归结成非线性规划问题时,一般要注意如下几点:
(i)确定供选方案:首先要收集同问题有关的资料和数据,在全面熟悉问题的基础上,确认什么是问题的可供选择的方案,并用一组变量来表示它们。
(ii)提出追求目标:经过资料分析,根据实际需要和可能,提出要追求极小化或极大化的目标。并且,运用各种科学和技术原理,把它表示成数学关系式。
(iii)给出价值标准:在提出要追求的目标之后,要确立所考虑目标的“好”或“坏”的价值标准,并用某种数量形式来描述它。
(iv)寻求限制条件:由于所追求的目标一般都要在一定的条件下取得极小化或极大化效果,因此还需要寻找出问题的所有限制条件,这些条件通常用变量之间的一些不等式或等式来表示。

线性规划与非线性规划的区别

如果线性规划的最优解存在,其最优解只能在其可行域的边界上达到(特别是可行域的顶点上达到);而非线性规划的最优解(如果最优解存在)则可能在其可行域的任意一点达到。

非线性规划的Matlab解法


它的返回值是向量x,其中 FUN 是用M 文件定义的函数 f (x);X0是x的初始值;A,B,Aeq,Beq 定义了线性约束 A* X ≤ B, Aeq * X = Beq ,如果没有线性约束,则A=[],B=[],Aeq=[],Beq=[];LB 和UB 是变量x 的下界和上界,如果上界和下界没有约束,则LB=[],UB=[],如果x 无下界,则LB 的各分量都为-inf,如果x 无上界,则UB的各分量都为 inf;NONLCON 是用M 文件定义的非线性向量函数C(x),Ceq(x);OPTIONS定义了优化参数,可以使用Matlab 缺省的参数设置。

下面给一个例子

多余的我就不多说了,matlab的可以详细看书
现在我们来看看再仔细看看非线性规划问题的解法到底有什么

Python 解决非线性规划

  • 非线性规划可以简单分两种,目标函数为凸函数or非凸函数
  • 凸函数的非线性规划,比如fun= x2 +y2 +xy,有很多常用库完成,比如cvxpy
  • 非凸函数的非线性规划(求极值),可以尝 试以下方法:
    • 纯数学方法,求导求极值
    • 神经网络、深度学习(反向传播算法中链式求导过程)
    • scipy. opt imize. minimize

scipy . optimize .minimize (fun, x0, args= () , method=None,jaC=None, hess=None, hes sp=None, bounds=None, constaints= (),tol =None, callback=None, options=None)
fun:求最小值的目标函数
args:常数值
method:求极值方法,一般默认。
constraints:约束条件
x0:变量的初始猜测值,注意minimize是局部最优

1、等式约束下的拉格朗日乘子法

<font size=3公式推导:这里只是简单的放了一张图片对等式约束下拉格朗日乘子法的求解步骤进行了讲解。

2、Python实现对带约束的非线性规划求解

<font size=3求解实际例题

Python编程实现求解

#导入sympy包,用于求导,方程组求解等等
from sympy import *
#设置变量
x1 = symbols("x1")
x2 = symbols("x2")
alpha = symbols("alpha")
#beta = symbols("beta")

#构造拉格朗日等式
L = 60 - 10*x1 - 4*x2 + x1*x1 + x2*x2 - x1*x2 - alpha * (x1 + x2 - 8)

#求导,构造KKT条件
difyL_x1 = diff(L, x1) #对变量x1求导
difyL_x2 = diff(L, x2) #对变量x2求导
difyL_alpha = diff(L, alpha) #对alpha求导
#求解KKT等式
aa = solve([difyL_x1, difyL_x2, difyL_alpha], [x1, x2, alpha])
print(aa)

python使用SciPy库实现求解问题

from scipy.optimize import minimize
import numpy as np
#目标函数:
def func(args):
    fun = lambda x: 60 - 10*x[0] - 4*x[1] + x[0]**2 + x[1]**2 - x[0]*x[1] 
    return fun

#约束条件,包括等式约束和不等式约束
def con(args):
    cons = ('type': 'eq', 'fun': lambda x: x[0]+x[1]-8)
    return cons

if __name__ == "__main__":
    args = ()
    args1 = ()
    cons = con(args1)
    x0 = np.array((2.0, 1.0)) #设置初始值,初始值的设置很重要,很容易收敛到另外的极值点中,建议多试几个值

    #求解#
    res = minimize(func(args), x0, method='SLSQP', constraints=cons)
    print(res.fun)
    print(res.success)
    print(res.x)

结果对比

1.普通法求结果

2.scipy库求结果

通过两个Python程序的求解结果对比分析,两个的求解结果相差不大,并且误差都在一定范围内,所以可以认为两个的求解结果是一致的。

样例1

计算1/x+x的最小值
如果我们足够熟悉这个函数的性质,我们可以很容易得出来,在x>0的时候,他的最小值为2,因为这是一个双勾函数,为奇函数,可以由基本不等式得到他的最小值,但是我们怎么用程序去实现呢

from scipy.optimize import minimize
import numpy as np
#计算 1/x+x 的最小值
def fun(args):
    a=args
    v=lambda x:a/x[0] +x[0]
    return v
if __name__ == "__main__":
    args = (1) #a
    x0 = np.asarray((2)) # 初始猜测值
    res = minimize(fun(args), x0, method='SLSQP')
    print(res)
#     print(res.fun)
#     print(res.success)
#     print(res.x)

可以得到如下结果,我们可以得到函数的最小是为2点多,可以看出minimize求的局部最优

样例2

计算(2+x1)/ (1+x2) - 3x1 + 4x3的最小值,其中x1、x2、x3范围在0.1到0.9之间

from scipy.optimize import minimize
import numpy as np

# 计算(2+x1)/ (1+x2) - 3x1 + 4x3的最小值,其中x1、x2、x3范围在0.1到0.9之间

def fun(args):
    a,b,c,d = args
    v = lambda x: (a+x[0])/(b+x[1]) - c*x[0] + d*x[2]
    return v

def con(args):
    # 约束条件 分为eq 和ineq
    #eq表示 函数结果等于0 ; ineq 表示 表达式大于等于0
    x1min,x1max,x2min,x2max,x3min,x3max = args
    cons = ('type':'ineq','fun':lambda x:x[0]-x1min,\\
    'type':'ineq','fun': lambda x:-x[0]+x1max,\\
    'type':'ineq','fun': lambda x:x[1]-x2min,\\
    'type':'ineq','fun': lambda x:-x[1]+x2max,\\
    'type':'ineq','fun': lambda x:x[2]-x3min,\\
    'type':'ineq','fun': lambda x:-x[2]+x3max)
    return cons
if __name__ == "__main__":
    #定义常量值
    args = (2,1,3,4) #a,b,c,d
    #设置参数范围/约束条件
    args1 = (0.1,0.9,0.1,0.9,0.1,0.9) #x1min, x1max, x2min, x2max
    cons = con(args1)
    #设置初始猜测值
    x0 = np.asarray((0.5,0.5,0.5))
    res = minimize(fun(args),x0,
    method='SLSQP',constraints=cons)
    print(res)
    print(res.fun)
    print(res.success)
    print(res.x)

可以看出对于这类简单函数,局部最优解与真实最优解相差不大,但是对于复杂的函数,x0的初始值设置,会很大程度影响最优解的结果。

ADD:
全局最优的函数: scipy.optimize.basinhopping
有一个缺点是无法设置约束,求全局的最优解的函数
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.basinhopping.html

每日一句
Don’t try so hard, the best things come when you least expect them to.
(不要着急,最好的总会在最不经意的时候出现)

以上是关于python非线性规划用啥模块的主要内容,如果未能解决你的问题,请参考以下文章

python求解线性规划问题,百度后发现了scipy模块,optimize,新手希望大神能写个实例,例子如下:

想学python有啥路线可以规划一下吗?

python 线性规划

python的pulp库解决线性规划问题

Python之建模规划篇--线性规划

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