建立一个模型


建立一个模型

例子:Bilinear, diet, facility, gc_pwl, gc_pwl_func, genconstr, matrix1, mip1, multiobj,多场景,分段,poolsearch, qcp, qp, sensitivity, sos, sudoku, workforce1, workforce_batchmode, workforce2, workforce3, workforce4, workforce5

Gurobi的几个示例从头开始构建模型。我们首先关注两点:mip1紧急求救信号.两者都构建了非常简单的模型来说明基本流程。

通常,构建模型的第一步是创建一个空模型。这是使用GRBnewmodelC函数:

/*创建一个空模型*/ error = GRBnewmodel(env, &model, "mip1", 0, NULL, NULL, NULL, NULL, NULL);if (error) goto QUIT;
当您创建模型时,您可以选择创建一组变量,以及指定边界、目标系数和这些变量的名称。这些例子分别添加了新变量。

在c++、c#和Java中,您可以使用GRBModel构造函数。在Java中,这看起来像:

//创建空模型GRBModel = new GRBModel(env);
在Python中,类被调用模型,其构造函数类似于GRBModelc++和Java的构造函数:
#创建一个新的模型m = gp.Model("mip1")

一旦创建了模型,典型的下一步就是添加变量。在C语言中,你使用GRBaddvars函数添加一个或多个变量:

错误= GRBaddvars(model, 3,0, NULL, NULL, NULL, obj, NULL, NULL, vtype,
在c++、Java和Python中,可以使用addVar方法模型对象(AddVar在c#)。在Java中,这看起来像:
var x = model.addVar(0.0, 1.0, 0.0, GRB.);二、“x”);
新变量的下界、上界、目标系数、类型和名称被指定为参数。在c++和Python中,你可以省略这些参数而使用默认值;看到Gurobi参考手册获取详细信息。

下一步是向模型添加约束。线性约束通过GRBaddconstrC函数:

错误= GRBaddconstr(model, 3, ind, val, GRB_LESS_EQUAL, 4.0,“c0”);
为了在C中添加一个线性约束,你必须为左边指定一个变量指标和系数列表,一种约束的意义(例如,GRB_LESS_EQUAL),右边是常数。你也可以给约束一个名字;如果您省略了名称,Gurobi将为约束分配一个默认名称。

在c++、c#、Java和Python中,您可以通过首先为左右两边构建线性表达式来构建线性约束。在Java中,它不支持操作符重载,你可以像下面这样构建一个表达式:

//设置目标:最大化x + y + 2 z GRBLinExpr expr = new GRBLinExpr();expr.addTerm (1.0 x);expr.addTerm (1.0, y);expr.addTerm (2.0, z);
然后使用addConstr方法GRBModel对象,使用这些用于左右两边的线性表达式添加约束:
模型。addConstr (expr伽马线暴。LESS_EQUAL, 4.0,“c0”);

对于c++、c#和Python,标准的数学运算符(如+、*、<=)已经重载,以便线性表达式类似于传统的数学表达式。在c++中:

模型。AddConstr(x + 2 * y + 3 * z <= 4.0, "c0");

一旦建立了模型,典型的下一步就是优化它(使用GRBoptimize在C语言中,model.optimizec++, Java, Python,或者模型。优化在c#)。然后,您可以查询X属性来检索解决方案(以及VarName属性检索每个变量的变量名)。在C语言中,X属性检索如下:

error = grbgetdblattr_array (model, GRB_DBL_ATTR_X, 0,3, sol);

在c++中:

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;

在Java中:

System.out.println(x.get(GRB.StringAttr.VarName) + " " +x.get(GRB.DoubleAttr.X));System.out.println(y.get(GRB.StringAttr.VarName) + " " +y.get(GRB.DoubleAttr.X));System.out.println(z.get(GRB.StringAttr.VarName) + " " +z.get(GRB.DoubleAttr.X));

在c#中:

Console.WriteLine (x。VarName+" " + x.X); Console.WriteLine(y.VarName + " " + y.X); Console.WriteLine(z.VarName + " " + z.X);

在Python中:

print('%s %g' % (v. varname, v.x))

当查询或修改约束或变量数组的属性值时,通常一次对整个数组执行操作更有效。这在C接口中是很自然的,其中大多数属性例程都接受数组参数。在c++、c#、Java和Python接口中,您可以使用得到方法GRBModel对象直接使用属性值数组(getAttr/setAttr在Python中)。在数独Java的例子,这样做如下:

double[][][] x = model.get(GRB.DoubleAttr.)X, var);

我们应该指出界面中一个重要的微妙之处。我们使用一个懒惰的更新构建和修改模型的方法。当您进行更改时,它们将被添加到队列中。只有在优化模型(或将其写入文件)时,队列才会被刷新。在不常见的情况下,您希望在优化模型之前查询有关模型的信息,您应该调用更新方法,然后执行查询。