【Scipy优化使用教程】二、Scipy中有约束优化的两种算法

这篇具有很好参考价值的文章主要介绍了【Scipy优化使用教程】二、Scipy中有约束优化的两种算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考官网:Scipy.

对于有约束的最小化问题,Scipy提供的minimize这个包有三个:trust-constr, SLSQP'COBYLA。它们要求使用稍微不同的结构来定义约束。
trust-constr需要要求约束被定义成一系列的LinearConstraintNonlinearConstraint两种类型。
SLSQP'COBYLA需要要求约束条件被定义为一连串的字典,其键为typefunjac
考虑有约束的最小化2个变量的Rosenbrock函数
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
这个问题有唯一解: [ x 0 , x 1 ] = [ 0.4149 , 0.1701 ] [x_0,x_1]=[0.4149,0.1701] [x0,x1]=[0.4149,0.1701]

信赖域约束算法(method=‘trust-constr’)

信任域约束方法处理的是约束性最小化问题,其形式为:
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
除此之外,单边约束可以通过对np.inf设置上限或下限并加上适当的符号来指定。

定义边界约束

边界限制 0 ≤ x 0 ≤ 1 , − 0.5 ≤ x 1 ≤ 2.0 0≤x_0≤1,-0.5≤x_1≤2.0 0x01,0.5x12.0被定义如下:

from scipy.optimize import Bounds
bounds = Bounds([0, -0.5], [1.0, 2.0])

定义线性约束

约束 x 0 + 2 x 1 ≤ 1 , 2 x 0 + x 1 = 1 x_0+2x_1≤1,2x_0+x_1=1 x0+2x112x0+x1=1可以写成如下形式:
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
LinearConstraint去定义:

from scipy.optimize import LinearConstraint
linear_constraint = LinearConstraint([[1, 2], [2, 1]], [-np.inf, 1], [1, 1])

定义非线性约束

非线性约束为:
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
其雅可比矩阵(对每个变量求导)为:
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
黑塞矩阵的线性组合:
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
NonlinearConstraint去定义:

#定义非线性约束
def cons_f(x):
    return [x[0]**2 + x[1], x[0]**2 - x[1]]
#定义导数
def cons_J(x):
    return [[2*x[0], 1], [2*x[0], -1]]
#定义二阶导数
def cons_H(x, v):
    return v[0]*np.array([[2, 0], [0, 0]]) + v[1]*np.array([[2, 0], [0, 0]])
from scipy.optimize import NonlinearConstraint
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=cons_H)

另外,也可以将Hessian定义为一个稀疏矩阵。

from scipy.sparse import csc_matrix
def cons_H_sparse(x, v):
    return v[0]*csc_matrix([[2, 0], [0, 0]]) + v[1]*csc_matrix([[2, 0], [0, 0]])
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1,
                                           jac=cons_J, hess=cons_H_sparse)

当黑塞矩阵难以计算的时候,可以使用HessianUpdateStrategy,目前可用的策略有:BFGSSR1

from scipy.optimize import BFGS
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=BFGS())

另外,Hessian可以用有限差分法进行近似。

nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess='2-point')

雅可比矩阵也可以用有限差分法估计,然而,在这种情况下,黑塞不能用有限差分计算,需要由用户提供或用之前介绍的HessianUpdateStrategy定义:

nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac='2-point', hess=BFGS())

求解

#设置初值
x0 = np.array([0.5, 0])
#这个需要结合之前无约束的算法来计算
res = minimize(rosen, x0, method='trust-constr', jac=rosen_der, hess=rosen_hess,
               constraints=[linear_constraint, nonlinear_constraint],
               options={'verbose': 1}, bounds=bounds)
print(res.x)

无约束代码在这里

`gtol` termination condition is satisfied.
Number of iterations: 12, function evaluations: 8, CG iterations: 7, optimality: 2.99e-09, constraint violation: 0.00e+00, execution time: 0.014 s.
[0.41494531 0.17010937]

