This section will work through a simple C# example in order to illustrate the use of the Gurobi .NET interface. The example builds a model, optimizes it, and outputs the optimal objective value. This section assumes that you are already familiar with the C# programming language. If not, a variety of books and web sites are available for learning the language (for example, the Microsoft online C# documentation).
Our example optimizes the following model:
maximize | x | + | y | + | 2 z | ||
subject to | x | + | 2 y | + | 3 z | ![]() |
4 |
x | + | y | ![]() |
1 | |||
x, y, z binary |
Example mip1_cs.cs
This is the complete source code for our example (also available in <installdir>/examples/c#/mip1_cs.cs)...
using System; using Gurobi; class mip1_cs { static void Main() { try { GRBEnv env = new GRBEnv("mip1.log"); GRBModel model = new 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"); // Integrate new variables model.Update(); // 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.0, "c0"); // Add constraint: x + y >= 1 model.AddConstr(x + y >= 1.0, "c1"); // Optimize model model.Optimize(); Console.WriteLine(x.Get(GRB.StringAttr.VarName) + " " + x.Get(GRB.DoubleAttr.X)); Console.WriteLine(y.Get(GRB.StringAttr.VarName) + " " + y.Get(GRB.DoubleAttr.X)); Console.WriteLine(z.Get(GRB.StringAttr.VarName) + " " + z.Get(GRB.DoubleAttr.X)); Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal)); // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } } }
Example details
Let us now walk through the example, line by line, to understand how it achieves the desired result of optimizing the indicated model.
The example begins by importing the Gurobi namespace (using Gurobi). Gurobi .NET applications should always start with this line.
Creating the environment
The first executable statement in our example obtains a Gurobi environment (using the GRBEnv() constructor):
GRBEnv env = new GRBEnv("mip1.log");Later calls to create an optimization model will always require an environment, so environment creation is typically the first step in a Gurobi application. The constructor argument specifies the name of the log file.
Creating the model
Once an environment has been created, the next step is to create a model. A Gurobi model holds a single optimization problem. It consists of a set of variables, a set of constraints, and the associated attributes (variable bounds, objective coefficients, variable integrality types, constraint senses, constraint right-hand side values, etc.). The first step towards building a model that contains all of this information is to create an empty model object:
GRBModel model = new GRBModel(env);The constructor takes the previously created environment as its argument.
Adding variables to the model
The next step in our example is to add variables to the model.
// 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");Variables are added through the AddVar() method on a model object. A variable is always associated with a particular model.
The first and second arguments to the AddVar() call are the variable lower and upper bounds, respectively. The third argument is the linear objective coefficient (zero here - we'll set the objective later). The fourth argument is the variable type. Our variables are all binary in this example. The final argument is the name of the variable.
The AddVar() method has been overloaded to accept several different argument lists. Please refer to the Gurobi Reference Manual for further details.
Updating the model - lazy modification
Model modifications in the Gurobi optimizer are done in a lazy fashion, meaning that the effects of the modifications are not seen immediately. This approach makes it easier to perform a sequence of model modifications, since the model doesn't change while it is being modified. However, lazy modifications do require you to manually integrate model changes when needed. This is done with the Update method:
// Integrate new variables model.Update();
Setting the objective
The next step in the example is to set the optimization objective:
// Set objective: maximize x + y + 2 z model.SetObjective(x + y + 2 * z, GRB.MAXIMIZE);
The objective is built here using overloaded operators. The C# API overloads the arithmetic operators to allow you to build linear and quadratic expression involving Gurobi variables.
The second argument indicates that the sense is maximization.
Adding constraints to the model
The next step in the example is to add the constraints:
// Add constraint: x + 2 y + 3 z <= 4 model.AddConstr(x + 2 * y + 3 * z <= 4.0, "c0"); // Add constraint: x + y >= 1 model.AddConstr(x + y >= 1.0, "c1");As with variables, constraints are always associated with a specific model. They are created using the AddConstr() or AddConstrs() methods on the model object.
We again use overloaded arithmetic operators to build linear expressions. The comparison operators are also overloaded to make it easy to build constraints.
The second argument to AddConstr gives the constraint name.
The Gurobi .NET interface also allows you to add constraints by building linear expressions in a term-by-term fashion:
GRBLinExpr expr = 0.0; expr.AddTerm(1.0, x); expr.AddTerm(2.0, x); expr.AddTerm(3.0, x); model.AddConstr(expr, GRB.LESS_EQUAL, 4.0, "c0");This particular AddConstr() signature takes a linear expression that captures the left-hand side of the constraint as its first argument, the sense of the constraint as its second argument, and a linear expression that captures the right-hand side of the constraint as its third argument. The constraint name is given as the fourth argument.
Optimizing the model
Now that the model has been built, the next step is to optimize it:
// Optimize model model.Optimize();This routine performs the optimization and populates several internal model attributes (including the status of the optimization, the solution, etc.).
Reporting results - attributes
Once the optimization is complete, we can query the values of the attributes. In particular, we can query the VarName and X attributes to obtain the name and solution value for each variable:
Console.WriteLine(x.Get(GRB.StringAttr.VarName) + " " + x.Get(GRB.DoubleAttr.X)); Console.WriteLine(y.Get(GRB.StringAttr.VarName) + " " + y.Get(GRB.DoubleAttr.X)); Console.WriteLine(z.Get(GRB.StringAttr.VarName) + " " + z.Get(GRB.DoubleAttr.X));
We can also query the ObjVal attribute on the model to obtain the objective value for the current solution:
Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal));
The names and types of all model, variable, and constraint attributes can be found in the Attributes section of the Gurobi Reference Manual.
Cleaning up
The example concludes with Dispose calls:
model.Dispose(); env.Dispose();These reclaim the resources associated with the model and environment. Garbage collection would reclaim these eventually, but if your program doesn't exit immediately after performing the optimization, it is best to reclaim them explicitly.
Note that all models associated with an environment must be disposed before the environment itself is disposed.
Error handling
Errors in the Gurobi .NET interface are handled through the .NET exception mechanism. In the example, all Gurobi statements are enclosed inside a try block, and any associated errors would be caught by the catch block.
Building and running the example
You can use the CS_examples_2008.sln or CS_examples_2010.sln solution files in <installdir>/examples/build to build and run the example with Visual Studio 2008 or 2010, respectively. Clicking on the 'mip1_cs' project, and then selecting Run from the Build menu will compile and run the example.
The C# and Visual Basic example directories (<installdir>/examples/c# and <installdir>/examples/vb) contain a number of examples. We encourage you to browse and modify them in order to become more familiar with the Gurobi .NET interface. We also encourage you to read the Gurobi Example Tour for more information.