Gurobi:C++优化库配置与例程解析
Gurobi:C++优化库配置
前⾔
由于在之前设计的webots控制器中使⽤MPC需要进⾏优化操作,因此需要选择⼀个C++的优化库,经过查,到了Gurobi
Gurobi 是由美国Gurobi公司开发的新⼀代⼤规模数学规划优化器,在 Decision Tree for Optimization Software ⽹站举⾏的第三⽅优化器评估中,展⽰出更快的优化速度和精度,成为优化器领域的新翘楚。
数学规划优化是应⽤在各个领域中最常见的优化⽅法之⼀,是过去30年当中在实际应⽤中创造价值最巨⼤的优化⽅法。在物流、⽣产制造、⾦融、交通运输、资源管理、集成电路设计、环境保护、电⼒管理等等领域,⼏乎⽆所不在。在世界⼀流的企业资源管理(ERP)、供应链管理(SCM)、运输管理等企业决策⼯具中,都有数学规划优化器的存在。
Gurobi 特点包括
(1)采⽤最新优化技术,充分利⽤多核处理器优势
(2)任何版本都⽀持并⾏计算,并且计算结果确定⽽⾮随机
(3)提供了⽅便轻巧的接⼝,⽀持 C++, Java, Python, .Net 开发,内存消耗少
(4)⽀持多种平台,包括 Windows, Linux, Mac OS X
(5)⽀持 AMPL, GAMS, AIMMS, Tomlab 和 Windows Solver Foundation 建模环境
(6)单⼀版本,开发版本也就是发布版本,程序转移便捷
(7)Gurobi 为学校教师和学⽣提供了免费版本。
(8)和 Matlab 有便捷接⼝。
Gurobi 优化性能显著超过传统优化⼯具
来⾃
1.安装
1)安装包
2)运⾏安装
3)安装后在桌⾯出现⼀个图标,双击打开进⼊Command-Line,进⾏注册
4)在官⽹注册
5) 将注册码复制到双击桌⾯打开的控制台中
6)注册完成
7)打开安装⽬录,在win64\lib⽂件夹下可以看到其静态库
2.环境配置
由于Gurobi的C++库是依赖于Visual Studio的编译器的所以只能在VS中搭建Gurobi的⼯程,另外需要注意的是7中所⽰的静态库后⾯的年份即对应VS的版本
1)新建⼀个空项⽬
2)添加⼀个源⽂件
3)选择VS2015解决⽅案配置和平台,选择Debug模式x64平台
4)配置外部链接库
⾸先是
配置属性->VC++⽬录->包含⽬录中添加安装⽬录下的include⽬录
配置属性->VC++⽬录->库⽬录中添加安装⽬录下的lib⽬录
接下来
C/C+±>代码⽣成->运⾏库 选择/MDd
最后
链接器->输⼊->附加依赖项添加gurobi_c++mdd2015库和通⽤C库gurobi91.lib
注意后⾯的年份与VS版本对应,⽽最后的mdd与上⼀步选择的运⾏库对应,其他的对应也可以使⽤,具体区别请仔细查阅
点击应⽤
3.优化例程
题⽬描述如下
注意最后⼀⾏,XYZ均为binary变量,binary变量的取值只能是0或1
在源⽂件中添加代码
/* Copyright 2019, Gurobi Optimization, LLC */
/* This example formulates and solves the following simple MIP model:
maximize    x +  y + 2 z
subject to  x + 2 y + 3 z <= 4
x +  y      >= 1
x, y, z binary
*/
#include"gurobi_c++.h"
using namespace std;
int main(int  argc,char*argv[])
{
try{
// Create an environment
GRBEnv env =GRBEnv(true);
env.set("LogFile","mip1.log");
env.start();
// Create an empty model
GRBModel model =GRBModel(env);
// Create variables
GRBVar x = model.addVar(0.0,1.0,0.0, GRB_BINARY,"x");
GRBVar y = model.addVar(0.0,1.0,0.0, GRB_BINARY,"y");
GRBVar z = model.addVar(0.0,1.0,0.0, GRB_BINARY,"z");
// Set objective: maximize x + y + 2 z
model.setObjective(x + y +2* z, GRB_MAXIMIZE);
// Add constraint: x + 2 y + 3 z <= 4
model.addConstr(x +2* y +3* z <=4,"c0");
// Add constraint: x + y >= 1
model.addConstr(x + y >=1,"c1");
// Optimize model
model.optimize();
cout << x.get(GRB_StringAttr_VarName)<<" "
<< x.get(GRB_DoubleAttr_X)<< endl;
cout << y.get(GRB_StringAttr_VarName)<<" "
<< y.get(GRB_DoubleAttr_X)<< endl;
cout << z.get(GRB_StringAttr_VarName)<<" "
<< z.get(GRB_DoubleAttr_X)<< endl;
cout <<"Obj: "<< (GRB_DoubleAttr_ObjVal)<< endl;
}catch(GRBException e){
cout <<"Error code = "<< e.getErrorCode()<< endl;
cout << e.getMessage()<< endl;
}catch(...){
cout <<"Exception during optimization"<< endl;
}
system("pause");
return0;
}
运⾏程序
求解完成,即当X=1,Y=0,X=1时取得最⼤值3
4.代码解析
//包含求解库头⽂件以调⽤其接⼝
#include"gurobi_c++.h"
/
/之后创建优化模型的调⽤总是需要⼀个环境,因此环境创建通常是Gurobi应⽤程序的第⼀步。 GRBEnv env =GRBEnv(true);//创建求解环境
env.set("LogFile","mip1.log");//创建求解环选择⼀个⽇志⽂件
env.start();//启动环境
// 创建⼀个空模型
GRBModel model =GRBModel(env);//构造函数将前⾯创建的环境作为参数。
/*
/*
创建变量
变量是通过模型对象上的addVar()⽅法添加的(或者addVars()如果你想⼀次添加多个)。变量总是与特定的模型相关联。
addVar()调⽤的第⼀个和第⼆个参数分别是变量的下界和上界。第三个参数是线性⽬标系数(这⾥为零—
—我们稍后将设置⽬标)。第四个参数是变量类型。在这个例⼦中,变量都是⼆进制的。最后⼀个参数是变量名。
*/
GRBVar x = model.addVar(0.0,1.0,0.0, GRB_BINARY,"x");
GRBVar y = model.addVar(0.0,1.0,0.0, GRB_BINARY,"y");
GRBVar z = model.addVar(0.0,1.0,0.0, GRB_BINARY,"z");
/*
设置⽬标函数: maximize x + y + 2 z
⽬标是在这⾥使⽤重载操作符构建的。c++ API重载算术运算符,允许您构建涉及Gurobi变量的线性和⼆次表达式。
第⼆个论点表明,感觉是最⼤化的。
请注意,虽然这个简单的⽰例使⽤显式的术语列表在单个语句中构建⽬标,但更复杂的程序通常会增
量地构建它。例如:
GRBLinExpr obj = 0.0;
obj += x;
obj += y;
obj += 2*z;
model.setObjective(obj, GRB_MAXIMIZE);
*/
model.setObjective(x + y +2* z, GRB_MAXIMIZE);
/*
添加约束:: x + 2 y + 3 z <= 4
x + y >= 1
与变量⼀样,约束总是与特定的模型相关联。它们是通过模型对象上的addConstr()或addconsts()⽅法创建的。
我们再次使⽤重载算术操作符来构建线性表达式。还重载了⽐较操作符,以便更容易构建约束。
addConstr的第⼆个参数给出了(可选的)约束名称。
同样,这个简单的⽰例使⽤显式的术语列表在单个语句中构建约束的线性表达式。更复杂的程序通常会增量地构建表达式。
visual studio和vs code的区别*/
model.addConstr(x +2* y +3* z <=4,"c0");
model.addConstr(x + y >=1,"c1");
/*
启动优化
该函数执⾏优化并填充⼏个内部模型属性(包括优化的状态、解决⽅案等)。
*/
model.optimize();
/*
输出结果
⼀旦优化完成,就可以查询属性的值。
特别是,可以查询VarName和X属性来获得每个变量的名称和解决⽅案值:
*/
cout << x.get(GRB_StringAttr_VarName)<<" "
<< x.get(GRB_DoubleAttr_X)<< endl;
cout << y.get(GRB_StringAttr_VarName)<<" "
<< y.get(GRB_DoubleAttr_X)<< endl;
cout << z.get(GRB_StringAttr_VarName)<<" "
<< z.get(GRB_DoubleAttr_X)<< endl;
/*
还可以查询模型上的ObjVal属性,获得当前解决⽅案的⽬标函数的值:
*/
cout <<"Obj: "<< (GRB_DoubleAttr_ObjVal)<< endl;
/*
Gurobi c++接⼝中的错误通过c++异常机制来处理。
在这个例⼦中,所有Gurobi语句都包含在⼀个try块中,任何相关的错误都将被catch块捕获:
*/
}catch(GRBException e){
cout <<"Error code = "<< e.getErrorCode()<< endl;    cout << e.getMessage()<< endl;
}catch(...){
cout <<"Exception during optimization"<< endl;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。