1 最优问题

我们先回顾下最优问题的概念。所谓最优化,就是指在满足某些约束条件的前提下,使得指定的目标函数极大化或极小化的过程。在工业界很多场景都可以归结为一个最优问题,利用合适的最优算法可以极大地提升效率和减小人工成本。通常情况下,现实的优化问题可以抽象为一个非线性规划,即:
m i n i m i z e f ( x ) s u b j e c t t o g i ( x ) ≤ 0 i = 1 , . . . , m h j ( x ) = 0 j = 1 , . . . , l x L ≤ x ≤ x U \begin{aligned} minimize \ &f(\mathsf{x})\\ subject\ to\ &g_i(\mathsf{x})\leq0\ \ i=1,...,m\\ &h_j(\mathsf{x})=0\ \ j=1,...,l\\ &\mathsf{x}^L\leq \mathsf{x} \leq \mathsf{x}^U \end{aligned} minimize subject to ​f(x)gi​(x)≤0  i=1,...,mhj​(x)=0  j=1,...,lxL≤x≤xU​
其中, x = [ x 1 , x 2 , . . . , x n ] T \mathsf{x}=[x_1,x_2,...,x_n]^T x=[x1​,x2​,...,xn​]T为 n n n维列向量,各元素称为决策变量,而 x L \mathsf{x}^L xL, x U \mathsf{x}^U xU表示决策变量的上界和下界; f f f称为目标函数或成本函数, g g g为不等式约束, h h h为等式约束。不同的优化问题通过适当的调整,总可以写成上面的形式。其实优化问题是个非常宽泛的概念,现在很火热的机器学习,其各种核心算法大多数也是在构建一个优化模型,例如神经网络经典的BP算法就属于一个无约束最优算法。
根据决策变量和目标函数的不同,一个非线性规划可以细分成下面这些特殊规划问题,通常我们对于特定的规划问题会有一些专门的算法来解算:

  • 线性规划:所有的函数(包括目标函数和约束条件)都是线性的(在可行域内),如果一个问题可以转化成线性规划,其求解起来是最简单的;
  • 整数规划: 所有的决策变量必须是整数;
  • 0-1规划:整数规划的进一步特殊化,决策变量只能在0和1中取值;
  • 混合整数规划:某些决策变量要求是整数,另一些则是连续变量的线性规划;
  • 混合非线性规划:某些决策变量要求是整数,另一些则是连续变量,约束条件和目标函数可以是非线性函数;
  • 二次规划:在可行域中,目标函数是二次函数,所有约束条件都是线性函数;
  • 凸规划:目标函数是凸函数或凹函数,可行域是凸集的规划;
  • 组合优化问题:这类问题通常需要确定一个整数组合,或者在一些离散变量组合中选择一个最优的组合。某些组合优化问题可以作为线性规划问题进行求解,这样比较简单;但更多的组合优化问题是规模很大并且无法转变为线性规划的,我们通常只需要获得接近最优解的结果而不是绝对最优,这种情况下启发式算法用的比较多。

对各种优化问题,现在已经有很多特定的或一般性的算法,一些第三方公司会以这些算法为核心推出自己的优化软件工具,方便研究者和工程师的应用。那么对于优化工具的使用者来说,他们要做的最核心的工作将是优化问题建模。建模就是采用数学模型来描述物理问题,要根据实际情况抽象出决策变量、目标函数以及约束条件,表述成上述的非线性规划形式。通过建模,我们可以了解问题属于哪一类优化问题,从而采用合适的优化工具来处理。

2 Google OR-Tools的特点

Google OR-Tools是谷歌前才几年推出的优化套件,是一个相当新的优化库,其社区也是相当活跃,毕竟谷歌的影响力摆在那呢,可是也因为是谷歌的产品,其官网地址国内得翻墙才能访问。我个人在最近的一个项目里使用的就是Google OR-Tools,根据官方的资料和我自己的使用体验,总结下来有下面这些特点:

  • 跨平台性:我认为这是它最吸引人的一点了,首先它的核心算法是基于C++写的,因此它天然地具有跨平台性,其次呢支持团队还分别针对C#、Java和python对核心算法库进行了封装,因此无论你是哪种技术栈都可以直接调用。
  • 面向具体问题的套件组成:之所以叫它优化工具套件,是因为OR-Tools集合了各种优化算法,在软件层面,按照不同的优化问题类型,提供了不同的类库和接口。比如对最简单的线性规划问题,可以使用Linear Solver来解决;对于路径最优这个特定的问题,可以实例化一个RoutingModel对象来解算。
  • 开源和开放:遵循Apache License 2.0,完全不用担心费用问题。另一方面,OR-Tools还支持第三方的求解器,你可以接入Gurobi, CPLEX这类商用求解器,或者SCIP, GLPK, GLOP等开源求解器来解算用OR-Tools建好的模型。
  • 偏底层:OR-Tools更倾向于求解器系统,我们需要用它提供的接口构造好问题模型才能计算,因此对应用者的要求偏高,你需要有足够的数学抽象能力才能用好它。与之对应的也有更加一些面向对象的优化工具,比如Optaplanner,工作的重心是放在软件系统的领域建模上。

