This section contains a simple example which demonstrates some of the key functionality of Gurobify. We demonstrate the following:
Creation of a Gurobi model, including specifying variable types and names
Adding an objective function to the model and choosing its sense (maximise or minimise)
Adding constraints to a model individually
Adding multiple constraints to a model at one time
Deleting constraints from a model
Optimising a model
Querying the optimisation status of a model
Displaying the solution to a feasible model
Setting a parameter (in this case the time limit)
Querying the current value of a parameter (again, the time limit)
Writing a model to a file
Reading a model from a file
The purpose of this example is to illustrate the use of Gurobify in a quick, simple manner. The example itself is trivial, but the same procedure applies for much more complex models. It only utilises some of the core commands available in Gurobify, though more commands are listed in detail in Chapter 3 "Using Gurobify", and further examples are given in Chapter 4 "Examples".
The first step in using gurobify is to create a model. To do this, we first need to define the types of variables that are to be used in the model, and we may optionally give them names. In this case we create a model with three binary variables, called \(x\), \(y\) and \(z\). We then define the objective function as \(x + 2 y + z\), which we set to be maximised.
gap> model := GurobiNewModel(["BINARY", "BINARY", "BINARY"], ["x", "y", "z"]); Gurobi model gap> GurobiSetObjectiveFunction( model, [1.,2.,1.] ); true gap> GurobiMaximiseModel(model); true
Having defined our model, we can now add constraints. To do this, a list of the coefficients for each of the variables is given, along with the sense of the equation (that is, \(=\), \(<\) or \(>\)), the value on the right hand side of the constraint, and optionally a name for the constraints. Gurobi does interprets \(<\) as \(\le\) and \(>\) as \(\ge\) and does not distinguish between them. Note, however, that gurobify only accepts the form \(<\) or \(>\). We add the constraints \(2x + 2y + 2z \le 6\) and \(x + 2y + 3z \ge 5\) to our model. We do not assign them names.
gap> GurobiAddConstraint(model, [2, 2, 2], "<", 6 ); true gap> GurobiAddConstraint(model, [1, 2, 3], ">", 5 ); true
Alternatively, the previous constraints could have been added simultaneously, by containing multiple constraints as entries of a list.
gap> constraints := [[2, 2, 2], [1, 2, 3]]; [ [ 2, 2, 2 ], [ 1, 2, 3 ] ] gap> sense := ["<", ">"]; [ "<", ">" ] gap> rhs := [6,5]; [ 6, 5 ] gap> GurobiAddMultipleConstraints( model, constraints, sense, rhs ); true
We can now optimise the model. This will return a Gurobi opimistion status code. More information on the status codes can be found in the Appendix. A status code of \(2\) lets us know that the model was successfully optimised. We may then query the model's solution.
gap> GurobiOptimiseModel(model); 2 gap> GurobiSolution(model); [ 1., 1., 1. ]
In addition to returning the optimisation status upon finishing optimisation, we can query the optimisation status of a model directly at any point in time. It will give the status of the model at the point when it was last optimised.
gap> GurobiOptimisationStatus(model); 2
We can reset any information found on a model to its pre-optimisation state. If we then check its status it will tell us that the model has been loaded, but no optimisation information is available.
gap> GurobiReset(model); true gap> GurobiOptimisationStatus(model); 1
We can change the objective sense of the model so that Gurobi will look for a solution which minimises the objective function instead. We then optimise the model and, if the optimisation is succesful, retun the solution.
gap> GurobiMinimiseModel(model); true gap> GurobiOptimiseModel(model); 2 gap> GurobiSolution(model); [ 0., 1., 1. ]
We can write the model to a file so that we may use it later. We need to specify the file name, and the extension of the file name will determine the type of file written. In this case we write the model to an lp file which we call "test.lp".
gap> GurobiWriteToFile(model, "test.lp"); true
It is also possible to read a model directly from a file. In this case it is not necessary to build the model from the ground up. We will read in the model from the "test.lp" file that we created in the previous step.
gap> re_model := GurobiReadModel("test.lp"); Gurobi model
We now add another constraint, \(x + y + z > 3\), to the model. Since we may want to remove this constraint later we give it the name "Other Constraint". We optimise the model and since it returns a feasible optimisation status we return the solution.
gap> GurobiAddConstraint(re_model, [1, 1, 1], ">", 3, "Other Constraint"); true gap> GurobiOptimiseModel(re_model); 2 gap> GurobiSolution(re_model); [ 1., 1., 1. ]
We add another constraint, \(y + z < 1\), to the model and also call it "Other Constraint". We optimise the model, and get a status code of \(3\), indicating that the model has no feasible solutions.
gap> GurobiAddConstraint(re_model, [0, 1, 1], "<", 1, "Other Constraint"); true gap> GurobiOptimiseModel(re_model); 3
Since we named the two additional constraints, we can delete them. This makes our model feasible again, and we get the same solution as before.
gap> GurobiDeleteConstraintsWithName(re_model, "Other Constraint"); true gap> GurobiOptimiseModel(re_model); 2 gap> GurobiSolution(re_model); [ 0., 1., 1. ]
There are many parameters and attributes of Gurobi models which can be set and queried. For example, we may set the time limit to something very small so that Gurobi terminates before finishing optimising. This returns a status code of \(9\). We may then change the time limit again to allow Gurobi more time to finish optimising and thus obtain a feasible solution again. Chapter 3 documents other parameters and attributes that Gurobify is able to modify.
gap> GurobiSetTimeLimit(re_model, 0.000001); true gap> GurobiOptimiseModel(re_model); 9 gap> GurobiSetTimeLimit(re_model, 10); true gap> GurobiOptimiseModel(re_model); 2
We can query the model to find out what the current time limit value is set to.
gap> GurobiTimeLimit(re_model); 10.
generated by GAPDoc2HTML