抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > Gurobi优化器使用(一)搭建并求解一个优化模型的过程【C++环境】

Gurobi优化器使用(一)搭建并求解一个优化模型的过程【C++环境】

时间:2018-10-18 21:42:17

相关推荐

Gurobi优化器使用(一)搭建并求解一个优化模型的过程 【C++环境】

Gurobi可以解决的问题文档实例——通过系数矩阵建模并求解解释实例——直接建模并求解求解结果如何读取一个已保存的模型

Gurobi可以解决的问题

文档

官方文档

8.1版本C++接口的官方文档

实例——通过系数矩阵建模并求解

当系数已存入到外部的模型文件中需要读取时可以采用该方法建模,否则不推荐这种方式.

待解决的问题如下:

/* 该例子解决下面的凸二次规划问题:minimize x + y + x^2 + x*y + y^2 + y*z + z^2subject to x + 2 y + 3 z >= 4x + y >= 1x, y, z 非负使用预定义的参数矩阵A和Q进行求解(一般在参数已存入外部数据时使用),否则不推荐使用稠密矩阵的方法。*/#include "gurobi_c++.h"using namespace std;static bool dense_optimize(GRBEnv* env,int rows,int cols,double* c, /* 目标函数的线性系数项 */double* Q, /* 目标函数的二次项 */double* A, /* 约束矩阵 */char* sense, /* 约束不等关系(大于,小于) */double* rhs, /* 右端项向量 */double* lb, /* 变量下界 */double* ub, /* 变量上界 */char* vtype, /* 变量类型 ( continuous , binary , etc .) */double* solution,double* objvalP){GRBModel model = GRBModel(*env);int i, j;bool success = false;/* Add variables to the model */GRBVar* vars = model.addVars(lb, ub, NULL, vtype, NULL, cols);/* Populate A matrix */for (i = 0; i < rows; i++) {GRBLinExpr lhs = 0;for (j = 0; j < cols; j++)if (A[i * cols + j] != 0)lhs += A[i * cols + j] * vars[j];model.addConstr(lhs, sense[i], rhs[i]);}GRBQuadExpr obj = 0;for (j = 0; j < cols; j++)obj += c[j] * vars[j];for (i = 0; i < cols; i++)for (j = 0; j < cols; j++)if (Q[i * cols + j] != 0)obj += Q[i * cols + j] * vars[i] * vars[j];model.setObjective(obj);model.optimize();model.write(" dense.lp");if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL) {*objvalP = model.get(GRB_DoubleAttr_ObjVal);for (i = 0; i < cols; i++)solution[i] = vars[i].get(GRB_DoubleAttr_X);success = true;}delete[] vars;return success;}int main(int argc,char* argv[]){GRBEnv* env = 0;try {env = new GRBEnv();double c[] = {1, 1, 0 };double Q[3][3] = {{1 , 1, 0}, {0, 1, 1}, {0, 0, 1} };double A[2][3] = {{1 , 2, 3}, {1, 1, 0} };char sense[] = {'>', '>' };double rhs[] = {4, 1 };double lb[] = {0, 0, 0 };bool success;double objval, sol[3];success = dense_optimize(env, 2, 3, c, &Q[0][0], &A[0][0], sense, rhs,lb, NULL, NULL, sol, &objval);cout << "x: " << sol[0] << " y: " << sol[1] << " z: " << sol[2] << endl;}catch (GRBException e) {cout << " Error code = " << e.getErrorCode() << endl;cout << e.getMessage() << endl;}catch (...) {cout << " Exception during optimization " << endl;}delete env;return 0;}}

解释

构建Gurobi环境

GRBEnv* env = 0;env = new GRBEnv();

建立模型的实例

GRBModel model = GRBModel(*env);

添加优化变量

GRBVar* vars = model.addVars(lb, ub, NULL, vtype, NULL, cols);GRBVar* addVars(const double* lb, const double* ub,const double* obj, const char* type,const std::string* name, int len);

注意:传入的是指针

添加约束

model.addConstr(const GRBLinExpr& expr, char sense, double rhs,std::string name="");GRBLinExpr lhs = 0;

① GRBLinExpr是线性表示类,源代码通过运算符重载,使它可以表示为GRBVar* vars的线性组合.

② sense是char类型,指约束的不等关系,‘>’

③ rhs是不等式右边的项

④ 一次只能添加一个约束,可以放到循环里面

设置目标函数

GRBQuadExpr obj = 0;

目标函数是二次型,与GRBLinExpr一样的方式,不过obj可以表示为二次。

添加目标函数,并进行优化

model.setObjective(obj);model.optimize();

保存优化好的模型

model.write(" dense.lp");

模型文件格式说明

打印优化结果

if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL) {*objvalP = model.get(GRB_DoubleAttr_ObjVal);for (i = 0; i < cols; i++)solution[i] = vars[i].get(GRB_DoubleAttr_X);

打印最优目标值和最优解

释放空间

一般定义了指针的话需要手动释放变量和环境

delete[] vars;delete env;

实例——直接建模并求解

这种建模方式直接了当.

/* 该例子解决下面的凸二次规划问题:minimize x + y + x^2 + x*y + y^2 + y*z + z^2subject to x + 2 y + 3 z >= 4x + y >= 1x, y, z 非负直接求解*/#include "gurobi_c++.h"using namespace std;int main(int argc, char* argv[]){GRBEnv* env = 0;try {env = new GRBEnv();GRBModel model = GRBModel(* env);// Create VariablesGRBVar x = model.addVar(0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "x");GRBVar y = model.addVar(0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "y");GRBVar z = model.addVar(0, GRB_INFINITY, 1.0, GRB_CONTINUOUS, "z");model.setObjective(x + y + x * x + x * y + y * y + y * z + z * z, GRB_MINIMIZE);model.addConstr(x + 2 * y + 3 * z >= 4, "c0");model.addConstr(x + y >= 1, "c1");// Optimize modelmodel.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: " << model.get(GRB_DoubleAttr_ObjVal) << endl;}catch (GRBException e) {cout << " Error code = " << e.getErrorCode() << endl;cout << e.getMessage() << endl;}catch (...) {cout << " Exception during optimization " << endl;}delete env;return 0;}

求解结果

两种方法求解结果是一样的

如何读取一个已保存的模型

以.lp模型为例。

GRBModel model = GRBModel(*env, "dense.lp");GRBVar x = model.getVar(0);GRBVar y = model.getVar(1);GRBVar z = model.getVar(2);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: " << model.get(GRB_DoubleAttr_ObjVal) << endl;

大部分内容跟上面是类似的,只不过在model构造函数的时候,从filename中读取模型。然后再获得变量值,进行模型优化。值得注意的是,lp文件指保留了模型的信息,并没有保存上一次优化后的结果。因此需要重新优化一下方可显示结果。

如果觉得《Gurobi优化器使用(一)搭建并求解一个优化模型的过程【C++环境】》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。