分别使用 Python 和 Math.Net 调用优化算法
1. Rosenbrock 函数
在数学最优化中,Rosenbrock 函数是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock 在 1960 年提出 。也称为 Rosenbrock 山谷或 Rosenbrock 香蕉函数,也简称为香蕉函数。
Rosenbrock 函数的定义如下:
f(x)=100(y−x2)2+(1−x)2
Rosenbrock 函数的每个等高线大致呈抛物线形,其全域最小值也位在抛物线形的山谷中(香蕉型山谷)。很容易找到这个山谷,但由于山谷内的值变化不大,要找到全域的最小值相当困难。

这篇文章分别用 Python 和 Math.Net 求Rosenbrock函数的最小值
2. Python
Python 里面的 scipy.optimize 提供了丰富的优化算法,对于 Rosenbrock函数,它的求解代码如下:
import numpy as np
from scipy.optimize import minimize
def rosenbrock(x):
return (1 - x[0])**2 + 100 * ((x[1] - x[0] * x[0])**2)
x0 = np.array([1.2, 1.2])
best = minimize(rosenbrock, x0)
print(best)
minimize 有两个参数,其中 rosenbrock 是要去求得最小值得 objective function;x0 是初始值,有时候初始值对结果影响很大。
上面代码得输出如下:
fun: 3.3496916936926394e-12
hess_inv: array([[0.49944334, 0.99865554],
[0.99865554, 2.00167338]])
jac: array([-4.95083209e-05, 2.79682766e-05])
message: 'Desired error not necessarily achieved due to precision loss.'
nfev: 159
nit: 10
njev: 49
status: 2
success: False
x: array([0.99999874, 0.9999976 ])
即 x(1) 和 y(1) 在接近 (1,1) 的情况下,Rosenbrock 函数有最小值,最小值接近 0。
也可以通过参数 'method='nelder-mead' 指定 minimize 使用 Nelder-Mead 算法,Nelder-Mead 算法是一种求多元函数局部最小值的算法,其优点是不需要函数可导并能较快收敛到局部最小值。使用 Nelder-Mead 算法的输出结果如下:
final_simplex: (array([[0.999993 , 0.99998474],
[0.99995096, 0.99990431],
[1.00003347, 1.00007239]]), array([2.05633807e-10, 2.97215547e-09, 4.09754011e-09]))
fun: 2.0563380675204333e-10
message: 'Optimization terminated successfully.'
nfev: 82
nit: 43
status: 0
success: True
x: array([0.999993 , 0.99998474])
其它参数的说明请参考 官方文档。
3. Math.Net
Math.Net 是一个开源项目,旨在构建和维护涵盖基础数学的工具箱,以满足 .Net 开发人员的高级需求和日常需求。其中 Math.NET Numerics 旨在为科学、工程和日常使用中的数值计算提供方法和算法。涵盖的主题包括特殊函数,线性代数,概率模型,随机数,插值,积分变换等等。
要使用 Math.NET Numerics,首先安装它的 Nuget 包:
Install-Package MathNet.Numerics
相比 Python,Math.Net 求解 Rosenbrock 函数的代码复杂些。它先使用 ObjectiveFunction.Value 创建目标函数,然后使用 NelderMeadSimplex 的 FindMinimum 函数求解,代码如下:
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Optimization;
using System;
double Value(Vector<double> input)
{
return Math.Pow((1 - input[0]), 2) + 100 * Math.Pow((input[1] - input[0] * input[0]), 2);
}
var obj = ObjectiveFunction.Value(Value);
var solver = new NelderMeadSimplex(convergenceTolerance: 0.0000000001, maximumIterations: 1000);
var initialGuess = new DenseVector(new[] { 1.2, 1.2 });
var result = solver.FindMinimum(obj, initialGuess);
Console.WriteLine("Value:\t" + result.FunctionInfoAtMinimum.Value);
Console.WriteLine("Point:\t" + result.MinimizingPoint[0] + " , " + result.MinimizingPoint[1]);
Console.WriteLine("Iterations:\t" + result.Iterations);
输出如下:
Value: 5.352382362443507E-19
Point: 1.0000000007114838 , 1.0000000014059296
Iterations: 145
虽然 MathNet.Numerics.Optimization 命名空间下还提供了其它类,例如 BfgsBMinimizer 和 NewtonMinimizer,但它们还需要开发者提供梯度函数,这对我来说太复杂了,反而不如 NelderMeadSimplex 好用。
4. 最后
Math.Net 提供了很多多元函数局部最小值的算法,但比起 Python 还是简化了太多,例如我还搞不清楚 Math.Net 中的优化算法怎么添加约束条件,这方面有机会再研究研究。
分别使用 Python 和 Math.Net 调用优化算法的更多相关文章
- 模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径
模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...
- python单例模式的实现与优化
python单例模式的实现与优化 阅读目录(Content) 单例模式 实现单例模式的几种方式 1.使用模块 2.使用装饰器 3.使用类 4.基于__new__方法实现(推荐使用,方便) 5.基于me ...
- [Python陷阱]os.system调用shell脚本获取返回值
当前有shell个脚本/tmp/test.sh,内容如下: #!/bin/bashexit 11 使用Python的os.system调用,获取返回值是: >>> ret=os.sy ...
- Python编程规范及性能优化(转载)
转载地址:http://codeweblog.com/python编程规范及性能优化/
- python中使用ctypes调用MinGW生成的动态链接库(dll)
关于gcc编译dll的我就不说了,网上举例一大堆,下面以g++为例. 假设有一个test.cpp文件如下: extern "C" { __declspec(dllexport) d ...
- JavaScript中的尾调用优化
文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScr ...
- PHP(Math的调用)
<script> //数学函数(用Math来调用)://round=四舍五入最接近的整数// var l = 1.1;// var y1 = Math.round(l);// docume ...
- 判断python对象是否可调用的三种方式及其区别
查找资料,基本上判断python对象是否为可调用的函数,有三种方法 使用内置的callable函数 callable(func) 用于检查对象是否可调用,返回True也可能调用失败,但是返回False ...
- 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化
项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...
随机推荐
- 10分钟快速入门vue.js
Vue.js是一个轻巧.高性能.可组件化的MVVM库,一套用于构建用户界面的渐进式框架,上手简单,兼容强大. 官方文档:https://cn.vuejs.org/v2/guide/ 下面我们就直接来使 ...
- 20201128-2 【自动化办公】读写csv文件
Exercise 1 import csv # 设置员工发展基金确认表路径 source_path = './员工发展基金确认表.csv' # 设置存放拆分结果文件的文件夹路径 result_path ...
- Mybatis学习-日志与分页
日志 为什么需要日志 如果一个数据库操作出现了异常,需要排错,那么日志就是最好的助手 Mybatis通过使用内置的日志工厂提供日志功能,有一下几种实现方式: SLF4J Apache Commons ...
- 轮廓检测论文解读 | Richer Convolutional Features for Edge Detection | CVPR | 2017
有什么问题可以加作者微信讨论,cyx645016617 上千人的粉丝群已经成立,氛围超好.为大家提供一个遇到问题有可能得到答案的平台. 0 概述 论文名称:"Richer Convoluti ...
- IDEA将Java Web项目打war包
准备工作 1.IntelliJ IDEA开发工具 2.可以正常运行的Java Web项目 打war包流程 1.使用快捷键Ctrl+Alt+Shift+s 或者 鼠标点击选中项目名按F4 打开 Proj ...
- day111:MoFang:邀请好友流程&生成邀请好友二维码&第三方应用识别二维码&本地编译测试&记录邀请人信息
目录 1.邀请业务逻辑流程图 2.邀请好友-前端 3.邀请好友-后端接口(生成二维码) 4.前端获取后端生成的二维码 5.前端长按页面,保存图片到相册 6.客户端通过第三方识别微信二维码,服务端提供对 ...
- Scala中的IO操作及ArrayBuffer线程安全问题
通过Scala对文件进行读写操作在实际业务中应用也比较多,这里介绍几种常用的方式,直接上代码: 1. 从文件中读取内容 object Main { def loadData(): Array[Stri ...
- Python三个处理excel表格的库
三个向excel表格写入数的库:xlwt,xlsxwriter,openpyxl,代码如下: 1 #第一个库,xlwt,不能写超过256列的表格 2 import xlwt 3 4 #新建workbo ...
- iOS常见遍历方法汇总
一.for循环 NSArray *iosArray = @[@"L", @"O", @"V", @"E", @" ...
- win10/win7下vs2013自带IISExpress支持局域网访问
打开IISExpress安装目录(C:\Users\Administrator\Documents\IISExpress\config),一般为我的文档下,用记事本打开applicationhost. ...