3 一个Demo

我们来基于OR-Tools写个小的Demo来体验一下。官网的教程是以Python为主的,只在前几章提供了其他语言的源码,我因为C#用的比较多,下面的Demo及后续文章的代码都在.net core平台实现。

我们来求解一个最简单的线性规划问题:
m a x i m i z e 3 x + y 0 ≤ x ≤ 1 0 ≤ y ≤ 2 x + y ≤ 2 \begin{aligned} maximize \ &3x+y \\ &0\leq x \leq 1\\ &0\leq y \leq 2\\ &x+y \leq 2 \end{aligned} maximize ​3x+y0≤x≤10≤y≤2x+y≤2​
用OR-Tools解决优化问题,一般我们都会进行以下的步骤:

  • 定义决策变量
  • 定义约束
  • 定义目标
  • 声明实现了算法的solver对象
  • 调用solver的方法进行计算得到结果

打开VS(最新的OR-Tools需要VS 2019的支持,低于2019的VS可能会报运行时异常),新建一个.Net Core的控制台项目

在Nuget包管理页面中搜索并下载OR-Tools依赖

因为这是个标准的线性规划,我们只需要调用线性优化库来计算。在主程序中添加LinearSolver空间的引用

using Google.OrTools.LinearSolver;

首先我们定义solver对象,线性优化库的程序中是需要依靠solver对象来创建变、约束和目标的,因此这里没有完全依照上面描述的步骤:

//Create the linear solver with the GLOP backend
Solver solver = Solver.CreateSolver("SimpleLpProgram", "GLOP_LINEAR_PROGRAMMING");

接着定义变量,即 x x x和 y y y。MakeNumVar方法的三个参数分别表示变量的下限、上限和名字,这里通过变量定义,就已经加上了原问题的前两个约束。

 //Create variables
Variable x = solver.MakeNumVar(0.0, 1.0, "x");
Variable y = solver.MakeNumVar(0.0, 2.0, "y");
Console.WriteLine("Number of variables = " + solver.NumVariables());

我们需要定义第三个约束。一个Constraint对象就代表一个线性约束,我们通过SetCoefficient方法设置这两个变量的权值都是1,也就表示 0 ≤ x + y ≤ 2 0 \leq x+y \leq 2 0≤x+y≤2

//Create a Linear constraint
Constraint ct = solver.MakeConstraint(0.0, 2.0, "ct");
ct.SetCoefficient(x, 1);
ct.SetCoefficient(y, 1);
Console.WriteLine("Number of constraints = " + solver.NumConstraints());

现在就剩目标还没有定义了,通过solver对象创建Objective对象,并设定一个最大化的目标

//Create the objective function
Objective objective = solver.Objective();
objective.SetCoefficient(x, 3);
objective.SetCoefficient(y, 1);
objective.SetMaximization();

最后我们就可以调用solver的Solve方法计算得到结果了

//Get the result
solver.Solve();
Console.WriteLine("Solution:");
Console.WriteLine("Objective value = " + solver.Objective().Value());
Console.WriteLine("x = " + x.SolutionValue());
Console.WriteLine("y = " + y.SolutionValue());


完整的程序:

