Quickstart Windows Gurobi
Quickstart Windows Gurobi
Quickstart Windows Gurobi
Contents
1 Introduction
28
6 Interactive Shell
34
7 Attributes
47
8 C Interface
48
9 C++ Interface
56
10 Java Interface
62
68
12 Python Interface
74
92
14 R Interface
96
15 Recommended Reading
100
101
106
18 File Overview
108
Introduction
Welcome to the GurobiTM Optimizer Quick Start Guide for Windows users! This document provides
a basic introduction to the Gurobi Optimizer, including:
Information on Obtaining a Gurobi License.
A Software Installation Guide, which includes information on Retrieving and Setting Up your
License.
An example of how to create a simple optimization model and solve it with the Gurobi
R interface,
Java
R .NET interface,
Microsoft
Python interface,
R interface, or
MATLAB
R interface.
At the end of the Quick Start Guide, you'll nd a File Overview that lists the les included in the
Gurobi distribution.
4
Additional resources
Once you are done with the Quick Start Guide, the next step is to explore these additional resources:
If you are familiar with mathematical modeling and are ready to use Gurobi from one of our
If you would like to see examples of ways to use Gurobi, consult the Gurobi Example Tour.
If you would like to learn more about mathematical programming or modeling, we've collected
Getting help
Have a question that isn't answered in this guide? Post it to the Gurobi Google Group. Clients
with current maintenance contracts can send questions to [email protected].
Ready to get started? Your rst step is to Obtain a License.
one.
If you are an academic user, you can obtain a free academic license on our website.
If you have purchased a license from us, that license should be visible through the Current
tab of your Licenses page on our website (you will need to login to your account to see this
page).
If you are planning to use Gurobi as a client of a machine that is already set up as a Gurobi
token server or compute server, you will need to create a token server client license or create
a compute server client license.
Once you have a license, your next step is to install the software.
Command-Line Installation
You can also install Gurobi using the command-line interface to the Windows Installer. Open a
cmd prompt, use cd to go to the directory that contains the Gurobi installer image, and enter the
following command:
msiexec /i Gurobi-7.0.0-win64.msi /norestart
If you are unfamiliar with running command-line commands on a Windows system, you can learn
more here.
sets Windows environment variables that will point to one particular version. This can cause
confusion, particularly when a program asks Windows to load the Gurobi DLL. If you understand
the implications, feel free to install both.
Helpful tools
To work with compressed les within the Gurobi Optimizer, we recommend that you install gzip
(www.gzip.org) and/or 7zip (www.7-zip.org).
You are now ready to proceed to the section on Retrieving Your Gurobi License.
If you would like an overview of the les included in the Gurobi distribution, you can also view the
File Overview section.
Your next step is to install this Gurobi license on your machine. You do this by obtaining a license
key le. Please consult the License Type eld on the License Detail page to identify your license
type, and click on the appropriate link below to proceed:
Free Academic
Named User
Single-Machine
Single-Use
Floating
Compute Server
Instant Cloud
If your license includes the Distributed Add-On and you plan to use any of the Gurobi distributed
algorithms, you'll also need to set up Gurobi Remote Services on your distributed worker machines.
10
You can store the license key le anywhere, but we strongly recommend that you accept the default
location by hitting Enter . Setting up a non-default location is error-prone and a frequent source of
trouble.
If you receive an error message at this stage, it typically means that we were unable to validate
your academic domain. Please consult the Academic Validation section for more information.
Next steps
If your license includes the Distributed Add-On and you plan to use any of the Gurobi distributed
algorithms, you'll also need to set up Gurobi Remote Services on your distributed worker machines.
Once you have followed the steps above and have obtained a license key le, your next step is to
test your license.
it means your domain isn't on our academic domain list. Please make sure you are connected to
your university network. If you are validating a home machine and the university provides a VPN,
please connect to it before retrieving your license. If the reported host name is a valid university
address, please send the specic error message you received to [email protected] and we'll add
your domain.
If you are having trouble validating your license through a VPN, note that some VPNs are congured
to use split tunneling , where trac to public internet sites is routed through your ISP. You should
ask your network administrator whether the VPN can be congured to route trac to gurobi.com
through the private network.
Some machines connect to the internet through a proxy server. Unfortunately, such congurations
are incompatible with our academic validation process.
it means your machine has no reverse DNS information. This usually happens when you are connecting to the Internet through a DHCP server that does NAT (network address translation) or
PAT (port address translation), but does not provide DNS information for its clients. The simplest
way to resolve this issue is to ask your network administrator to add a DNS entry (a PTR record )
for the DHCP device itself.
12
There is unfortunately no way for us to validate your academic license without reverse DNS information. You can visit this site to check DNS information for your IP address and to obtain more
information about reverse DNS.
13
You can store the license key le anywhere, but we strongly recommend that you accept the default
location by hitting Enter . Setting up a non-default location is error-prone and a frequent source of
trouble.
Next steps
If your license includes the Distributed Add-On and you plan to use any of the Gurobi distributed
algorithms, you'll also need to set up Gurobi Remote Services on your distributed worker machines.
Once you have followed the steps above and have obtained a license key le, your next step is to
test your license.
ask for the name of the directory in which to store your license key le (gurobi.lic). You should
see a prompt that looks like this:
You can store the license key le anywhere, but we strongly recommend that you accept the default
location by hitting Enter . Setting up a non-default location is error-prone and a frequent source of
trouble.
You should of course choose your own password. Clients will need to place this same line in their
client license les.
When adding this line to your gurobi.lic le, please be careful not to modify anything else in the
le.
runs under username LocalService , so it doesn't have access to your home directory).
If you would like to use a non-default license key le location, you can do so by setting system
environment variable GRB_LICENSE_FILE to point to the license key le. Important note: the environment variable should point to the license key le itself, not to the directory that contains the
le.
On Windows systems, environment variables are created and modied through the Control Panel.
16
Searching for Environment Variables from the Control Panel search box will lead you to the appropriate screen. You will need to add a new System variable named GRB_LICENSE_FILE, and set
it to the location of your license le (e.g., d:\gurobi\gurobi.lic). Important note: your new
environment variable must be a System variable, not a User variable.
Once you have followed the steps above and have obtained a license key le, your next step is to
start the token server.
On a Windows system, you can start the token service by selecting the Gurobi Token Server menu
item from the Gurobi folder of the Start menu. You should only do so after you have installed the
Gurobi license key le.
17
Firewalls
The next step after starting the Gurobi token server depends on your anti-virus software and
rewall settings. Most anti-virus software will immediately ask you to conrm that you are allowing
program grb_ts.exe to receive network trac. Once you conrm this, the token server will start
serving tokens. If you don't receive such a prompt, you will need to add grb_ts.exe to the rewall
exceptions list. To do this, select Allow a program through Windows rewall under the Security
area of the Control Panel (labeled Allow an app through Windows rewall in Windows 8).
Some machines have more restrictive rewalls that may require additional action. The Gurobi token
server uses port 41954 by default. If you are unable to reach the token server after taking the steps
described, you should ask your network administrator for more information on how to open the
required port.
to your gurobi.lic le to start the license service in verbose mode. Verbose mode produces a log
message (in the Windows Event Log) each time a token is checked in or out.
Next steps
Clients of the token server also need simple license les. Your next step is to set up a client license.
Once your token server is running and you've set up a client license, you can move on to testing the
license.
Once you've set up a client license, you can test the state of the token server at any time, as well
as get a list of the clients that are currently using tokens, by typing gurobi_cl --tokens.
3. Upgrade your license le (or modify GRB_LICENSE_FILE to point to the new license le).
4. Start the new token server.
or:
TOKENSERVER=192.168.1.100
You should of course substitute the name or IP address of your token server in the example above.
If your token server was congured to use a non-default port, you'll also need a line that provides
the port number:
PORT=46325
The client license le may also include two optional lines. A TIMEOUT line allows you to specify the
timeout (in seconds) in case the token server is unavailable. The default value is 30 seconds. A
PASSWORD line allows you to connect to a password-protected token server (you'll need to get the
password from the owner of the token server).
A more complex client token le might look like this:
TOKENSERVER=192.168.1.100
TIMEOUT=10
PASSWORD=abcd1234
We strongly recommend that you place your client gurobi.lic le in a default location for your
platform (either your home directory or c:\gurobi). Setting up a non-default location is errorprone and a frequent source of trouble. (If you still want to use a non-default location, please refer
to the instructions that appeared earlier in this section).
If your client and the token server are both running on the same machine, they can share a single
gurobi.lic le. You just need to add the following line to the gurobi.lic le you obtained from
our website:
TOKENSERVER=localhost
The token server will ignore this line, and the client will ignore everything but this line. Your
other option when both client and server are running on the same machine is to create a separate
19
gurobi.lic le for the client, and to set the GRB_LICENSE_FILE environment variable to point to
this le (following the earlier instructions for using a non-default license location).
Once your client license is in place, you can test the license. If you are unable to connect to the
server, you'll need to make sure the server is installed and running. Please consult the instructions
for starting a token server for more information.
or like this:
COMPUTESERVER=192.168.1.100,192.168.1.101,192,168.1.102
This line provides a comma-separated list of Gurobi Compute Servers. If your Compute Servers use
a password, you should also include a line that gives the password:
PASSWORD=cspwd
Please consult the Gurobi Compute Server section of the Gurobi Reference Manual for more information.
Note that if your client and server are both running on the same machine, they can share the same
gurobi.lic le. You just need to add a COMPUTESERVER=localhost line to the gurobi.lic le
22
you obtained from our website. The Compute Server will ignore this line, and the client will ignore
everything but this line. Another option in this situation is to create a separate gurobi.lic le for
the client, and to set the GRB_LICENSE_FILE environment variable to point to this le (following
the earlier instructions for using a non-default license location).
Once your client license is in place, you can test the license. If you are unable to connect to the
server, you'll need to make sure the server is installed and running. Please consult the instructions
for setting up a Compute Server for more information.
On Windows systems, Gurobi Remote Services is a Windows Service that allows a server to perform
Gurobi computations on behalf of other client machines. The set of services the server provides
depends on your license. If you are setting up a machine as a distributed worker, no license is
required. In this case, the only service provided by the server is to act as a worker in a distributed
algorithm. If you have a Compute Server license, then servers running Gurobi Remote Services
can provide a variety of services, including ooading computation from a set of clients, balancing
computational load among the servers, and providing failover capabilities, in addition to acting as
a distributed worker.
On a Windows system, you will need to start Gurobi Remote Services by selecting the Gurobi
Remote Services menu item from the Gurobi folder of the Start menu. You should only do so after
you have installed the Gurobi license key le.
Firewalls
The next step after starting Gurobi Remote Services depends on your anti-virus software and rewall settings. Most anti-virus software will ask you to conrm that you are allowing programs
grb_rs.exe and grb_rsw.exe to receive network trac. Once you conrm this, Gurobi Remote
Servides will start serving requests. If you don't receive such a prompt, you will need to add
grb_rs.exe and grb_rsw.exe to the rewall exceptions list. Select Allow a program through Windows rewall under the Security area of the Control Panel (labeled Allow an app through Windows
rewall in Windows 8).
Some machines have more restrictive rewalls that may require additional action. Gurobi Remote
Services uses ports 61000-65000 by default. If you are unable to reach the Compute Server after
taking the steps described, ask your network administrator for more information on how to open
the required ports.
23
to your gurobi.lic le to start Gurobi Remote Services in verbose mode. Verbose mode produces
a log message (in the Windows Event Log) each time a client starts a job.
All output from Gurobi Remote Services goes to the Windows Event Log. You can access this
through the Event Viewer. Type Event in the search box (under the Start menu in Windows Vista
and Windows 7, toward the bottom left of the desktop in Windows 10) to launch the viewer.
Next steps
Once you've set up Gurobi Remote Services, you should test the state of the server. Type this
command on your server:
gurobi_cl --server=localhost --status
These allow your client program to launch and use cloud instances from your account. You should
keep this information private, since anyone with access to it can also use your cloud instances.
Please consult the Gurobi Instant Cloud section of the Gurobi Reference Manual for more information.
25
If you are running as a client of a Gurobi Compute Server, the message above will be preceded by
a message like this:
Capacity available on 'myserver' - connecting...
Established 256-bit AES encrypted connection
Congratulations, your license is functioning correctly! You are now ready to use the Gurobi Optimizer. The next section will show you how to solve a simple optimization model.
Possible errors
If the Gurobi shell didn't produce the desired output, there's a problem with your license. We'll
list a few common errors here.
ERROR: No Gurobi license found (user smith, host mymachine, hostid 9d3128ce)
indicates that your gurobi.lic isn't valid for this machine. You should make sure that you are
using the right gurobi.lic le.
If you are running as a client of a Gurobi token server and receive this message:
ERROR: Failed to connect to token server 'myserver' (port 41954)
the token server isn't currently running. If you receive this message:
ERROR: No TOKENSERVER specified for TOKEN license
your license le is missing the TOKENSERVER= line that provides the name of your token server.
Please consult the section on setting up a token server.
If you are running as a client of a Gurobi Compute Server and receive this message:
26
the Compute Server isn't currently running. Please consult the section on setting up a Compute
Server.
27
Suppose the Mint wants to use the available materials to produce coins with the maximum total
dollar value. Which coins should they produce?
28
Second, we'll dene a linear objective function. This is the function we'd like to minimize (or
maximize).
The Gurobi Optimizer will consider all assignments of values to decision variables that satisfy the
specied linear constraints, and return one that optimizes the stated objective function.
The variables in this problem are quite straightforward. The solver will need to decide how many
of each coin to produce. It is convenient to give the decision variables meaningful names. In this
case, we'll call the variables Pennies , Nickels , Dimes , Quarters , and Dollars . We'll also introduce
variables that capture the quantities of the various minerals actually used by the solution. We'll
call them Cu , Ni , Zi , and Mn .
Recall that the objective of our optimization problem is to maximize the total dollar value of the
coins produced. Each penny produced is worth 0.01 dollars, each nickel is worth 0.05 dollars, etc.
This gives the following linear objective:
maximize: 0.01 Pennies + 0.05 Nickels + 0.1 Dimes + 0.25 Quarters + 1 Dollars
The constraints of this model come from the fact that producing a coin consumes certain quantities
of the available minerals, and the supplies of those minerals are limited. We'll capture these relationships in two parts. First, we'll create an equation for each mineral that captures the amount of
that mineral that is consumed. For copper, that equation would be:
Cu = 0.06 Pennies + 3.8 Nickels + 2.1 Dimes + 5.2 Quarters + 7.2 Dollars
The coecients for this equation come from the earlier coin specication table: one penny uses
0.06g of copper, one nickel uses 3.8g, etc.
The model must also capture the available quantities of each mineral. If we have 1000 grams of
copper available, then the constraint would be:
Cu <= 1000
For our example, we'll assume we have 1000 grams of copper and 50 grams of the other minerals.
There is actually one other set of constraints that must be captured in order for our model to
accurately reect the physical realities of our problem. While a dime is worth 10 cents, half of a
dime isn't worth 5 cents. The variables that capture the number of each coin produced must take
integer values.
MATLAB, R, etc.). However, to keep our example as simple as possible, we're going to read the
model from an LP format le. The LP format was designed to be human readable, and as such it
is well suited for our needs.
The LP format is mostly self-explanatory. Here is our model:
Maximize
.01 Pennies + .05 Nickels + .1 Dimes + .25 Quarters + 1 Dollars
Subject To
Copper: .06 Pennies + 3.8 Nickels + 2.1 Dimes + 5.2 Quarters + 7.2 Dollars Cu = 0
Nickel: 1.2 Nickels + .2 Dimes + .5 Quarters + .2 Dollars Ni = 0
Zinc: 2.4 Pennies + .5 Dollars - Zi = 0
Manganese: .3 Dollars - Mn = 0
Bounds
Cu <= 1000
Ni <= 50
Zi <= 50
Mn <= 50
Integers
Pennies Nickels Dimes Quarters Dollars
End
You'll nd this model in le coins.lp in the <installdir>/examples/data directory of your Gurobi
distribution. Specically, assuming you've installed Gurobi 7.0.1in the recommended location, you'll
nd the le in c:\gurobi701\win64\examples\data\coins.lp.
To modify this le, open it in a text editor (like Wordpad).
must include a space or newline between + and .1, and another between .1 and Dimes.
30
3. Arranging variables
Variables must always appear on the left-hand side of a constraint. The right-hand side is always a
constant. Thus, our constraint:
Cu = .06 Pennies + 3.8 Nickels + 2.1 Dimes + 5.2 Quarters + 7.2 Dollars
...becomes...
.06 Pennies + 3.8 Nickels + 2.1 Dimes + 5.2 Quarters + 7.2 Dollars - Cu = 0
31
0
0
Current Node
|
Objective Bounds
Obj Depth IntInf | Incumbent
BestBd
0 113.46154
0
1
0.00000 113.46154
113.4500000 113.46154
|
Work
Gap | It/Node Time
0.01%
0s
0s
Details on the format of the Gurobi log le can be found in the Gurobi Reference Manual. For
now, you can simply note that the optimal objective value is 113.45. Recall that the objective is
denoted in dollars. We can therefore conclude that by a proper choice of production plan, the Mint
can produce $113.45 worth of coins using the available minerals. Moreover, because this value is
optimal, we know that it is not possible to produce coins with value greater than $113.45!
It would clearly be useful to know the exact number of each coin produced by this optimal plan.
The gurobi_cl command allows you to set Gurobi parameters through command-line arguments.
One particularly useful parameter for the purposes of this example is ResultFile, which instructs
the Gurobi Optimizer to write a le once optimization is complete. The type of the le is encoded
in the sux. To request a .sol le:
> gurobi_cl ResultFile=coins.sol coins.lp
The command will produce a le that contains solution values for the variables in the model:
# Objective value = 113.45
Pennies 0
Nickels 0
Dimes 2
32
Quarters 53
Dollars 100
Cu 999.8
Ni 46.9
Zi 50
Mn 30
In the optimal solution, we'll produce 100 dollar coins, 53 quarters, and 2 dimes.
If we wanted to explore the parameters of the model (for example, to consider how the optimal
solution changes with dierent quantities of available minerals), we could use a text editor to modify
the input le. However, it is typically better to do such tests within a more powerful system. We'll
now describe the Gurobi Interactive Shell, which provides an environment for creating, modifying,
and experimenting with optimization models.
33
Interactive Shell
The Gurobi interactive shell allows you to perform hands-on interaction and experimentation with
optimization models. You can read models from les, perform complete or partial optimization runs
on them, change parameters, modify the models, reoptimize, and so on. The Gurobi shell is actually
a set of extensions to the Python shell. Python is a rich and exible programming language, and
any capabilities that are available from Python are also available from the Gurobi shell. We'll touch
on these capabilities here, but we encourage you to explore the help system and experiment with
the interface in order to gain a better understanding of what is possible.
One big advantage of working within Python is that the Python language is popular and well
supported. One aspect of this support is the breadth of powerful Python Integrated Development
Environments (IDEs) that are available, most of which can be downloaded for free from the internet.
This document includes instructions for setting up Gurobi for use within the Anaconda distribution.
Anaconda includes a powerful IDE (Spyder), as well as a notebook-style interface (Jupyter).
Before diving into the details of the Gurobi interactive shell, we should remind you that Gurobi
also provides a lightweight command line interface. If you just need to do a quick test on a model
stored in a le, you will probably nd that that interface is better suited to simple tasks than the
interactive shell.
Important note for AIX users: due to limited Python support on AIX, our AIX port does not
include the Interactive Shell or the Python interface. You can use the command line, or the C,
C++, or Java interfaces.
We will now work through a few simple examples of how the Gurobi shell might be used, in order to
give you a quick introduction to its capabilities. More thorough documentation on this and other
interfaces is available in the Gurobi Reference Manual.
From Linux or Mac OS, you can simply type gurobi.sh from the command prompt. If you've
installed a Python IDE, the shell will also be available from that environment.
34
Once the optimizer has started, you are ready to load and optimize a model. We'll consider model
coins.lp from <installdir>/examples/data...
> gurobi.bat (or gurobi.sh for Linux or Mac OS)
Gurobi Interactive Shell, Version 7.0.0
Copyright (c) 2016, Gurobi Optimization, Inc.
Type "help()" for help
gurobi> m = read('c:/gurobi700/win64/examples/data/coins.lp')
Read LP format model from file c:/gurobi700/win64/examples/data/coins.lp
Reading time = 0.00 seconds
(null): 4 rows, 9 columns, 16 nonzeros
gurobi> m.optimize()
Optimize a model with 4 rows, 9 columns and 16 nonzeros
Variable types: 4 continuous, 5 integer (0 binary)
Coefficient statistics:
Matrix range
[6e-02, 7e+00]
Objective range [1e-02, 1e+00]
Bounds range
[5e+01, 1e+03]
RHS range
[0e+00, 0e+00]
Found heuristic solution: objective 0
Presolve removed 1 rows and 5 columns
Presolve time: 0.00s
Presolved: 3 rows, 4 columns, 9 nonzeros
Variable types: 0 continuous, 4 integer (0 binary)
Root relaxation: objective 1.134615e+02, 3 iterations, 0.00 seconds
Nodes
|
Expl Unexpl |
H
0
0
Current Node
|
Objective Bounds
Obj Depth IntInf | Incumbent
BestBd
0 113.46154
0
1
0.00000 113.46154
113.4500000 113.46154
|
Work
Gap | It/Node Time
0.01%
0s
0s
The read() command reads a model from a le and returns a Model object. In the example, that
35
object is placed into variable m. There is no need to declare variables in the Python language; you
simply assign a value to a variable.
Note that read() accepts wildcard characters, so you could also have said:
gurobi> m = read('c:/gurobi700/win64/*/*/coin*')
Note also that Gurobi commands that read or write les will also function correctly with compressed
les. If gzip, bzip2, or 7zip are installed on your machine and available in your default path, then
you simply need to add the appropriate sux (.gz, .bz2, .zip, or .7z) to the le name to read or
write compressed versions.
The next statement in the example, m.optimize() , invokes the optimize method on the Model object
(you can obtain a list of all methods on Model objects by typing help(Model) or help(m)). The
Gurobi optimization engine nds an optimal solution with objective 113.45.
This routine prints all non-zero values of the specied attribute X. Attributes play a major role in
the Gurobi optimizer. We'll discuss them in more detail shortly.
You can also inspect the results of the optimization at a ner grain by retrieving a list of all the
variables in the model using the getVars() method on the Model object (m.getVars() in our example):
gurobi> v = m.getVars()
gurobi> print(len(v))
9
The rst command assigns the list of all Var objects in model m to variable v. The Python len()
command gives the length of the array (our example model coins has 9 variables). You can then
query various attributes of the individual variables in the list. For example, to obtain the variable
name and solution value for the rst variable in list v, you would issue the following command:
36
You can type help(Var) or help(v[0]) to get a list of all methods on a Var object. You can type
help(GRB.Attr) to get a list of all attributes.
The Gurobi optimizer keeps track of the state of the model, so it knows that the currently loaded
solution is not necessarily optimal for the modied model. When you invoke the optimize() method
again, it performs a new optimization on the modied model...
gurobi> m.optimize()
Optimize a model with 4 rows, 9 columns and 16 nonzeros
Variable types: 4 continuous, 5 integer (0 binary)
Coefficient statistics:
Matrix range
[6e-02, 7e+00]
Objective range [1e-02, 1e+00]
Bounds range
[1e+01, 1e+03]
RHS range
[0e+00, 0e+00]
Presolve removed 2 rows and 5 columns
Presolve time: 0.00s
Presolved: 2 rows, 4 columns, 5 nonzeros
MIP start did not produce a new incumbent solution
Variable types: 0 continuous, 4 integer (0 binary)
Found heuristic solution: objective 25.9500000
Root relaxation: objective 7.190000e+01, 2 iterations, 0.00 seconds
Nodes
|
Expl Unexpl |
H
H
0
0
0
0
0
0
Current Node
|
Objective Bounds
Obj Depth IntInf | Incumbent
BestBd
71.90000
25.95000
71.8500000
71.9000000
|
Work
Gap | It/Node Time
71.90000 177%
71.90000 0.07%
71.90000 0.00%
0s
0s
0s
37
The result shows that, if you force the solution to include at least 10 pennies, the maximum possible
objective value for the model decreases from 113.45 to 71.9. A simple check conrms that the new
lower bound is respected:
gurobi> print(v[0].x)
10.0
38
0
0
0
0
2
732
781
Current Node
|
Objective Bounds
Obj Depth IntInf | Incumbent
BestBd
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
0
0
0
0
0
72 3.6917e+09
72 3.6917e+09
72 3.6917e+09
72 3.6917e+09
72 3.6917e+09
2.800024e+09
2.666693e+09
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
|
Work
Gap | It/Node Time
78.3%
78.3%
78.3%
78.3%
78.3%
71.4%
70.0%
5.2
5.3
0s
0s
0s
0s
0s
0s
0s
H 1091 984
H 1092 986
H 1092 984
H 1095 988
* 1845 1543
94
* 2131 1627
126
H 2244 1580
H 2248 1341
H 3345 1816
H 3346 1744
H15979 10383
H19540 13051
*21124 13489
101
*23011 14690
100
*25630 15679
143
*28365 15421
113
H29910 16333
*30582 16765
124
*33238 16251
92
*37319 18258
85
H40623 19584
81781 42951 1.1000e+09 49
199990 100088 1.6000e+09 82
*242810 116891
97
*243703 116786
95
5.1
5.1
5.1
5.1
4.9
4.8
4.8
5.0
4.1
4.1
2.5
2.4
2.4
2.3
2.3
2.3
2.3
2.3
2.3
2.2
2.3
2.2
2.3
2.3
2.3
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
1s
1s
1s
1s
1s
1s
1s
1s
1s
1s
2s
5s
10s
11s
11s
It quickly becomes apparent that this model is quite a bit more dicult than the earlier coins model.
The optimal solution is actually 1,200,000,000, but nding that solution takes a while. After
letting the model run for 10 seconds, we interrupt the run (by hitting CTRL-C, which produces the
Interrupt request received message) and consider our options. Typing m.optimize() would resume
the run from the point at which it was interrupted.
39
Changing parameters
Rather than continuing optimization on a dicult model like glass4, it is sometimes useful to try
dierent parameter settings. When the lower bound moves slowly, as it does on this model, one
potentially useful parameter is MIPFocus, which adjusts the high-level MIP solution strategy. Let
us now set this parameter to value 1, which changes the focus of the MIP search to nding good
feasible solutions. There are two ways to change the parameter value. You can either use method
m.setParam() :
gurobi> m.setParam('MIPFocus', 1)
Changed value of parameter MIPFocus to 1
Prev: 0 Min: 0
Max: 3 Default: 0
Once the parameter has been changed, we call m.reset() to reset the optimization on our model and
then m.optimize() to start a new optimization run:
gurobi> m.reset()
gurobi> m.optimize()
Optimize a model with 396 Rows, 322 Columns and 1815 NonZeros
Presolve removed 4 rows and 5 columns
Presolve time: 0.00s
Presolved: 392 Rows, 317 Columns, 1815 Nonzeros
Found heuristic solution: objective 3.691696e+09
Root relaxation: objective 8.000024e+08, 72 iterations, 0.00 seconds
Nodes
|
Expl Unexpl |
H
H
H
H
40
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
Current Node
|
Objective Bounds
Obj Depth IntInf | Incumbent
BestBd
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
0
0
0
0
8.0000e+08
8.0000e+08
0
0
72 3.6917e+09
72 3.6917e+09
72 3.6917e+09
73 3.6917e+09
3.075022e+09
3.020023e+09
76 3.0200e+09
75 3.0200e+09
2.550024e+09
2.175020e+09
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
|
Work
Gap | It/Node Time
78.3%
78.3%
78.3%
78.3%
74.0%
73.5%
73.5%
73.5%
68.6%
63.2%
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
0
H 95
H 96
H 101
H 110
H 352
H 406
H 1074
H 1078
H 1107
H 1696
H 1845
H 1863
H 2353
H 2517
H 2598
H 2733
14259
24846
H25035
H25066
H25072
H26218
H26326
H26577
2 8.0000e+08
98
98
103
103
325
375
888
889
878
1125
1146
1087
1273
1299
1248
1252
7927 1.5000e+09
14278 1.1000e+09
13985
14020
13532
14083
14118
13650
85
49
75 2.1750e+09
2.150020e+09
2.120018e+09
2.116687e+09
2.100017e+09
2.000018e+09
1.991686e+09
1.981836e+09
1.966686e+09
1.900018e+09
1.800017e+09
1.800017e+09
1.733350e+09
1.733350e+09
1.700016e+09
1.666682e+09
1.633349e+09
28 1.6333e+09
55 1.6333e+09
1.600016e+09
1.600016e+09
1.583350e+09
1.575016e+09
1.566682e+09
1.525016e+09
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0000e+08
8.0001e+08
8.0001e+08
8.0001e+08
8.0001e+08
8.0001e+08
8.0001e+08
8.0001e+08
63.2%
62.8%
62.3%
62.2%
61.9%
60.0%
59.8%
59.6%
59.3%
57.9%
55.6%
55.6%
53.8%
53.8%
52.9%
52.0%
51.0%
51.0%
51.0%
50.0%
50.0%
49.5%
49.2%
48.9%
47.5%
4.6
4.6
4.5
4.3
4.2
4.0
3.5
3.5
3.5
3.4
4.2
4.3
4.3
4.3
4.3
4.2
3.5
3.5
3.5
3.5
3.5
3.5
3.5
3.5
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
0s
1s
1s
1s
1s
1s
1s
5s
10s
10s
10s
10s
10s
10s
10s
Results are consistent with our expectations. We nd a better solution sooner by shifting the focus
towards nding feasible solutions (objective value 1.525e9 versus 1.6e9).
41
The setParam() method is designed to be quite exible and forgiving. It accepts wildcards as
arguments, and it ignores character case. Thus, the following commands are all equivalent:
gurobi>
gurobi>
gurobi>
gurobi>
m.setParam('NODELIMIT', 100)
m.setParam('NodeLimit', 100)
m.setParam('Node*', 100)
m.setParam('N???Limit, 100)
Note that Model.Params is a bit less forgiving than setParam() . In particular, wildcards are not
allowed with this approach. You don't have to worry about capitalization of parameter names in
either approach, though, so m.Params.Heuristics and m.Params.heuristics are equivalent.
The full set of available parameters can be browsed using the paramHelp() command. You can
obtain further information on a specic parameter (e.g., MIPGap) by typing paramHelp('MIPGap').
The tool tries a number of dierent parameter settings, and eventually outputs the best ones that
it nds. For example:
Tested 12 parameter sets in 47.77s
Baseline parameter set: runtime 2.39s
Improved parameter set 1 (runtime 1.72s):
RINS 0
In this case, it found that setting the RINS parameter to 0 for model misc07 reduced the runtime
from 2.39s to 1.72s.
42
Note that tuning is meant to give general suggestions for parameters that might help performance.
You should make sure that the results it gives on one model are helpful on the full range of models
you plan to solve. You may sometimes nd that performance problems can't be xed with parameter
changes alone, particulary if your model has severe numerical issues.
Tuning is also available as a standalone program. From a command prompt, you can type:
> grbtune c:\gurobi700\win64\examples\data\p0033
Please consult the Automated Tuning Tool section of the Gurobi Reference Manual for more information.
would read the new value of the Threads parameter from le gurobi.env and then optimize model
coins.lp using one thread. Note that if the same parameter is changed in both gurobi.env and in
your program (or through the Gurobi command-line), the value from gurobi.env will be overridden.
The distribution includes a sample gurobi.env le (in the bin directory). The sample includes
every parameter, with the default value for each, but with all settings commented out.
43
Note that parameters can be set for a particular model with the Model.setParam() method or the
Model.Params class, or they can be changed for all models in the Gurobi shell by using the global
setParam() method.
Help
The interactive shell includes an extensive help facility. To access it, simply type help() at the
prompt. As previously mentioned, help is available for all of the important objects in the interface. For example, as explained in the help facility, you can type help(Model), help(Var), or
help(Constr). You can also obtain detailed help on any of the available methods on these objects. For example, help(Model.setParam) gives help on setting model parameters. You can also
use a variable, or a method on a variable, to ask for help. For example, if variable m contains a
Model object, then help(m) is equivalent to help(Model), and help(m.setParam) is equivalent to
help(Model.setParam).
Interface customization
The Gurobi interactive shell lives within a full-featured scripting language. This allows you to
perform a wide range of customizations to suit your particular needs. Creating custom functions
requires some knowledge of the Python language, but you can achieve a lot by using a very limited
set of language features.
Let us consider a simple example. Imagine that you store your models in a certain directory on
your disk. Rather than having to type the full path whenever you read a model, you can create
your own custom read method:
gurobi> def myread(filename):
....... return read('/home/john/models/'+filename)
44
If you don't want to type this function in each time you start the Gurobi shell, you can store it in
a le. The le would look like the following:
from gurobipy import *
def myread(filename):
return read('/home/john/models/'+filename)
The from gurobipy import * line is required in order to allow you to use the read method from
the Gurobi shell in your custom function. The name of your customization le must end with a .py
sux. If the le is named custom.py, you would then type the following to import this function:
gurobi> from custom import *
One le can contain as many custom functions as you'd like (see custom.py in <installdir>/examples/python
for an example). If you wish to make site-wide customizations, you can also customize the gurobi.py
le that is included in <installdir>/lib.
Once you import this function (from custom import *), you can then say m.optimize(mycallback)
to obtain the desired termination behavior. Alternatively, you could dene your own custom optimize method that always invokes the callback:
def myopt(model):
model.optimize(mycallback)
You can pass arbitrary data into your callback through the model object. For example, if you set
m._mydata = 1 before calling optimize() , you can query m._mydata inside your callback function.
Note that the names of user data elds must begin with an underscore.
This callback example is included in <installdir>/examples/python/custom.py.
Type from custom import * to import the callback and the myopt() function.
You can type help(GRB.Callback) for more information on callbacks. You can also refer to the
Callback class documentation in the Gurobi Reference Manual.
Unless you are using your own private Python installation, you will need to run this command as
super-user. Once gurobipy is successfully installed, you can type import gurobipy or from gurobipy import *
from your Python shell and access all of the Gurobi classes and methods.
Note that Gurobi distributes an Anaconda package, so you don't need to perform these steps if you
are using Anaconda Python. Please refer to the instructions for setting up Gurobi for use within
the Anaconda distribution for details.
Note that for this installation to succeed, your Python environment must be compatible with the
Gurobi Python module. You should only install 32-bit Gurobi libraries into a 32-bit Python shell
(similarly for 64-bit versions). In addition, your Python version must be compatible. With this
release, gurobipy can be used with Python 2.7 or 3.5 on Windows and Linux, and with Python 2.7
on Mac OS.
46
Attributes
As mentioned in the previous section, most of the information associated with a Gurobi model is
stored in a set of attributes . Some attributes are associated with the variables of the model, some
with the constraints of the model, and some with the model itself. After you optimize a model, for
example, the solution is stored in the X variable attribute. Attributes that are computed by the
Gurobi optimizer (such as the solution attribute) cannot be modied directly by the user, while
those that represent input data (such as the LB attribute which stores variable lower bounds) can.
Each of the Gurobi language interfaces contains routines for querying or modifying attribute values.
To retrieve or modify the value of a particular attribute, you simply pass the name of the attribute
to the appropriate query or modication routine. In the C interface, for example, you'd make the
following call to query the current solution value on variable 1:
double x1;
error = GRBgetdblattrelement(model, GRB_DBL_ATTR_X, 1, &x1);
This routine returns a single element from an array-valued attribute containing double-precision
data. Routines are provided to query and modify scalar-valued and array-valued attributes of type
int, double, char, or char *.
In the object oriented interfaces, you query or modify attribute values through the appropriate
objects. For example, if variable v is a Gurobi variable object (a GRBVar), then the following calls
would be used to modify the lower bound on v:
C++:
Java:
C#:
Python:
v.set(GRB_DoubleAttr_LB, 0.0)
v.set(GRB.DoubleAttr.LB, 0.0)
v.Set(GRB.DoubleAttr.LB, 0.0) or v.LB = 0.0
v.lb = 0.0
The exact syntax for querying or modifying an attribute varies slightly from one language to another,
but the basic approach remains consistent: you call the appropriate query or modication method
using the name of the desired attribute as an argument.
The full list of Gurobi attributes can be found in the Attributes section of the Gurobi Reference
Manual.
47
C Interface
This section will work through a simple C example in order to illustrate the use of the Gurobi
C interface. The example builds a simple Mixed Integer Programming 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 are available for learning the language (for
example, The C Programming Language , by Kernighan and Ritchie).
Our example optimizes the following model:
maximize x +
y + 2z
subject to x + 2 y + 3 z 4
x +
y
1
x, y, z binary
Example mip1_c.c
This is the complete source code for our example (also available as
<installdir>/examples/c/mip1_c.c)...
#include <stdlib.h>
#include <stdio.h>
#include "gurobi_c.h"
int
main(int argc,
char *argv[])
{
GRBenv *env = NULL;
GRBmodel *model = NULL;
int
error = 0;
double
sol[3];
int
ind[3];
double
val[3];
double
obj[3];
char
vtype[3];
int
optimstatus;
double
objval;
int
zero = 0;
/* Create environment */
48
49
error = GRBoptimize(model);
if (error) goto QUIT;
/* Write model to 'mip1.lp' */
error = GRBwrite(model, "mip1.lp");
if (error) goto QUIT;
/* Capture solution information */
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimstatus);
if (error) goto QUIT;
error = GRBgetdblattr(model, GRB_DBL_ATTR_OBJVAL, &objval);
if (error) goto QUIT;
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, 3, sol);
if (error) goto QUIT;
printf("\nOptimization complete\n");
if (optimstatus == GRB_OPTIMAL) {
printf("Optimal objective: %.4e\n", objval);
printf(" x=%.0f, y=%.0f, z=%.0f\n", sol[0], sol[1], sol[2]);
} else if (optimstatus == GRB_INF_OR_UNBD) {
printf("Model is infeasible or unbounded\n");
} else {
printf("Optimization was stopped early\n");
}
QUIT:
/* Error reporting */
if (error) {
printf("ERROR: %s\n", GRBgeterrormsg(env));
exit(1);
}
/* Free model */
GRBfreemodel(model);
/* Free environment */
50
GRBfreeenv(env);
}
return 0;
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 including a few include les. Gurobi C applications should always start by
including gurobi_c.h, along with the standard C include les (stdlib.h and stdio.h).
Later requests to create optimization models will always require an environment, so environment
creation should always be the rst step when using the Gurobi optimizer. The second argument to
GRBloadenv() provides the name of the Gurobi log le. If the argument is an empty string or NULL,
no log le will be written.
Note that environment creation may fail, so you should check the return value of the call.
The rst argument to GRBnewmodel() is the previously created environment. The second is a
pointer to the location where the pointer to the new model should be stored. The third is the name
51
of the model. The fourth is the number of variables to initially add to the model. Since we're
creating an empty model, the number of initial variables is 0. The remaining arguments would
describe the initial variables (lower bounds, upper bounds, variable types, etc.), had they been
present.
The rst argument to GRBaddvars() is the model to which the variables are being added. The
second is the number of added variables (3 in our example).
Arguments three through six describe the constraint matrix coecients associated with the new
variables. The third argument gives the number of non-zero constraint matrix entries associated
with the new variables, and the next three arguments give details on these non-zeros. In our
example, we'll be adding these non-zeros when we add the constraints. Thus, the non-zero count
here is zero, and the following three arguments are all NULL.
The seventh argument to GRBaddvars() is the linear objective coecient for each new variable.
Since our example aims to maximize the objective, and by default Gurobi will minimize the objective,
we'll need to change the objective sense. This is done in the next statement. Note we could have
multiplied the objective coecients by -1 instead (since maximizing c0 x is equivalent to minimizing
c0 x).
The next two arguments specify the lower and upper bounds of the variables, respectively. The
NULL values indicate that these variables should take their default values (0.0 and 1.0 for binary
variables).
The tenth argument species the types of the variables. In this example, the variables are all binary
(GRB_BINARY).
The nal argument gives the names of the variables. In this case, we allow the variable names to
take their default values (x0, x1, and x2).
52
The rst argument of GRBaddconstr() is the model to which the constraint is being added. The
second is the total number of non-zero coecients associated with the new constraint. The next
two arguments describe the non-zeros in the new constraint. Constraint coecients are specied
using a list of index-value pairs, one for each non-zero value. In our example, the rst constraint to
be added is x + 2y + 3z 4. We have chosen to make x the rst variable in our constraint matrix, y
the second, and z the third (note that this choice is arbitrary). Given our variable ordering choice,
the index-value pairs that are required for our rst constraint are (0, 1.0), (1, 2.0), and (2, 3.0).
These pairs are placed in the ind and val arrays.
The fth argument to GRBaddconstr() provides the sense of the new constraint. Possible values
are GRB_LESS_EQUAL, GRB_GREATER_EQUAL, or GRB_EQUAL. The sixth argument gives the right-hand
side value. The nal argument gives the name of the constraint (we allow the constraint to take its
default name here by specifying NULL for the argument).
The second constraint is added in a similar fashion:
/* Second constraint: x + y >= 1 */
ind[0] = 0; ind[1] = 1;
val[0] = 1; val[1] = 1;
error = GRBaddconstr(model, 2, ind, val, GRB_GREATER_EQUAL, 1.0, NULL);
if (error) goto QUIT;
Note that routine GRBaddconstrs() would allow you to add both constraints in a single call. The
arguments for this routine are much more complex, though, without providing any signicant advantages, so we recommend that you add one constraint at a time.
53
This routine performs the optimization and populates several internal model attributes, including
the status of the optimization, the solution, etc. Once the function returns, we can query the values
of these attributes. In particular, we can query the status of the optimization process by retrieving
the value of the Status attribute...
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &optimstatus);
if (error) goto QUIT;
The optimization status has many possible values. An optimal solution to the model may have been
found, or the model have been determined to be infeasible or unbounded, or the solution process
may have been interrupted. A list of possible statuses can be found in the Gurobi Reference Manual.
For our example, we know that the model is feasible, and we haven't modied any parameters that
might cause the optimization to stop early (e.g., a time limit), so the status will be GRB_OPTIMAL.
Another important model attribute is the value of the objective function for the computed solution.
This is accessed through this call:
error = GRBgetdoubleattr(model, GRB_DBL_ATTR_OBJVAL, &objval);
if (error) goto QUIT;
Note that this call would return a non-zero error result if no solution was found for this model.
Once we know that the model was solved, we can extract the X attribute of the model, which
contains the value for each variable in the computed solution:
error = GRBgetdoublearrayattr(model, GRB_DBL_ATTR_X, 0, 3, x);
if (error) goto QUIT;
printf(" x=%.0f, y=%.0f, z=%.0f", x[0], x[1], x[2]);
This routine retrieves the values of an array-valued attribute. The third and fourth arguments
indicate the index of the rst array element to be retrieved, and the number of elements to retrieve,
respectively. In this example we retrieve entries 0 through 2 (i.e., all three of them)
Error reporting
We would like to point out one additional aspect of the example. Almost all of the Gurobi methods
return an error code. The code will typically be zero, indicating that no error was encountered, but
it is important to check the value of the code in case an error arises.
54
While you may want to print a specialized error code at each point where an error may occur,
the Gurobi interface provides a more exible facility for reporting errors. The GRBgeterrormsg()
routine returns a textual description of the most recent error associated with an environment:
if (error) {
printf("ERROR: %s\n", GRBgeterrormsg(env));
exit(1);
}
Once the error reporting is done, the only remaining task in our example is to release the resources
associated with our optimization task. In this case, we populated one model and created one
environment. We call GRBfreemodel(model) to free the model, and GRBfreeenv(env) to free the
environment (in that order).
55
C++ Interface
This section will work through a simple C++ example in order to illustrate the use of the Gurobi
C++ 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 are available for learning the language (for example, The C++ Programming
Language , by Stroustrup).
Our example optimizes the following model:
maximize x +
y + 2z
subject to x + 2 y + 3 z 4
x +
y
1
x, y, z binary
Note that this is the same model that was modeled and optimized in the C Interface section.
Example mip1_c++.cpp
This is the complete source code for our example (also available in
<installdir>/examples/c++/mip1_c++.cpp)...
#include "gurobi_c++.h"
using namespace std;
int
main(int argc,
char *argv[])
{
try {
GRBEnv env = GRBEnv();
GRBModel model = 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");
// Set objective: maximize x + y + 2 z
56
model.setObjective(x + y + 2 * z, GRB_MAXIMIZE);
// Add constraint: x + 2 y + 3 z <= 4
model.addConstr(x + 2 * y + 3 * z <= 4, "c0");
// Add constraint: x + y >= 1
model.addConstr(x + y >= 1, "c1");
// Optimize model
model.optimize();
cout <<
<<
cout <<
<<
cout <<
<<
return 0;
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 including le gurobi_c++.h. Gurobi C++ applications should always start
by including this le.
57
Later calls to create an optimization model will always require an environment, so environment
creation is typically the rst step in a Gurobi application.
Variables are added through the addVar() method on the model object (or addVars() if you wish
to add more than one at a time). A variable is always associated with a particular model.
The rst and second arguments to the addVar() call are the variable lower and upper bounds,
respectively. The third argument is the linear objective coecient (zero here - we'll set the objective
later). The fourth argument is the variable type. Our variables are all binary in this example. The
nal argument is the name of the variable.
The addVar() method has been overloaded to accept several dierent argument lists. Please refer
to the Gurobi Reference Manual for further details.
The objective is built here using overloaded operators. The C++ API overloads the arithmetic
operators to allow you to build linear and quadratic expressions involving Gurobi variables.
The second argument indicates that the sense is maximization.
Note that while this simple example builds the objective in a single statement using an explicit list
of terms, more complex programs will typically build it incrementally. For example:
GRBLinExpr obj = 0.0;
obj += x;
obj += y;
obj += 2*z;
model.setObjective(obj, GRB_MAXIMIZE);
As with variables, constraints are always associated with a specic model. They are created using
the addConstr() or addConstrs() methods on the model object.
We again use overloaded arithmetic operators to build the linear expression. The comparison
operators are also overloaded to make it easier to build constraints.
The second argument to addConstr gives the (optional) constraint name.
Again, this simple example builds the linear expression for the constraint in a single statement using
an explicit list of terms. More complex programs will typically build the expression incrementally.
The second constraint in our model is added with this similar call:
// Add constraint: x + y >= 1
model.addConstr(x + y >= 1, "c1");
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
59
We can also query the ObjVal attribute on the model to obtain the objective value for the current
solution:
cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
The names and types of all model, variable, and constraint attributes can be found in the Attributes
section of the Gurobi Reference Manual.
Error handling
Errors in the Gurobi C++ interface are handled through the C++ 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.
sual Studio version and your choice of runtime library (Gurobi supports runtime library
options /MD, /MDd, /MT, and /MTd). To give an example, use le gurobi_c++md2010.lib
when you choose runtime library option /MD in Visual Studio 2010. Similarly, use le
60
gurobi_c++mtd2012.lib when you choose runtime library option /MTd in Visual Studio
2012.
A C++ program that uses Gurobi must link in both the Gurobi C++ library (e.g., gurobi_c++mt2010.lib
on Windows, libgurobi_c++.a on Linux and Mac) and the Gurobi C library (gurobi70.lib
on Windows, libgurobi70.so on Linux and Mac).
61
Java Interface
This section will work through a simple Java example in order to illustrate the use of the Gurobi
Java interface. The example builds a model, optimizes it, and outputs the optimal objective value.
This section assumes that you are already familiar with the Java programming language. If not, a
variety of books and websites are available for learning the language (for example, the online Java
tutorials).
Our example optimizes the following model:
maximize x +
y + 2z
subject to x + 2 y + 3 z 4
x +
y
1
x, y, z binary
Note that this is the same model that was modeled and optimized in the C Interface section.
Example Mip1.java
This is the complete source code for our example (also available in
<installdir>/examples/java/Mip1.java)...
import gurobi.*;
public class Mip1 {
public static void main(String[] args) {
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");
// Set objective: maximize x + y + 2 z
GRBLinExpr expr = new GRBLinExpr();
expr.addTerm(1.0, x); expr.addTerm(1.0, y); expr.addTerm(2.0, z);
model.setObjective(expr, GRB.MAXIMIZE);
62
} catch (GRBException e) {
System.out.println("Error code: " + e.getErrorCode() + ". " +
e.getMessage());
}
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 classes (import gurobi.*). Gurobi Java applications
should always start with this line.
63
Later calls to create an optimization model will always require an environment, so environment
creation is typically the rst step in a Gurobi application. The constructor argument species the
name of the log le.
Variables are added through the addVar() method on a model object (or addVars() if you wish to
add more than one at a time). A variable is always associated with a particular model.
The rst and second arguments to the addVar() call are the variable lower and upper bounds,
respectively. The third argument is the linear objective coecient (zero here - we'll set the objective
later). The fourth argument is the variable type. Our variables are all binary in this example. The
nal argument is the name of the variable.
The addVar() method has been overloaded to accept several dierent argument lists. Please refer
to the Gurobi Reference Manual for further details.
64
The objective must be a linear or quadratic function of the variables in the model. In our example,
we build our objective by rst constructing an empty linear expression and adding three terms to
it.
The second argument to setObjective indicates that the optimization sense is maximization.
As with variables, constraints are always associated with a specic model. They are created using
the addConstr() or addConstrs() methods on the model object.
The rst argument to addConstr() is the left-hand side of the constraint. We built the left-hand side
by rst creating an empty linear expression object, and then adding three terms to it. The second
argument is the constraint sense (GRB_LESS_EQUAL, GRB_GREATER_EQUAL, or GRB_EQUAL). The third
argument is the right-hand side (a constant in our example). The nal argument is the constraint
name. Several signatures are available for addConstr() . Please consult the Gurobi Reference Manual
for details.
The second constraint is created in a similar manner:
// Add constraint: x + y >= 1
expr = new GRBLinExpr();
expr.addTerm(1.0, x); expr.addTerm(1.0, y);
model.addConstr(expr, GRB.GREATER_EQUAL, 1.0, "c1");
65
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
We can also query the ObjVal attribute on the model to obtain the objective value for the current
solution:
System.out.println("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.
66
Error handling
Errors in the Gurobi Java interface are handled through the Java 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.
67
Note that this is the same model that was modeled and optimized in the C Interface section.
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");
// Set objective: maximize x + y + 2 z
68
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.VarName + " " + x.X);
Console.WriteLine(y.VarName + " " + y.X);
Console.WriteLine(z.VarName + " " + z.X);
Console.WriteLine("Obj: " + model.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.
69
Later calls to create an optimization model will always require an environment, so environment
creation is typically the rst step in a Gurobi application. The constructor argument species the
name of the log le.
Variables are added through the AddVar() method on a model object (or AddVars if you wish to
add more than one at a time). A variable is always associated with a particular model.
The rst and second arguments to the AddVar() call are the variable lower and upper bounds,
respectively. The third argument is the linear objective coecient (zero here - we'll set the objective
later). The fourth argument is the variable type. Our variables are all binary in this example. The
nal argument is the name of the variable.
The AddVar() method has been overloaded to accept several dierent argument lists. Please refer
to the Gurobi Reference Manual for further details.
The objective is built here using overloaded operators. The C# API overloads the arithmetic
operators to allow you to build linear and quadratic expressions involving Gurobi variables.
70
As with variables, constraints are always associated with a specic 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 easier 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, y);
expr.AddTerm(3.0, z);
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 rst 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.
// Optimize model
model.Optimize();
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
We can also query the ObjVal attribute on the model to obtain the objective value for the current
solution:
Console.WriteLine("Obj: " + model.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.
72
73
Python Interface
The Gurobi Python interface can be used in a number of ways. It is the basis of our Interactive
Shell, where it is typically used to work with existing models. It can also be used to write standalone
programs that create and solve models, in much the same way that you would use our other language
interfaces. The Gurobi distribution includes a Python interpreter and a basic set of Python modules. If you'd like additional capabilities, you can also install the Anaconda Python distribution,
which includes both a graphical development environment (Spyder) and a notebook-style interface
(Jupyter).
When comparing our Python interface against our other language interfaces, you will nd that our
Python interface adds a few higher-level constructs that allow you to build models using a more
mathematical syntax, similar to the way you might work with a traditional modeling language. This
section will work through two Python modeling examples. The rst will present a Python program
that is similar to the C, C++, Java, and C# programs presented in previous sections. The second
demonstrates some of the higher-level modeling capabilities of our Python interface.
This section assumes that you are already familiar with the Python programming language, and
that you have read the preceding section on the Gurobi Interactive Shell. If you would like to learn
more about the Python language, we recommend that you visit the Python online tutorial.
As we noted, the Gurobi distribution includes all the tools you will need to run Python programs.
However, if you would prefer to use your own Python installation, we also provide tools for installing
the gurobipy module into your Python environment. You should refer to the instructions for
building and running the examples for further details.
One big advantage of working within Python is that the Python language is popular and well
supported. One aspect of this support is the breadth of powerful Python Integrated Development
Environments (IDEs) that are available, most of which can be downloaded for free from the internet.
This document includes instructions for setting up Gurobi for use within the Anaconda distribution.
Anaconda greatly simplies the task of installing Python packages, and it includes both a graphical
development environment (Spyder) and a notebook-style interface (Jupyter). If you plan to do
signicant Python development, we recommend that you install Anaconda now. You will also nd
pointers to other useful Python tools there.
Important note for AIX users: due to limited Python support on AIX, our AIX port does not
include the Interactive Shell or the Python interface. You can use the C, C++, or Java interfaces.
The Python example directory contains a number of examples. We encourage you to browse and
modify them in order to become more familiar with the Gurobi Python interface. We also encourage
you to read the Gurobi Example Tour for more information.
74
Note that this is the same model that was modeled and optimized in the C Interface section.
Example mip1.py
This is the complete source code for our example (also available in
<installdir>/examples/python/mip1.py)...
from gurobipy import *
try:
# Create a new model
m = Model("mip1")
#
x
y
z
Create variables
= m.addVar(vtype=GRB.BINARY, name="x")
= m.addVar(vtype=GRB.BINARY, name="y")
= m.addVar(vtype=GRB.BINARY, name="z")
# Set objective
m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)
# Add constraint: x + 2 y + 3 z <= 4
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")
# Add constraint: x + y >= 1
m.addConstr(x + y >= 1, "c1")
m.optimize()
for v in m.getVars():
print(v.varName, v.x)
75
print('Obj:', m.objVal)
except GurobiError:
print('Error reported')
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 functions and classes:
from gurobipy import *
Create variables
= m.addVar(vtype=GRB.BINARY, name="x")
= m.addVar(vtype=GRB.BINARY, name="y")
= m.addVar(vtype=GRB.BINARY, name="z")
Variables are added through the addVar() method on a model object (or addVars() if you wish to
add more than one at a time). A variable is always associated with a particular model.
76
Python allows you to pass arguments by position or by name. We've passed them by name here.
Each variable gets a type (binary), and a name. We use the default values for the other arguments.
Please refer to the online help (help(Model.addVar) in the Gurobi Shell) for further details on
addVar().
The objective is built here using overloaded operators. The Python API overloads the arithmetic
operators to allow you to build linear and quadratic expressions involving Gurobi variables.
The second argument indicates that the sense is maximization.
Note that while this simple example builds the objective in a single statement using an explicit list
of terms, more complex programs will typically build it incrementally. For example:
obj = LinExpr();
obj += x;
obj += y;
obj += 2*z;
model.setObjective(obj, GRB.MAXIMIZE);
As with variables, constraints are always associated with a specic model. They are created using
the addConstr() method on the model object.
We again use overloaded arithmetic operators to build linear expressions. The comparison operators
are also overloaded to make it easier to build constraints.
The second argument to addConstr gives the (optional) constraint name.
Again, this simple example builds the linear expression for the constraint in a single statement using
an explicit list of terms. More complex programs will typically build the expression incrementally.
The second constraint is created in a similar manner:
# Add constraint: x + y >= 1
m.addConstr(x + y >= 1, "c1")
77
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
We can also query the objVal attribute on the model to obtain the objective value for the current
solution:
print('Obj:', m.objVal)
The names and types of all model, variable, and constraint attributes can be found in the online
Python documentation. Type help(GRB.Attr) in the Gurobi Shell for details.
Error handling
Errors in the Gurobi Python interface are handled through the Python exception mechanism. In
the example, all Gurobi statements are enclosed inside a try block, and any associated errors would
be caught by the except block.
78
Motivation
At the heart of any optimization model lies a set of decision variables. Finding a convenient way to
store and access these variables can often represent the main challenge in implementing the model.
While the variables in some models map naturally to simple programming language constructs
(e.g., x[i] for contiguous integer values i), other models can present a much greater challenge.
For example, consider a model that optimizes the ow of multiple dierent commodities through
a supply network. You might have a variable x['Pens', 'Denver', 'New York'] that captures
the ow of a manufactured item (pens in this example) from Denver to New York. At the same
time, you might not want to have a variable x['Pencils', 'Denver', 'Seattle'], since not all
combinations of commodities, source cities, and destination cities represent valid paths through the
network. Representing a sparse set of decision variables in a typical programming language can be
cumbersome.
To compound the challenge, you typically need to build constraints that involve subsets of these
decision variables. For example, in our network ow model you might want to put an upper bound
on the total ow that enters a particular city. You could certainly collect the relevant decision
variables by iterating over all possible cities and selecting only those variables that capture possible
ow from that source city into the desired destination city. However, this is clearly wasteful if not all
79
origin-destination pairs are valid. In a large network problem, the ineciency of this approach could
lead to major performance issues. Handling this eciently can require complex data structures.
The Gurobi Python interface has been designed to make the issues we've just described quite
easy to manage. We'll present a specic example of how this is done shortly. Before we do,
though, we'll need to describe a few important Python constructs: lists, tuples, dictionaries,
list comprehension, and generator expressions. These are standard Python concepts that are
particularly important in our interface. We'll also introduce the tuplelist and tupledict classes,
which are custom classes that we've added to the Gurobi Python interface.
A quick reminder: you can consult the online Python documentation for additional information on
any of the Python data structures mentioned here.
What's the dierence between a list and a tuple? A tuple is immutable , meaning that you can't
modify it once it has been created. By contrast, you can add new members to a list, remove
members, change existing members, etc. This immutable property allows you to use tuples as
indices for dictionaries.
Dictionaries
A Python dictionary allows you to map arbitrary key values to pieces of data. Any immutable
Python object can be used as a key: an integer, a oating-point number, a string, or even a tuple.
80
To give an example, the following statements create a dictionary x, and then associates a value 1
with key ('Pens', 'Denver', 'New York')
gurobi> x = {} # creates an empty dictionary
gurobi> x[('Pens', 'Denver', 'New York')] = 1
gurobi> print(x[('Pens', 'Denver', 'New York')])
1
Python allows you to omit the parenthesis when accessing a dictionary using a tuple, so the following
is also valid:
gurobi> x = {}
gurobi> x['Pens', 'Denver', 'New York'] = 2
gurobi> print(x['Pens', 'Denver', 'New York'])
2
We've stored integers in the dictionary here, but dictionaries can hold arbitrary objects. In particular, they can hold Gurobi decision variables:
gurobi> x['Pens', 'Denver', 'New York'] = model.addVar()
gurobi> print(x['Pens', 'Denver', 'New York'])
<gurobi.Var *Awaiting Model Update*>
To initialize a dictionary, you can of course simply perform assignments for each relevant key:
gurobi>
gurobi>
gurobi>
gurobi>
values = {}
values['zero'] = 0
values['one'] = 1
values['two'] = 2
We have included a utility routine in the Gurobi Python interface that simplies dictionary initialization for a case that arises frequently in mathematical modeling. The multidict function allows
you to initialize one or more dictionaries in a single statement. The function takes a dictionary as
its argument, where the value associated with each key is a list of length n. The function splits
these lists into individual entries, creating n separate dictionaries. The function returns a list. The
rst result is the list of shared key values, followed by the n individual dictionaries:
81
gurobi> names, lower, upper = multidict({ 'x': [0, 1], 'y': [1, 2], 'z': [0, 3] })
gurobi> print(names)
['x', 'y', 'z']
gurobi> print(lower)
{'x': 0, 'y': 1, 'z': 0}
gurobi> print(upper)
{'x': 1, 'y': 2, 'z': 3}
Note that you can also apply this function to a dictionary where each key maps to a scalar value. In
that case, the function simply returns the list of keys as the rst result, and the original dictionary
as the second.
You will see this function in several of our Python examples.
A generator expression is very similar, but it is used to generate an Iterable (something that can
be iterated over). For example, suppose we want to compute the sum of the squares of the numbers
from 1 through 5. We could use list comprehension to build the list, and then pass that list to sum.
However, it is simpler and more ecient to use a generator expression:
gurobi> sum(x*x for x in [1, 2, 3, 4, 5])
55
A generator expression can be used whenever a method accepts an Iterable argument (something
that can be iterated over). For example, most Python methods that accept a list argument (the
most common type of Iterable) will also accept a generator expression.
Note that there's a Python routine for creating a contiguous list of integers: range. The above
would typically be written as follows:
gurobi> sum(x*x for x in range(1,6))
82
Note that the for statements are executed left-to-right, and values from one can be used in the
next, so a more ecient way to write the above is:
gurobi> [(x,y) for x in range(4) for y in range(x+1, 4)]
Generator expressions are used extensively in our Python examples, primarily in the context of the
addConstrs method.
To select a sub-list where particular tuple entries match desired values, you specify the desired values
as arguments to the select method. The number of arguments to select is equal to the number
of entries in the members of the tuplelist (they should all have the same number of entries). You
use a '*' string to indicate that any value is acceptable in that position in the tuple.
Each tuple in our example contains two entries, so we can perform the following selections:
gurobi> print(l.select(1, '*'))
<gurobi.tuplelist (2 tuples, 2 values
( 1 , 2 )
( 1 , 3 )
>
gurobi> print(l.select('*', 3))
<gurobi.tuplelist (2 tuples, 2 values
( 1 , 3 )
( 2 , 3 )
>
gurobi> print(l.select(1, 3))
<gurobi.tuplelist (1 tuples, 2 values
( 1 , 3 )
>
gurobi> print(l.select('*', '*'))
<gurobi.tuplelist (4 tuples, 2 values
( 1 , 2 )
( 1 , 3 )
( 2 , 3 )
each):
each):
each):
each):
83
( 2 , 4 )
>
You may have noticed that similar results could have been achieved using list comprehension. For
example:
gurobi> print(l.select(1, '*'))
<gurobi.tuplelist (2 tuples, 2 values each):
( 1 , 2 )
( 1 , 3 )
>
gurobi> print([(x,y) for x,y in l if x == 1])
[(1, 2), (1, 3)]
The problem is that the latter statement considers every member in the list, which can be quite
inecient for large lists. The select method builds internal data structures that make these
selections quite ecient.
Note that tuplelist is a sub-class of list, so you can use the standard list methods to access or
modify a tuplelist:
gurobi> print(l[1])
(1,3)
gurobi> l += [(3, 4)]
gurobi> print(l)
<gurobi.tuplelist (5 tuples, 2 values each):
( 1 , 2 )
( 1 , 3 )
( 2 , 3 )
( 2 , 4 )
( 3 , 4 )
>
returns the result as a tupledict. Let us give a simple example. We'll begin by constructing a list
of tuples, and then we'll create a set of Gurobi variables that are indexed using this list:
gurobi> l = list([(1, 2), (1, 3), (2, 3), (2, 4)])
gurobi> d = model.addVars(l, name="d")
The addVars method will create variables d(1,2), d(1,3), d(2,3), and d(2,4). Note that the name
argument is used to name the resulting variables, but it only gives the prex for the name - the
names are subscripted by the tuple keys (so the variables would be named d[1,2], d[1,3], etc.).
You can then use this tupledict to build linear expressions. For example, you could do:
gurobi> sum(d.select(1, '*'))
The select method returns a list of Gurobi variables where the rst eld of the associated tuple is 1.
The Python sum statement then creates a linear expression that captures the sum of these variables.
In this case, that expression would be d(1,2) + d(1,3). Similarly, sum(d.select('*', 3)) would
give d(1,3) + d(2,3). As with a tuplelist, you use a '*' string to indicate that any value is
acceptable in that position in the tuple.
The tupledict class includes a method that simplies the above. Rather than sum(d.select('*', 3)),
you can use d.sum('*', 3) instead.
The tupledict class also includes a prod method, for cases where your linear expression has coefcients that aren't all 1.0. Coecients are provided through a dict argument. They are indexed
using the same tuples as the tupledict. For example, given a dict named coeff with two entries: coeff(1,2) = 5 and coeff(2,3) = 7, a call to d.prod(coeff) would give the expression
5 d(1,2) + 7 d(2,3). You can also include a lter, so d.prod(coeff, 2, '*') would give just
7 d(2,3).
Note that tupledict is a sub-class of dict, so you can use the standard dict methods to access or
modify a tupledict:
gurobi> print(d[1,3])
<gurobi.Var d[1,3]>
gurobi> d[3, 4] = 0.3
gurobi> print(d[3, 4])
0.3
gurobi> print(d.values())
dict_values([<gurobi.Var d[1,2]>, 0.3, <gurobi.Var d[1,3]>, <gurobi.Var d[2,3]>, <gurobi.Var d[2
In our upcoming network ow example, once we've built a tupledict that contains a variable
for each valid commodity-source-destination combination on the network (we'll call it flows), we
can create a linear expression that captures the total ow on all arcs that empty into a specic
destination city as follows:
gurobi> inbound = flows.sum('*', '*', 'New York')
We now present an example that illustrates the use of all of the concepts discussed so far.
85
netow.py example
Our example solves a multi-commodity ow model on a small network. In the example, two commodities (Pencils and Pens) are produced in two cities (Detroit and Denver), and must be shipped
to warehouses in three cities (Boston, New York, and Seattle) to satisfy given demand. Each arc in
the transportation network has a cost associated with it, and a total capacity.
This is the complete source code for our example (also available in
<installdir>/examples/python/netflow.py)...
from gurobipy import *
# Model data
commodities = ['Pencils', 'Pens']
nodes = ['Detroit', 'Denver', 'Boston', 'New York', 'Seattle']
arcs, capacity = multidict({
('Detroit', 'Boston'): 100,
('Detroit', 'New York'): 80,
('Detroit', 'Seattle'): 120,
('Denver', 'Boston'): 120,
('Denver', 'New York'): 120,
('Denver', 'Seattle'): 120 })
cost = {
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pens',
('Pens',
('Pens',
('Pens',
('Pens',
('Pens',
'Detroit',
'Detroit',
'Detroit',
'Denver',
'Denver',
'Denver',
'Detroit',
'Detroit',
'Detroit',
'Denver',
'Denver',
'Denver',
inflow = {
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pens',
'Detroit'):
'Denver'):
'Boston'):
'New York'):
'Seattle'):
'Detroit'):
86
'Boston'):
'New York'):
'Seattle'):
'Boston'):
'New York'):
'Seattle'):
'Boston'):
'New York'):
'Seattle'):
'Boston'):
'New York'):
'Seattle'):
50,
60,
-50,
-50,
-10,
60,
10,
20,
60,
40,
40,
30,
20,
20,
80,
60,
70,
30 }
('Pens',
('Pens',
('Pens',
('Pens',
'Denver'):
'Boston'):
'New York'):
'Seattle'):
40,
-40,
-30,
-30 }
87
The model works with two commodities (Pencils and Pens), and the network contains 5 nodes and
6 arcs. We initialize commodities and nodes as simple Python lists. We use the Gurobi multidict
function to initialize arcs (the list of keys) and capacity (a dictionary).
The model also requires cost data for each commodity-arc pair:
cost = {
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pens',
('Pens',
('Pens',
('Pens',
('Pens',
('Pens',
'Detroit',
'Detroit',
'Detroit',
'Denver',
'Denver',
'Denver',
'Detroit',
'Detroit',
'Detroit',
'Denver',
'Denver',
'Denver',
'Boston'):
'New York'):
'Seattle'):
'Boston'):
'New York'):
'Seattle'):
'Boston'):
'New York'):
'Seattle'):
'Boston'):
'New York'):
'Seattle'):
10,
20,
60,
40,
40,
30,
20,
20,
80,
60,
70,
30 }
Once this dictionary has been created, the cost of moving commodity h from node i to j can be
queried as cost[(h,i,j)]. Recall that Python allows you to omit the parenthesis when using a
tuple to index a dictionary, so this can be shortened to just cost[h,i,j].
A similar construct is used to initialize node demand data:
inflow = {
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pencils',
('Pens',
('Pens',
('Pens',
('Pens',
('Pens',
88
'Detroit'):
'Denver'):
'Boston'):
'New York'):
'Seattle'):
'Detroit'):
'Denver'):
'Boston'):
'New York'):
'Seattle'):
50,
60,
-50,
-50,
-10,
60,
40,
-40,
-30,
-30 }
The rst, positional arguments to addVars give the index set. In this case, we'll be indexing flow
by commodities and arcs. In other words, flow[c,i,j] will capture the ow of commodity c from
node i to node j. Note that flow only contains variables for source, destination pairs that are
present in arcs.
Note that this one statement uses several of the concepts that were introduced earlier in this section.
The rst concept used here is the sum method on flow, which is used to create a linear expression
over a subset of the variables in the tupledict. In particular, it is summing over all commodities
(the '*' in the rst eld) associated with an edge between a pair of cities i and j.
The second concept used here is a generator expression, which iterates over all arcs in the network.
Specically, this portion of the statement...
for i,j in arcs
indicates that we are iterating over every edge in arcs. In each iteration, i and j will be populated
using the corresponding values from a tuple in arcs. In a particular iteration, flow.sum('*',i,j)
will be computed using those specic values, as will capacity[i,j].
The third thing to note is that we're passing the result as an argument to addConstrs. This method
will create a set of Gurobi constraints, one for each iteration of the generator expression.
The nal thing to note is that the last argument gives the base for the constraint name. The
addConstrs method will automatically append the corresponding indices for each constraint. Thus,
for example, the name of the constraint that limits ow from Denver to Boston will be cap[Denver,Boston].
Note that if you prefer to do your own looping, you could obtain the equivalent behavior with the
following loop:
89
This call to addConstrs is similar to the previous one, although a bit more complex. We invoke the
sum method on a tupledict, wrapped inside of a generator expression, to add one linear constraint
for each commodity-node pair. In this instance, we call sum twice, and we use a generator expression
that contains of a pair of for loops, but the basic concepts remain the same.
Results
Once we've added the model constraints, we call optimize and then output the optimal solution:
if m.status == GRB.Status.OPTIMAL:
solution = m.getAttr('x', flow)
for h in commodities:
print('\nOptimal flows for %s:' % h)
for i,j in arcs:
if solution[h,i,j] > 0:
print('%s -> %s: %g' % (i, j, solution[h,i,j]))
If you run the example (gurobi.bat netflow.py on Windows, or gurobi.sh netflow.py on Linux
and Mac), you should see the following output:
Optimize a model with 16 rows, 12 columns and 36 nonzeros
Presolve removed 16 rows and 12 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Iteration
Objective
Primal Inf.
Dual Inf.
Time
0
5.5000000e+03 0.000000e+00
0.000000e+00
0s
Solved in 0 iterations and 0.00 seconds
Optimal objective 5.500000000e+03
90
If you are a Python user and wish to use Gurobi from within your own Python environment, we
recommend that you use the Anaconda Python distribution. Anaconda includes a number of very
useful packages, and the Gurobi Anaconda package simplies the installation process.
You can also install the gurobipy module directly into other Python environments. The steps for
doing this depend on your platform. On Windows, you can double-click on the pysetup program
in the Gurobi <installdir>/bin directory. This program will prompt you for the location of your
Python installation; it handles all of the details of the installation. On Linux or Mac OS, you will
need to open a terminal window, change your current directory to the Gurobi <installdir> (the
directory that contains the le setup.py), and issue the following command:
python setup.py install
Unless you are using your own private Python installation, you will need to run this command as
super-user. Once gurobipy is successfully installed, you can type python mip1.py (more generally,
you can type from gurobipy import * in your Python environment).
91
MATLAB Interface
This section describes the Gurobi MATLAB interface. We begin with information on how to set up
Gurobi for use within MATLAB. An example of how to use the MATLAB interface follows.
You will need to be careful that the MATLAB binary and the Gurobi package you install both
use the same instruction set. For example, if you are using the 64-bit version of MATLAB, you'll
need to install the 64-bit version of Gurobi, and you'll need to use the 64-bit Gurobi MATLAB
libraries (i.e., the ones included with the 64-bit version of Gurobi). This is particularly important
on Windows systems, where the error messages that result from instruction set mismatches can be
quite cryptic.
Example
Let us now turn our attention to an example of using Gurobi to solve a simple MIP model. Our
example optimizes the following model:
maximize x +
y + 2z
subject to x + 2 y + 3 z 4
x +
y
1
x, y, z binary
Note that this is the same model that was modeled and optimized in the C Interface section.
This is the complete source code for our example (also available in
<installdir>/examples/matlab/mip1.m)...
names = {'x'; 'y'; 'z'};
92
try
clear model;
model.A = sparse([1 2 3; 1 1 0]);
model.obj = [1 1 2];
model.rhs = [4; 1];
model.sense = '<>';
model.vtype = 'B';
model.modelsense = 'max';
clear params;
params.outputflag = 0;
params.resultfile = 'mip1.lp';
result = gurobi(model, params);
disp(result)
for v=1:length(names)
fprintf('%s %d\n', names{v}, result.x(v));
end
fprintf('Obj: %e\n', result.objval);
catch gurobiError
fprintf('Error reported\n');
end
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.
Subsequent statements populate other elds of the model variable, including the objective vector,
the right-hand-side vector, and the constraint sense vector.
In addition to the mandatory elds, this example also sets two optional elds: modelsense and
vtype. The former is used to indicate the sense of the objective function. The default is minimization, so we've set the elds equal to 'max' to indicate that we would like to maximize the specied
objective. The vtype eld is used to indicate the types of the variables in the model. In our example, all variables are binary ('B'). Note that our interface allows you to specify a scalar value for
the sense and vtype arguments. The Gurobi interface will expand that scalar to a constant array
of the appropriate length. In this example, the scalar value 'B' will be expanded to an array of
length 3, containing one 'B' value for each column of A.
In this example, we set the Gurobi OutputFlag parameter to 0 in order to shut o Gurobi output.
We also set the ResultFile parameter to request that Gurobi produce a le as output (in this case,
an LP format le that contains the optimization model). The Gurobi MATLAB interface allows
you to set as many Gurobi parameters as you like. The eld names in the parameter structure
simply need to match Gurobi parameter names, and the values of the elds should be set to the
desired parameter value. Please consult the Parameters section of the Gurobi Reference Manual for
a complete list of all Gurobi parameters.
We pass the model and the optional list of parameter changes to the gurobi() function. It computes
an optimal solution to the specied model and returns the computed result.
status codes. If Gurobi was able to nd a solution to the model, the return value will also include
objval and x elds. The former gives the objective value for the computed solution, and the latter
is the computed solution vector (one entry per column of the constraint matrix). For continuous
models, we will also return dual information (reduced costs and dual multipliers), and possibly an
optimal basis.
In our example, we simply print the optimal objective value (result.objval) and the optimal
solution vector (result.x).
If Gurobi was successfully set up for use in MATLAB, you should see the following output:
status:
versioninfo:
objval:
runtime:
x:
slack:
objbound:
itercount:
baritercount:
nodecount:
'OPTIMAL'
[1x1 struct]
3
0.0386
[3x1 double]
[2x1 double]
3
0
0
0
x 1
y 0
z 1
Obj: 3.000000e+00
The MATLAB example directory contains a number of examples. We encourage you to browse and
modify them in order to become more familiar with the Gurobi MATLAB interface.
95
R Interface
This section describes the Gurobi R interface. We begin with information on how to set up Gurobi
for use within R. An example of how to use the R interface follows.
The R package le can be found in the <installdir>/R directory of your Gurobi installation. For
a default installation of Gurobi 7.0.1, the command would be:
Linux:
install.packages('/opt/gurobi701/linux64/R/gurobi_7.0-1_R_x86_64-unknown-linux-gnu.tar.gz',
repos=NULL)
Windows: install.packages('c:\gurobi701\win64\R\gurobi_7.0-1.zip', repos=NULL)
Mac: install.packages('/Library/gurobi701/mac64/R/gurobi_7.0-1.tgz', repos=NULL)
You will need to adjust the path to match your install directory and version.
You will need to be careful that the R binary and the Gurobi package you install both use the same
instruction set. For example, if you are using the 64-bit version of R, you'll need to install the 64-bit
version of Gurobi, and the 64-bit Gurobi R package. This is particularly important on Windows
systems, where the error messages that result from instruction set mismatches can be quite cryptic.
If you are using R from RStudio Server, and you get an error indicating that R is unable to load
the Gurobi DLL or shared object, you may need to set the rsession-ld-library-path entry in
the server cong le. Please consult the RStudio documentation for more information.
Example
Let us now turn our attention to an example of using Gurobi to solve a simple MIP model. Our
example optimizes the following model:
maximize x +
y + 2z
subject to x + 2 y + 3 z 4
x +
y
1
x, y, z binary
96
Note that this is the same model that was modeled and optimized in the C Interface section.
This is the complete source code for our example (also available in
<installdir>/examples/R/mip.R)...
library('gurobi')
model <- list()
model$A
model$obj
model$modelsense
model$rhs
model$sense
model$vtype
<<<<<<-
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 package (library('gurobi')). R programs that call
Gurobi must include this line.
vector, the right-hand-side vector, and the constraint sense vector. In each case, we use the built-in
c function to initialize the array arguments.
In addition to the mandatory components, this example also sets two optional components: modelsense
and vtype. The former is used to indicate the sense of the objective function. The default is minimization, so we've set the components equal to 'max' to indicate that we would like to maximize
the specied objective. The vtype component is used to indicate the types of the variables in the
model. In our example, all variables are binary ('B'). Note that our interface allows you to specify
a scalar value for any array argument. The Gurobi interface will expand that scalar to a constant
array of the appropriate length. In this example, the scalar value 'B' will be expanded to an array
of length 3, containing one 'B' value for each column of A.
One important note about default variable bounds: the convention in math programming is that
a variable will by default have a lower bound of 0 and an innite upper bound. If you'd like your
variables to have dierent bounds, you'll need to provide them explicitly.
In this example, we wish to set the Gurobi OutputFlag parameter to 0 in order to shut o Gurobi
output. The Gurobi R interface allows you to pass a list of the Gurobi parameters you would like
to change. Please consult the Parameters section of the Gurobi Reference Manual for a complete
list of all Gurobi parameters.
We pass the model and the optional list of parameter changes to the gurobi() function. It computes
an optimal solution to the specied model and returns the computed result.
complete list of all possible status codes. If Gurobi was able to nd a solution to the model, the
return value will also include objval and x components. The former gives the objective value for
the computed solution, and the latter is the computed solution vector (one entry per column of the
constraint matrix). For continuous models, we will also return dual information (reduced costs and
dual multipliers), and possibly an optimal basis.
In our example, we simply print the optimal objective value (result$objval) and the optimal
solution vector (result$x).
If the Gurobi package was successfully installed, you should see the following output:
[1] "Solution:"
[1] 3
[1] 1 0 1
99
Recommended Reading
The very basic introduction to mathematical programming and mathematical modeling in this
document barely scratches the surface of this very broad and rich eld. We've collected a set of
recommended books here that provide more information on various aspects of math programming.
If you want more information on the algorithms and mathematics underlying the solution of linear
programming problems, we recommend Introduction to Linear Optimization by Bertsimas, Tsitsiklis, and Tsitsiklis, or Linear Programming: Foundations and Extensions by R. Vanderbei. For a
detailed treatment of interior-point methods for linear programming, we recommend Primal-Dual
Interior-Point Methods by S. Wright.
For more information on the algorithms and mathematics underlying the solution of mixed-integer
programming problems, we recommend Integer Programming by L. Wolsey.
For an introduction to the process of creating mathematical programming representations of business
problems, we recommand Model Building in Mathematical Programming by H.P. Williams.
100
Gurobi supports Python 2.7 and Python 3.5, in both 32-bit and 64-bit versions. Click on the download button (Windows 64-Bit Python 2.7 in this case), and then download and run the Anaconda
installer.
101
You can remove the Gurobi package at any time by issuing the command
102
Note that a general-purpose Python IDE like Spyder requires one extra step that isn't required
when you launch the Gurobi shell from the Gurobi icon or by using the gurobi.bat command:
you must manually load the Gurobi module by typing from gurobipy import * before issuing any
Gurobi commands.
You can also use Spyder to run any of the Gurobi examples. For example, if you use Open under the
File menu to open Gurobi example mip1.py, and then click on the Run icon (the green triangle),
you should see:
103
Some Gurobi examples require command-line arguments. Those can be input from the Configure...
item of the Run menu. For example, to run the sudoku.py example with le sudoku1 as input...
104
Anaconda Python includes all of the Python modules used in the Gurobi examples, but feel free to
explore the vast library of additional Python modules. A list of available modules can be found at
the PyPI site. You can use the conda command to install additional modules. Type conda into a
terminal window with no arguments to get additional information on this command.
Our simple example shows a set of commands that create and solve a simple linear programming
model, and then plot the resulting constraints and the computed optimal vertex.
For those of you who aren't familiar with notebook-style interfaces, they allow you to mix executable
code, text, and graphics to create a self-documenting stream of results. Notebooks can be saved and
continued later, which make them particularly well suited for prototyping and experimentation.
105
While these two interfaces are useful for issuing simple commands, they aren't suited for extensive
interactive usage. If you want to launch Gurobi command-line commands and see the resulting
106
output, for example, you'll need a Console window (also known as a Command Prompt window or
just a cmd window). To launch a Console window, type cmd into either the Run window or the
Search box (as described above). This window will remain open, displaying the output from the
previous command and waiting for the next command, until you close it.
107
File Overview
This section briey describes the purposes of the more important les in the Gurobi distribution.
Note that the list below may not precisely agree with your installation. We've omitted a few less
important les. In addition, a few le names depend on the exact version of the Gurobi optimizer
that you installed.
The following les and directories are created in your installation directory (c:\gurobi701\win64
by default for the 64-bit Windows distribution):
EULA.doc - Gurobi End User License Agreement - Microsoft Word format
EULA.pdf - Gurobi End User License Agreement - PDF format
ReleaseNotes.html - release notes
bin
aes70.dll - Gurobi communication library (used for Compute Server and Instant Cloud)
Gurobi70.NET.XML - Visual Studio help for .NET wrapper
Gurobi70.NET.dll - .NET wrapper
GurobiJni70.dll - Java JNI wrapper
grb_rs.exe - Gurobi Remote Services executable
grb_rsw.exe - Gurobi Remote Services executable
grb_ts.exe - Gurobi Token Server executable
grbgetkey.exe - retrieves your Gurobi license key from the Gurobi key server
grbprobe.exe - probes system details (typically not used)
grbtune.exe - parameter tuning tool
gurobi.bat - starts the Gurobi interactive shell
gurobi.env - sample parameter initialization le
gurobi70.dll - Gurobi native DLL (used by all Gurobi interfaces)
gurobi_cl.exe - simple command-line binary
libcurl.dll - CURL library (used for Instant Cloud)
docs
108
build - Visual Studio projects for C, C++, C#, and Visual Basic examples; run*.bat
les for Java and Python examples
c - source code for C examples
c# - source code for C# examples
c++ - source code for C++ examples
data - data les for examples
java - source code for Java examples
matlab - source code for MATLAB examples
python - source code for Python examples
R - source code for R examples
vb - source code for Visual Basic examples
include
gurobi_c++mdd2015.lib - C++ interface (when using -MDd compiler switch with Visual
Studio 2015)
gurobi_c++mt2010.lib - C++ interface (when using -MT compiler switch with Visual
Studio 2010)
gurobi_c++mt2012.lib - C++ interface (when using -MT compiler switch with Visual
Studio 2012)
gurobi_c++mt2013.lib - C++ interface (when using -MT compiler switch with Visual
Studio 2013)
gurobi_c++mt2015.lib - C++ interface (when using -MT compiler switch with Visual
Studio 2015)
gurobi_c++mtd2010.lib - C++ interface (when using -MTd compiler switch with Visual
Studio 2010)
gurobi_c++mtd2012.lib - C++ interface (when using -MTd compiler switch with Visual
Studio 2012)
gurobi_c++mtd2013.lib - C++ interface (when using -MTd compiler switch with Visual
Studio 2013)
gurobi_c++mtd2015.lib - C++ interface (when using -MTd compiler switch with Visual
Studio 2015)
matlab - Gurobi MATLAB interface
python27 - Python 2.7 les used by the interactive shell and the Python interface (no need to
python35 - Python 3.5 les (no need to look inside this directory)
R - R Gurobi package
setup.py - Python setup le - for installing the gurobipy module into your own Python envi-
ronment
src
110