Build a model#
Several of the Gurobi examples build models from scratch. We start by focusing on two: mip1 example and sos example. Both build very simple models to illustrate the basic process.
Typically, the first step in building a model is to create an empty model.
error = GRBnewmodel(env, &model, "mip1", 0, NULL, NULL, NULL, NULL, NULL);
if (error) goto QUIT;
You can optionally create a set of variables when you create the model, as well as specifying bounds, objective coefficients, and names for these variables. These examples add new variables separately.
GRBModel model = new GRBModel(env);
GRBModel model = new GRBModel(env);
GRBModel model = new GRBModel(env);
m = gp.Model("mip1")
Dim model As GRBModel = New GRBModel(env)
Once the model has been created, the typical next step is to add variables.
error = GRBaddvars(model, 3, 0, NULL, NULL, NULL, obj, NULL, NULL, vtype, NULL);
if (error) goto QUIT;
GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "x");
GRBVar x = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x");
GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "x");
GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "x")
Dim x As GRBVar = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x")
The new variable’s lower bound, upper bound, objective coefficient, type, and name are specified as arguments. In C++ and Python, you can omit these arguments and use default values; see the Gurobi Reference Manual for details.
The next step is to add (linear) constraints to the model.
error = GRBaddconstr(model, 3, ind, val, GRB_LESS_EQUAL, 4.0, "c0");
if (error) goto QUIT;
To add a linear constraint in C, you must specify a list of variable
indices and coefficients for the left-hand side, a sense for the
constraint (e.g., GRB_LESS_EQUAL
), and a right-hand side constant.
You can also give the constraint a name; if you omit the name, Gurobi
will assign a default name for the constraint.
In C++ you build a linear constraint by first building linear expressions for the left- and right-hand sides. For C++ the standard mathematical operators such as +, *, <= have been overloaded so that the linear expression resembles a traditional mathematical expression.
model.addConstr(x + 2 * y + 3 * z <= 4.0, "c0");
In C# you build a linear constraint by first building linear expressions for the left- and right-hand sides. For C# the standard mathematical operators such as +, *, <= have been overloaded so that the linear expression resembles a traditional mathematical expression.
model.AddConstr(x + 2 * y + 3 * z <= 4.0, "c0");
In Java you build a linear constraint by first building linear expressions for the left- and right-hand sides. In Java, which doesn’t support operator overloading, you build an expression as follows:
GRBLinExpr expr = new GRBLinExpr();
expr.addTerm(1.0, x); expr.addTerm(2.0, y); expr.addTerm(3.0, z);
You then use the addConstr
method on the GRBModel
object to add
a constraint using these linear expressions for the left- and right-hand
sides:
model.addConstr(expr, GRB.LESS_EQUAL, 4.0, "c0");
In Python you build a linear constraint by first building linear expressions for the left- and right-hand sides. For Python the standard mathematical operators such as +, *, <= have been overloaded so that the linear expression resembles a traditional mathematical expression.
model.addConstr(x + 2 * y + 3 * z <= 4.0, "c0")
In Visual Basic you build a linear constraint by first building linear expressions for the left- and right-hand sides. For Python the standard mathematical operators such as +, *, <= have been overloaded so that the linear expression resembles a traditional mathematical expression.
model.AddConstr(x + 2 * y + 3 * z <= 4.0, "c0")
Once the model has been built, the typical next step is to optimize it
(using GRBoptimize()
in C, model.optimize
in C++, Java, and
Python, or model.Optimize
in C#). You can then query the
X attribute on the variables to retrieve the solution
(and the VarName attribute to retrieve the variable
name for each variable).
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 3, sol);
if (error) goto QUIT;
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;
Console.WriteLine(x.VarName + " " + x.X);
Console.WriteLine(y.VarName + " " + y.X);
Console.WriteLine(z.VarName + " " + z.X);
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));
for v in m.getVars():
print(f"{v.VarName} {v.X:g}")
Console.WriteLine(x.VarName & " " & x.X)
Console.WriteLine(y.VarName & " " & y.X)
Console.WriteLine(z.VarName & " " & z.X)
When querying or modifying attribute values for an array of constraints or
variables, it is generally more efficient to perform the action on the
whole array at once. This is quite natural in the C interface, where most
of the attribute routines take array arguments. In the C++, C#, Java, and
Python interfaces, you can use the get
and set
methods on the
GRBModel
object to work directly with arrays of attribute values
(getAttr
/getAttr
in
Python).
In the mip1, C example, this is done as follows:
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 3, sol);
if (error) goto QUIT;
In the sensitivity C++ example, this is done as follows:
origX = model.get(GRB_DoubleAttr_X, vars, numVars);
In the sudoku C# example, this is done as follows:
double[,,] x = model.Get(GRB.DoubleAttr.X, vars);
In the sudoku Java example, this is done as follows:
double[][][] x = model.get(GRB.DoubleAttr.X, vars);
In the sudoku Python example, this is done as follows:
solution = model.getAttr('X', vars)
In the sudoku Visual Basic example, this is done as follows:
Dim x As Double(,,) = model.Get(GRB.DoubleAttr.X, vars)
Important
We should point out one important subtlety in our interface. We use a lazy update approach to building and modifying a model. When you make changes, they are added to a queue. The queue is only flushed when you optimize the model (or write it to a file). In the uncommon situation where you want to query information about your model before optimizing it, you should call the update method before making your query.