using System;
using Google.OrTools.LinearSolver;namespace Demo1
{class Program{static void Main(string[] args){//Create the linear solver with the GLOP backendSolver solver = Solver.CreateSolver("SimpleLpProgram", "GLOP_LINEAR_PROGRAMMING");//Create variablesVariable x = solver.MakeNumVar(0.0, 1.0, "x");Variable y = solver.MakeNumVar(0.0, 2.0, "y");Console.WriteLine("Number of variables = " + solver.NumVariables());//Create a Linear constraintConstraint ct = solver.MakeConstraint(0.0, 2.0, "ct");ct.SetCoefficient(x, 1);ct.SetCoefficient(y, 1);Console.WriteLine("Number of constraints = " + solver.NumConstraints());//Create the objective function Objective objective = solver.Objective();objective.SetCoefficient(x, 3);objective.SetCoefficient(y, 1);objective.SetMaximization();//Get the resultsolver.Solve();Console.WriteLine("Solution:");Console.WriteLine("Objective value = " + solver.Objective().Value());Console.WriteLine("x = " + x.SolutionValue());Console.WriteLine("y = " + y.SolutionValue());}}
}

Google OR-Tools(一) Get Start相关推荐

  1. 使用.NET Core与Google Optimization Tools实现加工车间任务规划

    前一篇文章<使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling>算是一种针对内容的规划,而针对时间顺序任务规划,加工车间的工活儿 ...

  2. Google Optimization Tools介绍

    Google Optimization Tools(OR-Tools)是一款专门快速而便携地解决组合优化问题的套件.它包含了: 约束编程求解器. 简单而统一的接口,用于多种线性规划和混合整数规划求解, ...

  3. Google Webmaster Tools 结构化数据标记使用入门指南

    要想使自己的产品在Google搜索结果有一个好的排名,我们不仅可以在提高Google搜索排名上下功夫,也可以改善我们的产品在Google搜索结果页的结构化数据样式,这样就能够以更准确.更具吸引力的方式 ...

  4. Google Perf Tools安装以及使用

    Google Performance Tools安装以及使用 这边文章都记录在github:https://github.com/NIGHTFIGHTING/gperftools-tutorial 一 ...

  5. Google Optimization Tools实现加工车间任务规划【Python版】

    上一篇介绍了<使用.NET Core与Google Optimization Tools实现加工车间任务规划>,这次将Google官方文档python实现的版本的完整源码献出来,以满足喜爱 ...

  6. 使用.Net Core与Google Optimization Tools实现员工排班计划Scheduling

    上一篇说完<Google Optimization Tools介绍>,让大家初步了解了Google Optimization Tools是一款约束求解(CP)的高效套件.那么我们用.Net ...

  7. Google 推出的 web 输入法工具 Google input tools

    这又是一个Google 推出的超牛的服务,随处使用您的词汇和语言,支持各项 Google 服务.Chrome 浏览器.Android 设备和 Windows.Google真的是在下一盘很大的棋, 以后 ...

  8. 【Google Chart Tools: Infographics】谷歌图表工具:信息图表

    https://developers.google.com/chart/infographics/docs/qr_codes 我们可以使用在线的谷歌api对网页网址进行二维码的生成,,其实简单说来也就 ...

  9. OR-Tools|带你了解谷歌开源优化工具(Google Optimization Tools)

    转眼间暑假已经过去一大半了,大家有没有度过一个充实的假期呢?小编这两天可忙了,boss突然说发现了一个很有趣的开源求解器:OR-Tools.经过一番了解,小编发现它对于为解决优化问题而烦恼的小伙伴真的 ...

  10. Web 开发与设计之 Google 兵器谱

    Google 的使命是 Web,在 Google 眼中,未来的一切应用都将 Web 化,一直以来,Google 为 Web 开发与设计者推出了大量免费工具,让他们更好地创建,维护,改善他们的 Web ...

最新文章

  1. WF4.0实战(七):请假流程(带驳回操作)
  2. python【数据结构与算法】深入浅出Linear(线性表)
  3. vue-cli3项目更改favicon图标
  4. BigDecimal add方法问题:调用add后,求和结果没变
  5. jq实现点事图片移动_新品速递 | 移动云图片文字识别类产品全新版本惊喜登场...
  6. Pytorch学习(一)—— 自动求导机制
  7. 使用摄像头录像后,需要删除系统缓存数据!
  8. jquery/js 点击空白区域隐藏某一个层/元素
  9. 体验 CodeSmith
  10. 配置交换机端口聚合(思科、华为、锐捷)
  11. 数据-第19课-递归的应用实战一
  12. NB-iot的M5310A的学习
  13. Unity与 DLL文件 ☀️| 怎样使用 C# 类库 生成一个DLL文件 并 调用!
  14. 看不懂英文文档,是我们英语太差吗?
  15. 盈世邮箱服务器pop3,Coremail私有协议为什么比POP3协议、IMAP协议更好
  16. java bridge_JavaBridge
  17. python判断是否回文_Python语言判断输入的是否是回文数的方法
  18. 【区块链】从一笔交易看区块链运作流程
  19. 头发合成:手绘草图妙变逼真秀发
  20. Python Scrapy 爬虫 - 爬取多级别的页面

热门文章

  1. 豆瓣评分8.5+,这10本书读三遍也不够
  2. Qt编写监控Onvif综合示例(支持云台/预置位/抓图/事件订阅等)
  3. camera Intrinsic and Extrinsic
  4. 逻辑强化(14)原因解释 答案解析
  5. 必应词典NABC分析
  6. 【数据结构】循环队列
  7. No module named ‘torchvision‘
  8. Android第三方集成之一键分享ShareSDK的使用eclipse篇 #CSDN博文精选# #IT# #第三方集成# #安卓#
  9. 石英晶体谐振器的功能有哪些
  10. 渗透攻击exp共享站点(建议收藏❤️)