完整代码

import numpy as np
from scipy.optimize import minimize
#无约束
def rosen(x):
    """The Rosenbrock function"""
    return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)

def rosen_der(x):
    xm = x[1:-1]
    xm_m1 = x[:-2]
    xm_p1 = x[2:]
    der = np.zeros_like(x)
    der[1:-1] = 200*(xm-xm_m1**2) - 400*(xm_p1 - xm**2)*xm - 2*(1-xm)
    der[0] = -400*x[0]*(x[1]-x[0]**2) - 2*(1-x[0])
    der[-1] = 200*(x[-1]-x[-2]**2)
    return der
def rosen_hess(x):
    x = np.asarray(x)
    H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1)
    diagonal = np.zeros_like(x)
    diagonal[0] = 1200*x[0]**2-400*x[1]+2
    diagonal[-1] = 200
    diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:]
    H = H + np.diag(diagonal)
    return H

#设置约束
from scipy.optimize import Bounds
bounds = Bounds([0, -0.5], [1.0, 2.0])
from scipy.optimize import LinearConstraint
linear_constraint = LinearConstraint([[1, 2], [2, 1]], [-np.inf, 1], [1, 1])

def cons_f(x):
    return [x[0]**2 + x[1], x[0]**2 - x[1]]
#定义导数
def cons_J(x):
    return [[2*x[0], 1], [2*x[0], -1]]
#定义二阶导数
def cons_H(x, v):
    return v[0]*np.array([[2, 0], [0, 0]]) + v[1]*np.array([[2, 0], [0, 0]])
from scipy.optimize import NonlinearConstraint
nonlinear_constraint = NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=cons_H)

#求解
x0 = np.array([0.5, 0])
res = minimize(rosen, x0, method='trust-constr', jac=rosen_der, hess=rosen_hess,
               constraints=[linear_constraint, nonlinear_constraint],
               options={'verbose': 1}, bounds=bounds)

print(res.x)

另外也可以对目标函数的第一和第二导数进行近似,例如,黑塞矩阵可以用SR1准牛顿法近似,梯度可以用有限差分法近似:

from scipy.optimize import SR1
res = minimize(rosen, x0, method='trust-constr',  jac="2-point", hess=SR1(),
               constraints=[linear_constraint, nonlinear_constraint],
               options={'verbose': 1}, bounds=bounds)
`gtol` termination condition is satisfied.
Number of iterations: 12, function evaluations: 24, CG iterations: 7, optimality: 4.48e-09, constraint violation: 0.00e+00, execution time: 0.02 s.
[0.41494531 0.17010937]

序列最小二乘(SLSQP) (method=‘SLSQP’)

SLSQP需要如下形式:
slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶

设置约束

slsqp,优化求解工具,算法,python,学习,动态规划,自动驾驶
线性和非线性约束都被定义为字典,其键为type、fun和jac:
首先是定义域:

from scipy.optimize import Bounds
bounds = Bounds([0, -0.5], [1.0, 2.0])

等式与不等式约束:

#不等式约束
ineq_cons = {'type': 'ineq',
             'fun' : lambda x: np.array([1 - x[0] - 2*x[1],
                                         1 - x[0]**2 - x[1],
                                         1 - x[0]**2 + x[1]]),
             #jac是对fun的求导
             'jac' : lambda x: np.array([[-1.0, -2.0],
                                         [-2*x[0], -1.0],
                                         [-2*x[0], 1.0]])}
#等式约束
eq_cons = {'type': 'eq',
           'fun' : lambda x: np.array([2*x[0] + x[1] - 1]),
           'jac' : lambda x: np.array([2.0, 1.0])}

求解

x0 = np.array([0.5, 0])
res = minimize(rosen, x0, method='SLSQP', jac=rosen_der,
               constraints=[eq_cons, ineq_cons], options={'ftol': 1e-9, 'disp': True},
               bounds=bounds)
print(res.x)
Optimization terminated successfully    (Exit mode 0)
            Current function value: 0.34271757499419825
            Iterations: 4
            Function evaluations: 5
            Gradient evaluations: 4
[0.41494475 0.1701105 ]

完整代码

import numpy as np
from scipy.optimize import minimize
#定义无约束的目标函数
def rosen(x):
    """The Rosenbrock function"""
    return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)

def rosen_der(x):
    xm = x[1:-1]
    xm_m1 = x[:-2]
    xm_p1 = x[2:]
    der = np.zeros_like(x)
    der[1:-1] = 200*(xm-xm_m1**2) - 400*(xm_p1 - xm**2)*xm - 2*(1-xm)
    der[0] = -400*x[0]*(x[1]-x[0]**2) - 2*(1-x[0])
    der[-1] = 200*(x[-1]-x[-2]**2)
    return der
def rosen_hess(x):
    x = np.asarray(x)
    H = np.diag(-400*x[:-1],1) - np.diag(400*x[:-1],-1)
    diagonal = np.zeros_like(x)
    diagonal[0] = 1200*x[0]**2-400*x[1]+2
    diagonal[-1] = 200
    diagonal[1:-1] = 202 + 1200*x[1:-1]**2 - 400*x[2:]
    H = H + np.diag(diagonal)
    return H

#定义约束
from scipy.optimize import Bounds
bounds = Bounds([0, -0.5], [1.0, 2.0])

ineq_cons = {'type': 'ineq',
             'fun' : lambda x: np.array([1 - x[0] - 2*x[1],
                                         1 - x[0]**2 - x[1],
                                         1 - x[0]**2 + x[1]]),
             'jac' : lambda x: np.array([[-1.0, -2.0],
                                         [-2*x[0], -1.0],
                                         [-2*x[0], 1.0]])}
eq_cons = {'type': 'eq',
           'fun' : lambda x: np.array([2*x[0] + x[1] - 1]),
           'jac' : lambda x: np.array([2.0, 1.0])}
           
#求解
x0 = np.array([0.5, 0])
res = minimize(rosen, x0, method='SLSQP', jac=rosen_der,
               constraints=[eq_cons, ineq_cons], options={'ftol': 1e-9, 'disp': True},
               bounds=bounds)

print(res.x)

PS:大部分 trust-constr方法可用的选项对 SLSQP来说是不可用的。文章来源地址https://www.toymoban.com/news/detail-788379.html

到了这里,关于【Scipy优化使用教程】二、Scipy中有约束优化的两种算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Scipy 中级教程——优化

    Scipy 提供了多种优化算法,用于求解最小化或最大化问题。这些问题可以涉及到拟合模型、参数优化、函数最优化等。在本篇博客中,我们将深入介绍 Scipy 中的优化功能,并通过实例演示如何应用这些算法。 1. 单变量函数最小化 假设我们有一个单变量函数,我们想要找到使

    2024年01月21日
    浏览(8)
  • 缓存平均的两种算法

    缓存平均的两种算法

    引言         线边库存物料的合理性问题是物流仿真中研究的重要问题之一,如果线边库存量过多,则会对生产现场的布局产生负面影响,增加成本,降低效益。 写在前面         仿真分析后对线边Buffer的使用情况进行合理的评估就是一个非常重要的事情。比较关心的参数

    2024年02月13日
    浏览(10)
  • 【数据结构与算法分析】使用C语言实现队列的两种(带头结点与不带头结点)链式存储,并且给出一种循环队列的设计思想

    【数据结构与算法分析】使用C语言实现队列的两种(带头结点与不带头结点)链式存储,并且给出一种循环队列的设计思想

      当我们编写程序时,经常需要处理各种数据结构。队列是一种常见的数据结构,它有着广泛的应用场景。队列的基本操作包括入队和出队,应用于模拟等待队列、消息队列、计算机缓存等场合。   在实际编程中,我们可以用不同的数据结构来实现队列。本文主要介绍了

    2024年02月08日
    浏览(248)
  • Unity3D教程:播放视频的两种方式

    Unity3D教程:播放视频的两种方式

    Unity3D 中播放游戏视频的方式有两种,第一种是在游戏对象中播放,就好比在游戏世界中创建一个Plane面对象,摄像机直直的照射在这个面上。第二种是在GUI层面上播放视频。播放视频其实和贴图非常相像,因为播放视频用到的MovieTexture属于贴图Texture的子类,那么本章我们就

    2024年02月11日
    浏览(15)
  • 关键词提取 | 基于Textrank算法的两种关键词提取

    关键词提取 | 基于Textrank算法的两种关键词提取

    目录 一、PageRank算法 二、TextRank算法 1. 抽取(keyword extraction) 2. 关键短语抽取(keyphrase extration) 3. 关键句抽取(sentence extraction) 三、TextRank算法实现 1. 基于Textrank4zh的TextRank算法实现 2. 基于jieba的TextRank算法实现 3. 基于SnowNLP的TextRank算法实现 四、PageRank算法与Text

    2024年04月14日
    浏览(35)
  • Jenkins安装插件教程 牢记 Jenkis安装插件(plugin)的两种方法

    Jenkins安装插件教程 牢记 Jenkis安装插件(plugin)的两种方法

    目录 jenkins在线安装组件(plugin) jenkins离线安装组件(plugin)         前言:在jenkins学习使用或使用的过程中,由于网络的问题,在选择安装插件的时候,会出现某些插件安装失败。这是需要重新安装(可以选择在线或者离线安装)或者在工作的过程中,部署在jenkins的

    2024年02月16日
    浏览(7)
  • 操作教程|在MeterSphere中通过SSH登录服务器的两种方法

    操作教程|在MeterSphere中通过SSH登录服务器的两种方法

    MeterSphere开源持续测试平台拥有非常强大的插件集成机制,用户可以通过插件实现平台能力的拓展,借助插件或脚本实现多种功能。在测试过程中,测试人员有时需要通过SSH协议登录至服务器,以获取某些配置文件和日志文件,或者启动其他服务、执行脚本等,MeterSphere平台提

    2024年04月09日
    浏览(9)
  • C++ 实现定时器的两种方法(线程定时和时间轮算法修改版)

    定时器要求在固定的时间异步执行一个操作,比如boost库中的boost::asio::deadline_timer,以及MFC中的定时器。也可以利用c++11的thread, mutex, condition_variable 来实现一个定时器。 1、使用C++11中的thread, mutex, condition_variable来实现一个定时器。 注:此算法会每一个任务创建一个线程,不推

    2024年02月05日
    浏览(12)
  • 机器学习笔记之优化算法(一)无约束优化概述

    机器学习笔记之优化算法(一)无约束优化概述

    从本节开始,将介绍 优化算法 ( Optimization Algorithm ) (text{Optimization Algorithm}) ( Optimization Algorithm ) 。 基于支持向量机 ( Support Vector Machine,SVM ) (text{Support Vector Machine,SVM}) ( Support Vector Machine,SVM ) 最大间隔分类器 的朴素思想: 从能够将所有样本点 正确分类 的直线中找到 满足

    2024年02月15日
    浏览(13)
  • 宝塔面板绑定域名之后无法登录的两种解决方法【图文教程亲测有效】

    宝塔面板绑定域名之后无法登录的两种解决方法【图文教程亲测有效】

    手贱,点击了绑定域名,保存后直接报错了!! 为面板绑定一个访问域名,注意:一旦绑定域名,只能通过域名访问面板 报错如下: 去云服务器后台,使用命令: 使用命令 rm -f /www/server/panel/data/domain.conf 删除绑定域名后,就能用ip+端口进入面板了` 是的,就是没有备案导致的

    2024年02月12日
    浏览(15)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包