Quickstart Linux
Quickstart Linux
1 Introduction 1
6 Interactive Shell 28
i
7 Attributes 40
8 C Interface 41
9 C++ Interface 48
10 Java Interface 54
12 Python 66
12.1 Python Installation Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Using pip to install gurobipy . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Manual installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Anaconda and Gurobi conda package . . . . . . . . . . . . . . . . . . . . . . 67
12.2 Python Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Jupyter Notebook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
The Spyder IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
12.3 gurobipy, the Gurobi Python Interface . . . . . . . . . . . . . . . . . . . . . . . . . . 73
12.4 Simple Python Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
12.5 Python Matrix Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
12.6 Python Dictionary Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
12.7 Running the examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
13 MATLAB Interface 96
14 R Interface 100
ii
Introduction
Welcome to the GurobiTM Optimizer Quick Start Guide for Linux users! This document provides
a basic introduction to the Gurobi Optimizer, including:
• 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
Command Line, and
• C interface,
• C++ interface,
• Java R interface,
• Python interface,
• MATLAB R interface, or
• R interface.
At the end of the Quick Start Guide, you’ll find a File Overview that lists the files included in the
Gurobi distribution.
1
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
programming language APIs, consult the Gurobi Reference Manual.
• If you would like to see examples of ways to use Gurobi, consult the Gurobi Example Tour.
• If you are a Gurobi Compute Server user, consult the Gurobi Remote Services Reference
Manual.
• If you would like to learn more about mathematical programming or modeling, we’ve collected
a set of references in our recommended reading section.
Getting help
If you have a question that is not answered in this document, please visit the Gurobi support site at
https://support.gurobi.com. There, you can read knowledge base articles and join the community
discussion forum. Also, if you have a current maintenance contract, you can use the Gurobi support
site to submit a request to the Gurobi support team.
Ready to get started? Your first step is to Obtain a License.
2
Obtaining a Gurobi License
You will need a license in order to install and use the Gurobi Optimizer. There are several ways to
obtain one, depending on your situation:
• If you would like a free evaluation license, please email us at [email protected] to request 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 your Current
Gurobi Licenses page on our website (you will need to log in to your account to see this page).
• The exception is a Web License Service (WLS) license, where you will need to download a
WLS client license from our server.
• If you plan to use Gurobi as a client of a Gurobi Compute Server, you will need to create a
Compute Server client license.
• If you plan to use Gurobi as a client of a Gurobi token server, you will need to create a token
server client license.
Once you have a license, your next step is to install the software.
3
Software Installation Guide
Before using the Gurobi Optimizer, you’ll need to install the software on your computer. This
section covers the installation of the entire Gurobi product. If you plan to use Gurobi from Python
only, you can use our pip package or our Anaconda package instead.
When installing the full Gurobi product, your first steps are to visit our download page, find your
platform (we’ll assume Linux in this document), and choose the corresponding file to download.
4
Your next step is to choose a destination directory. We recommend /opt for a shared installation
(assuming you have sudo privileges to write in that directory), or your home directory for a private
installation, but other directories will work as well. You’ll need to change your working directory
to the destination directory (e.g., cd /opt or cd /home/jones), then copy the Gurobi distribution
to that directory, and then extract the contents:
tar xvfz gurobi9.5.2_linux64.tar.gz
This command will create a sub-directory /opt/gurobi952/linux64 that contains the complete
Gurobi distribution (assuming you chose /opt). Your <installdir> (which we’ll refer to through-
out this document) will be /opt/gurobi952/linux64.
The Gurobi Optimizer makes use of several executable files. In order to allow these files to be found
when needed, you will have to modify a few environment variables:
Users of the bash shell should add the following lines to their .bashrc files:
export GUROBI_HOME="/opt/gurobi952/linux64"
export PATH="${PATH}:${GUROBI_HOME}/bin"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib"
Users of the csh shell should add the following lines to their .cshrc files:
setenv GUROBI_HOME /opt/gurobi952/linux64
setenv PATH ${PATH}:${GUROBI_HOME}/bin
setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib
If LD_LIBRARY_PATH is not already set, use the following instead:
export LD_LIBRARY_PATH="${GUROBI_HOME}/lib"
or
5
If you would like an overview of the files included in the Gurobi distribution, you can also view the
File Overview section.
If you are running Gurobi on a system with SELinux enforced, you should read this section.
3.1 SELinux
When you run a program that uses Gurobi on some SELinux systems, you may run into the
following error message:
error while loading shared libraries: libgurobi95.so:
cannot restore segment prot after reloc: Permission denied
The simplest workaround is to set alloc_execmod on your system (as root):
The on setting is the default on most SELinux systems, but it may be off in some cases. Note that
this is a system-wide setting, so you should consult your system administrator before making this
change.
A more local workaround is to modify the security context for the Gurobi shared library:
> chcon -t textrel_shlib_t libgurobi95.so
You can also use the semanage command to set SELinux policy for this library.
Please consult the SELinux documentation for more information on these commands.
6
Retrieving and Setting Up a Gurobi License
Once your license is visible on the Current Gurobi Licenses page of our website, click on the License
ID to view the License Details page:
Your next step is to install this Gurobi license on your machine. You do this by obtaining a license
key file.
7
We strongly recommend that you place your client gurobi.lic file in a default location for your
platform (either your home directory or /opt/gurobi). Setting up a non-default location is error-
prone and a frequent source of trouble.
Please consult the License Type field on the License Details page for your license to identify your
license type. 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.
–––––––––––––––––––––––––––––––
Contacting Gurobi key server...
–––––––––––––––––––––––––––––––
8
–––––––––––––––––––––
Saving license key...
–––––––––––––––––––––
In which directorywould you like to store the Gurobi license key file?
[hit Enter to store it in /opt/gurobi]:
You can store the license key file anywhere, but we strongly recommend that you accept the default
location (either your home directory or /opt/gurobi) 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.
When you run the Linux version of the Gurobi Optimizer, it will look for the gurobi.lic key
file in three different default locations: /opt/gurobi, /opt/gurobi952 (for 9.5.2), and your home
directory. If you would like to use a non-default license key file location, you can do so by setting an
environment variable GRB_LICENSE_FILE to point to the license key file. See Setting environment
variables for details on how to do this.
Important note: the environment variable should point to the license key file itself, not to the
directory that contains the file.
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 file, your next step is to
test your license.
Academic validation
If you are using a free academic license, grbgetkey will perform an academic validation step before
retrieving your license key. This step checks your domain name against our list of known academic
domains. This section will help you resolve validation errors.
it means your domain isn’t on our academic domain list. Please make sure you are connected to
9
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 visit our support site for assistance.
If you are having trouble validating your license through a VPN, note that some VPNs are con-
figured to use split tunneling, where traffic to public internet sites is routed through your ISP.
You should ask your network administrator whether the VPN can be configured to route traffic to
gurobi.com through the private network.
Some machines connect to the internet through a proxy server. You can use the HTTPS_PROXY or
HTTP_PROXY environment variables to enable grbgetkey to work with your proxy server. Type
grbgetkey --help for details.
If grbgetkey produces a message that only references a numerical IP address, like this:
ERROR 303: hostname 234.28.234.12 (234.28.234.100) not recognized as
belonging to an academic domain
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.
There is unfortunately no way for us to validate your academic license without reverse DNS infor-
mation. You can visit this site to check DNS information for your IP address and to obtain more
information about reverse DNS.
10
Gurobi license key client (version 9.5.2)
Copyright (c) 2022, Gurobi Optimization, LLC
–––––––––––––––––––––––––––––––
Contacting Gurobi key server...
–––––––––––––––––––––––––––––––
–––––––––––––––––––––
Saving license key...
–––––––––––––––––––––
In which directorywould you like to store the Gurobi license key file?
[hit Enter to store it in /opt/gurobi]:
You can store the license key file anywhere, but we strongly recommend that you accept the default
location (either your home directory or /opt/gurobi) by hitting Enter. Setting up a non-default
location is error-prone and a frequent source of trouble.
When you run the Linux version of the Gurobi Optimizer, it will look for the gurobi.lic key
file in three different default locations: /opt/gurobi, /opt/gurobi952 (for 9.5.2), and your home
directory. If you would like to use a non-default license key file location, you can do so by setting an
environment variable GRB_LICENSE_FILE to point to the license key file. See Setting environment
variables for details on how to do this.
Important note: the environment variable should point to the license key file itself, not to the
directory that contains the file.
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 file, your next step is to
test your license.
11
While some container environments may run macOS or Windows binaries, Gurobi currently only
supports Linux containers.
The simplest way to use a WLS license is with a gurobi.lic license file. To retrieve one, visit
the Web License Manager site, log in to your account, click on the Licenses tab, and finally click
Download for the WLS license you plan to use. We recommend that you store the resulting
gurobi.lic file in /opt/gurobi, which is the default location on Linux.
The gurobi.lic file you get will always contain the following three lines:
WLSACCESSID=203dec48-e3f8-46ac-0184-92d7d6ded944
WLSSECRET=a080cce8-4e01-4e36-955e-61592c5630db
LICENSEID=12127
These give the WLS license ID, the access ID for that license, and the corresponding secret key.
These credentials are private and should not be shared with anyone who is not entitled to use your
license.
As noted earlier, you can also provide your credentials through a Gurobi programming language
API using an API key.
When you run the Linux version of the Gurobi Optimizer, it will look for the gurobi.lic key
file in three different default locations: /opt/gurobi, /opt/gurobi952 (for 9.5.2), and your home
directory. If you would like to use a non-default license key file location, you can do so by setting an
environment variable GRB_LICENSE_FILE to point to the license key file. See Setting environment
variables for details on how to do this.
Important note: the environment variable should point to the license key file itself, not to the
directory that contains the file.
Next steps
Once you have followed the steps above and obtained a license key file, your next step is to test
your license.
12
Retrieving a Floating license
If you are using a floating license, you will need to choose a machine to act as your Gurobi token
server. This token server doles out tokens to client machines. A client will request a token from the
token server when it creates a Gurobi environment, and it will return the token when it destroys
that environment. The client machine can be any machine that can reach the token server over your
network (including the token server itself). The client can run any supported operating system.
Thus, for example, a Linux client can request tokens from a Windows token server.
Once you’ve chosen a machine to act as your token server, you’ll need to run the grbgetkey
command on your machine to retrieve your Gurobi license key. Note that the machine must be
connected to the Internet in order to run this command. An Internet connection is not required
after you have obtained your license key.
If your computer isn’t connected to the Internet or if your network security system does not allow
the command below to function, we also offer a manual license key process. You’ll find manual
instructions at the bottom of the License Details page for your license (which can be found by
visiting Current Gurobi Licenses and clicking on the appropriate License ID).
The exact grbgetkey command to run for a specific license is indicated at the bottom of the License
Details page (e.g., grbgetkey 253e22f3-...). We recommend that you use copy-paste to copy
the entire grbgetkey command from our website and paste it into a shell window.
The grbgetkey program passes identifying information about your machine back to our website,
and the website responds with your license key. Once this exchange has occurred, grbgetkey will
ask for the name of the directory in which to store your license key file (gurobi.lic). You should
see a prompt that looks like this:
Gurobi license key client (version 9.5.2)
Copyright (c) 2022, Gurobi Optimization, LLC
–––––––––––––––––––––––––––––––
Contacting Gurobi key server...
–––––––––––––––––––––––––––––––
–––––––––––––––––––––
Saving license key...
–––––––––––––––––––––
In which directorywould you like to store the Gurobi license key file?
[hit Enter to store it in /opt/gurobi]:
You can store the license key file anywhere, but we strongly recommend that you accept the default
location (either your home directory or /opt/gurobi) by hitting Enter. Setting up a non-default
location is error-prone and a frequent source of trouble.
13
Setting a password for your token server
If you want to require clients of your token server to specify a password in order to check out a
token, you’ll need to add one line to your gurobi.lic file:
PASSWORD=abcd1234
You should of course choose your own password. Clients will need to place this same line in their
client license files.
When adding this line to your gurobi.lic file, please be careful not to modify anything else in the
file.
When you run the Linux version of the Gurobi Optimizer, it will look for the gurobi.lic key
file in three different default locations: /opt/gurobi, /opt/gurobi952 (for 9.5.2), and your home
directory. If you would like to use a non-default license key file location, you can do so by setting an
environment variable GRB_LICENSE_FILE to point to the license key file. See Setting environment
variables for details on how to do this.
Important note: the environment variable should point to the license key file itself, not to the
directory that contains the file.
Once you have followed the steps above and have obtained a license key file, your next step is to
start the token server.
Important note: most Gurobi licenses do not use the token server. You should
only follow these instructions if you are setting up a floating license. If you are
not sure whether you need to start a token server, you can examine the contents of
your gurobi.lic file. If it contains the line TYPE=TOKEN, and does not contain the line
MACHINELIMIT=0, then you need a token server.
To start the Linux token server daemon, run the program grb_ts (with no arguments) on your
token server machine. You only need to do this once -- the token server will keep running until
you stop it (or until the machine is shut down). Be sure that the license key file has been installed
before running this program. Note that the token server runs as a user process, so you do not need
root privileges to start it.
If you would like the token server to restart automatically when the machine is rebooted, there
are a number of options for doing so (including /etc/rc.local and upstart). You should talk to
your system administrator.
To stop a running token server, you can issue the grb_ts -s command. You can also use the ps
command to find the relevant process ID, and the kill command to terminate that process.
Output from the token server goes to the system log (/var/log/syslog). You should see a message
similar to the following when you start the server:
14
Mar 5 12:37:21 mymachine grb[7917]: Gurobi Token Server started: Sat Mar 5 12:37:21 2022
By default, the token server only produces logging output when it starts. To obtain more detailed
logging information, start the token server with the -v switch. This will produce a log message
each time a token is checked in or out.
The token server forks off a separate process that runs in the background. Use the -n switch to
run it in the foreground instead.
Firewalls
If you run into trouble accessing the token server, check to see if the server is running firewall
software that is blocking access to some ports. The Gurobi token server uses port number 41954 by
default, so you’ll need to open access to that port on the server. Please consult the documentation
for your firewall software to determine how to do this. If there’s a conflict on the default port, you
can choose a different one by adding a PORT line to both the server and the client license key files:
PORT=46325
You can choose any available port number.
Next steps
Clients of the token server also need simple license files. 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.
To upgrade your token server from an earlier version of the Gurobi Optimizer, you will need to
perform the following steps (on the machine running the token server):
3. Upgrade your license file (or modify GRB_LICENSE_FILE to point to the new license file).
The purpose of a token server client license is quite simple: it tells the client where to find the
Gurobi token server. You can create this file yourself (using a text editor like vim, for example).
The client gurobi.lic file typically contains a single line of text:
TOKENSERVER=mymachine.mydomain.com
15
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 configured to use a non-default port, you’ll also need a line that provides
the port number:
PORT=46325
The client license file may also include a few optional lines. A SERVERTIMEOUT line allows you to
specify the timeout (in seconds) in case the token server is unavailable. The default value is 30
seconds. If the client program is unable to contact the server for more than the specified amount
of time, the client will quit with a network error.
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 file might look like this:
TOKENSERVER=192.168.1.100
SERVERTIMEOUT=10
PASSWORD=abcd1234
We strongly recommend that you place your client gurobi.lic file in a default location for your
platform (either your home directory or /opt/gurobi). Setting up a non-default location is error-
prone 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 file. You just need to add the following line to the gurobi.lic file 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
gurobi.lic file for the client, and to set the GRB_LICENSE_FILE environment variable to point to
this file (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.
16
as a Compute Server. Once you have your key, you will need to start Gurobi Remote Services.
Finally, client machines will need a Compute Server client license in order to find the Compute
Server(s).
Note that if you are setting up a machine as a client of an existing Compute Server, you just need
to create a Compute Server client license.
If you have purchased one or more Gurobi Compute Server licenses, you’ll need to perform a
few setup steps in order to start your Compute Servers. Once started, client machines will be
able to offload the work of solving an optimization model onto these servers. The clients and the
Compute Servers can run any mix of supported operating systems. Thus, for example, multiple
Linux machines could submit jobs to a pair of Compute Servers, one running Windows and the
other running Linux. Any machine that can reach the Compute Server(s) over your network can
be a client (including the Compute Servers themselves).
Once you’ve chosen a machine to act as a Compute Server (or a node in a Compute Server cluster),
you’ll need to run the grbgetkey command on your machine to retrieve your Gurobi license key.
Note that the machine must be connected to the Internet in order to run this command. An
Internet connection is not required after you have obtained your license key.
If your computer isn’t connected to the Internet or if your network security system does not allow
the command below to function, we also offer a manual license key process. You’ll find manual
instructions at the bottom of the License Details page for your license (which can be found by
visiting Current Gurobi Licenses and clicking on the appropriate License ID).
The exact grbgetkey command to run for a specific license is indicated at the bottom of the License
Details page (e.g., grbgetkey 253e22f3-...). We recommend that you use copy-paste to copy
the entire grbgetkey command from our website and paste it into a shell window.
The grbgetkey program passes identifying information about your machine back to our website,
and the website responds with your license key. Once this exchange has occurred, grbgetkey will
ask for the name of the directory in which to store your license key file (gurobi.lic). You should
see a prompt that looks like this:
Gurobi license key client (version 9.5.2)
Copyright (c) 2022, Gurobi Optimization, LLC
–––––––––––––––––––––––––––––––
Contacting Gurobi key server...
–––––––––––––––––––––––––––––––
–––––––––––––––––––––
Saving license key...
–––––––––––––––––––––
17
In which directorywould you like to store the Gurobi license key file?
[hit Enter to store it in /opt/gurobi]:
You can store the license key file anywhere, but we strongly recommend that you accept the default
location (either your home directory or /opt/gurobi) by hitting Enter. Setting up a non-default
location is error-prone and a frequent source of trouble.
When you run the Linux version of the Gurobi Optimizer, it will look for the gurobi.lic key
file in three different default locations: /opt/gurobi, /opt/gurobi952 (for 9.5.2), and your home
directory. If you would like to use a non-default license key file location, you can do so by setting an
environment variable GRB_LICENSE_FILE to point to the license key file. See Setting environment
variables for details on how to do this.
Important note: the environment variable should point to the license key file itself, not to the
directory that contains the file.
Once you have followed the steps above and have obtained a license key file, your next step is to
start Gurobi Remote Services.
If you are a Compute Server user, we recommend that you read the Gurobi Remote Services
Reference Manual for information about configuring and using Remote Services. We’ll provide a
few relevant details here, but this other document provides a much broader overview.
You have two options for indicating that a Gurobi program will act as a client of a Compute Server.
If you are writing a program that calls the Gurobi C, C++, Java, .NET, or Python APIs, these
APIs provide routines that allow you to specify the name of a Compute Server node (by creating an
empty environment and then setting parameters related to Compute Server on that environment).
If you use these routines, Gurobi licenses aren’t required on the client.
Alternately, you can set up a gurobi.lic file that points to the Compute Server. This option
allows you to use a Compute Server with nearly any program that calls Gurobi, without the need
to modify the calling program. You can create your client gurobi.lic with a text editor like vim.
The file should contain a line that looks like this:
COMPUTESERVER=server.mydomain.com:61000
or like this:
COMPUTESERVER=192.168.1.100:61000
This line should provide the name or IP address of any machine in your Compute Server cluster,
optionally followed by the chosen port number on that server (which was chosen when you set up
the Compute Server on that machine). If your Compute Server uses a password, you should also
include a line that gives the password:
18
PASSWORD=cspwd
Please consult the Using Remote Services section of the Gurobi Remote Services Reference Manual
for more information.
Note that if your client and server are both running on the same machine, you’ll need to set the
GRB_LICENSE_FILE environment variable to point to the Compute Server license. You’ll then need
to create a separate gurobi.lic file for the client, and temporarily set the GRB_LICENSE_FILE
environment variable to point to this file (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 Cluster Setup
and Administration section of the Gurobi Remote Services Reference Manual for more information.
Next steps
Once you’ve set up Gurobi Remote Services, you should test the state of the server. Type this
command on your server (assuming you have configured your Compute Server to use port 61000):
gurobi_cl --server=localhost:61000
19
Capacity available on ’localhost:61000’ - connecting...
CLOUDACCESSID=312e9gef-e0bc-4114-b6fb-26ed7klaeff9
CLOUDKEY=ae32L0H321dgaL
If you are using a non-default pool, the file should also indicate the name of that pool:
CLOUDPOOL=myPool
These lines 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 Remote Services Reference Manual
for more information.
20
gurobi>
If you are running as a client of a Gurobi Compute Server, the message above will be preceded by
a message like this:
If you are using the Gurobi Instant Cloud, the message above will be preceded by a message like
this instead:
Congratulations, your license is functioning correctly! You are now ready to use the Gurobi Opti-
mizer. 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.
The following message...
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 file.
If you are running as a client of a Gurobi token server and receive this message:
21
the token server isn’t currently running. If you receive this message:
your license file 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:
the Compute Server isn’t currently running. Please consult the section on setting up a Compute
Server.
If, after following the instructions, you still experience problems while setting up or testing your
license, please visit our support site for assistance.
22
Solving a Simple Model - The Gurobi Command Line
Now that the Gurobi Optimizer is installed and the license key has been tested, you’re ready to
solve a simple math programming model.
This section includes instructions on how to create a simple math programming model and how to
use the Gurobi command-line interface to compute an optimal solution. If you are already familiar
with mathematical modeling and LP-format files, feel free to skip to the end of this section.
Note that this section gives only a brief glimpse into the capabilities of the Gurobi command-line
interface. This interface plays a number of different roles. In addition to providing a simple interface
for solving a model, it can also be used to launch a model on a Compute Server or Gurobi Instant
Cloud, and it can check on the status of a token server. If you’d like additional information, consult
the Command-Line Tool section of our Reference Manual.
Suppose the Mint wants to use the available materials to produce coins with the maximum total
dollar value. Which coins should they produce?
• First, we’ll need to define the decision variables. The goal of the optimization is to choose
values for these variables.
23
• Second, we’ll define a linear objective function. This is the function we’d like to minimize (or
maximize).
• Third, we’ll define the linear constraints.
The Gurobi Optimizer will consider all assignments of values to decision variables that satisfy the
specified 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 coefficients for this equation come from the earlier coin specification 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 reflect 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.
24
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 find this model in file coins.lp in the <installdir>/examples/data directory of your
Gurobi distribution. Specifically, assuming you’ve installed Gurobi 9.5.2 in the recommended loca-
tion, you’ll find the file in /opt/gurobi952/linux64/examples/data/coins.lp.
To modify this file, open it in a text editor (like vim).
Before you consider making any modifications to this file or creating your own, we should point
out a few rules about LP format files.
1. Ordering of the sections
Our example contains an objective section (Maximize...), a constraint section (Subject To...), a
variable bound section (Bounds...), and an integrality section (Integers...). The sections must
come in that order. The complete list of section types and the associated ordering rules can be
found in the file format section of the Gurobi Reference Manual.
2. Separating tokens
Tokens must be separated by either a space or a newline. Thus, for example, the term:
+ .1 Dimes
must include a space or newline between + and .1, and another between .1 and Dimes.
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
25
4. Variable default bounds
Unless stated otherwise, a variable has a zero lower bound and an infinite upper bound. Thus,
Cu <= 1000 really means 0 <= Cu <= 1000. Similarly, any variable not mentioned in the Bounds
section may take any non-negative value.
Full details on the LP file format are provided in the file format section of the Gurobi Reference
Manual.
26
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
Details on the format of the Gurobi log file 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 file once optimization is complete. The type of the file is encoded
in the suffix. To request a .sol file:
The command will produce a file that contains solution values for the variables in the model:
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 different quantities of available minerals), we could use a text editor to modify
the input file. 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.
27
Interactive Shell
The Gurobi interactive shell allows you to perform hands-on interaction and experimentation with
optimization models. You can read models from files, 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 flexible 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 file, you will probably find 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.
28
gurobi> m = read(’/opt/gurobi952/linux64/examples/data/coins.lp’)
Read LP format model from file /opt/gurobi952/linux64/examples/data/coins.lp
Reading time = 0.01 seconds
: 4 rows, 9 columns, 16 nonzeros
gurobi> m.optimize()
Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
Optimize a model with 4 rows, 9 columns and 16 nonzeros
Model fingerprint: 0x06e334a4
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.0000000
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)
The read() command reads a model from a file and returns a Model object. In the example, that
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(’/opt/gurobi952/linux64/*/*/coin*’)
Note also that Gurobi commands that read or write files will also function correctly with compressed
files. If gzip, bzip2, or 7zip are installed on your machine and available in your default path, then
you simply need to add the appropriate suffix (.gz, .bz2, .zip, or .7z) to the file 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 node log generated by the optimize() call shows the progress of the optimization. The most
29
prominent measurements of progress are the Incumbent and BestBd values, which track the best
solution found so far, and the bound on the best possible solution. For more details on the node
log, refer to the MIP Logging section in the Gurobi Reference Manual. The Gurobi optimization
engine finds an optimal solution with objective 113.45.
gurobi> m.printAttr(’X’)
Variable X
-------------------------
Dimes 2
Quarters 53
Dollars 100
Cu 999.8
Ni 46.9
Zi 50
Mn 30
This routine prints all non-zero values of the specified 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 finer 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 first 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 first variable in list v, you would issue the following command:
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.
30
gurobi> v = m.getVars()
gurobi> v[0].lb = 10
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 modified model. When you invoke the optimize()
method again, it performs a new optimization on the modified model...
gurobi> m.optimize()
Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
Optimize a model with 4 rows, 9 columns and 16 nonzeros
Model fingerprint: 0xa40e053a
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 from previous solve did not produce a new incumbent solution
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 confirms that the new
lower bound is respected:
gurobi> print(v[0].x)
10.0
31
gurobi> m = read(’/opt/gurobi952/linux64/examples/data/glass4’)
Read MPS format model from file /opt/gurobi952/linux64/examples/data/glass4.mps
Reading time = 0.00 seconds
glass4: 396 Rows, 322 Columns, 1815 NonZeros
gurobi> m.optimize()
Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
Optimize a model with 396 rows, 322 columns and 1815 nonzeros
Model fingerprint: 0x18b19fdf
Variable types: 20 continuous, 302 integer (0 binary)
Coefficient statistics:
Matrix range [1e+00, 8e+06]
Objective range [1e+00, 1e+06]
Bounds range [1e+00, 8e+02]
RHS range [1e+00, 8e+06]
Presolve removed 4 rows and 5 columns
Presolve time: 0.00s
Presolved: 392 rows, 317 columns, 1815 nonzeros
Variable types: 19 continuous, 298 integer (298 binary)
Found heuristic solution: objective 3.133356e+09
Cutting planes:
32
Gomory: 8
Implied bound: 13
Projected implied bound: 1
MIR: 19
Flow cover: 17
Zero half: 1
RLT: 4
Relax-and-lift: 17
Solve interrupted
Best objective 1.500012666667e+09, best bound 1.000006945369e+09, gap 33.3334%
It quickly becomes apparent that this model is quite a bit more difficult than the earlier coins
model. The optimal solution is actually 1,200,000,000, but finding that solution takes a while.
After letting the model run for 15 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.
Changing parameters
Rather than continuing optimization on a difficult model like glass4, it is sometimes useful to try
different 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 finding good
feasible solutions. There are two ways to change the parameter value. You can either use method
m.setParam():
gurobi> m.setParam(’MIPFocus’, 1)
Set parameter MIPFocus to value 1
gurobi> m.Params.MIPFocus = 1
Set parameter MIPFocus to value 1
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()
Discarded solution information
gurobi> m.optimize()
Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
Optimize a model with 396 rows, 322 columns and 1815 nonzeros
Model fingerprint: 0x541d0ad3
Variable types: 20 continuous, 302 integer (0 binary)
Coefficient statistics:
Matrix range [1e+00, 8e+06]
33
Objective range [1e+00, 1e+06]
Bounds range [1e+00, 8e+02]
RHS range [1e+00, 8e+06]
Presolve removed 4 rows and 5 columns
Presolve time: 0.00s
Presolved: 392 rows, 317 columns, 1815 nonzeros
Variable types: 19 continuous, 298 integer (298 binary)
Found heuristic solution: objective 3.133356e+09
Cutting planes:
Gomory: 37
Cover: 9
Implied bound: 41
MIR: 51
34
Flow cover: 266
RLT: 107
Relax-and-lift: 99
Solve interrupted
Best objective 1.200012600000e+09, best bound 8.000066838804e+08, gap 33.3335%
Results are consistent with our expectations. We find a better solution sooner by shifting the focus
towards finding feasible solutions (objective value 1.2e9 versus 1.5e9).
The setParam() method is designed to be quite flexible and forgiving. It accepts wildcards as
arguments, and it ignores character case. Thus, the following commands are all equivalent:
gurobi> m.setParam(’*Cuts’, 2)
Matching parameters: [’Cuts’, ’CliqueCuts’, ’CoverCuts’, ’FlowCoverCuts’,
’FlowPathCuts’, ’GUBCoverCuts’, ’ImpliedCuts’, ’MIPSepCuts’, ’MIRCuts’, ’ModKCuts’,
’NetworkCuts’, ’SubMIPCuts’, ’ZeroHalfCuts’]
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 specific parameter (e.g., MIPGap) by typing paramHelp(’MIPGap’).
35
Baseline parameter set: mean runtime 1.48s
FlowCoverCuts 1
Aggregate 0
MIPFocus 1
In this case, it found that setting the MIPFocus parameter to 1 for model misc07 reduced the
runtime from 1.48 to 1.22.
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 find that performance problems can’t be fixed with
parameter changes alone, particularly if your model has severe numerical issues.
Tuning is also available as a standalone program. From a command prompt, you can type:
> grbtune /opt/gurobi952/linux64/examples/data/p0033
Please consult the Automated Tuning Tool section of the Gurobi Reference Manual for more infor-
mation.
36
Read LP format model from file coins.lp
Reading time = 0.00 seconds
: 4 rows, 9 columns, 16 nonzeros
Optimize a model with 4 rows, 9 columns and 16 nonzeros
Model fingerprint: 0x06e334a4
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.0000000
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)
would read the new value of the Threads parameter from 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 tool), the value from gurobi.env will be
overridden.
A few parameters can only be used from the Gurobi command-line tool, and thus can’t be set
through gurobi.env. These parameters are labeled ’Command-line only’ in the Parameter section
of the Gurobi Reference Manual.
37
Read MPS format model from file /opt/gurobi952/linux64/examples/data/stein9.mps
Reading time = 0.00 seconds
STEIN9: 13 Rows, 9 Columns, 45 NonZeros.
The models() command gives a list of all active models.
gurobi> models()
Currently loaded models:
a : <gurobi.Model MIP instance P0033: 16 constrs, 33 vars, Parameter changes: LogFile=gurobi.log>
b : <gurobi.Model MIP instance STEIN9: 13 constrs, 9 vars, Parameter changes: LogFile=gurobi.log>
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 inter-
face. 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 ob-
jects. 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> m = myread(’stein9’)
Read MPS format model from file /home/john/models/stein9.mps
If you don’t want to type this function in each time you start the Gurobi shell, you can store it in
a file. The file would look like the following:
38
from gurobipy import *
def myread(filename):
return read(’/home/john/models/’+filename)
The from gurobipy import * line allows you to use the read method from the Gurobi shell in
your custom function. The name of your customization file must end with a .py suffix. If the file
is named custom.py, you would then type the following to import this function:
One file 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 file 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 define your own custom opti-
mize method that always invokes the callback:
def myopt(model):
model.optimize(mycallback)
39
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 modified 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 modification 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:
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 modification
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.
40
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 + 2y + 3z ≤ 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)...
/* Copyright 2022 , Gurobi Optimization , LLC */
/* This example formulates and solves the following simple MIP model :
maximize x + y + 2 z
subject to x + 2 y + 3 z <= 4
x + y >= 1
x, y, z binary
*/
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 ;
41
double objval ;
/* Create environment */
error = GRBemptyenv (& env );
if ( error ) goto QUIT ;
error = GRBsetstrparam ( env , " LogFile " , " mip1 . log " );
if ( error ) goto QUIT ;
/* Add variables */
obj [0] = 1; obj [1] = 1; obj [2] = 2;
vtype [0] = GRB_BINARY ; vtype [1] = GRB_BINARY ; vtype [2] = GRB_BINARY ;
error = GRBaddvars ( model , 3 , 0 , NULL , NULL , NULL , obj , NULL , NULL , vtype ,
NULL );
if ( error ) goto QUIT ;
/* Optimize model */
error = GRBoptimize ( model );
if ( error ) goto QUIT ;
42
error = GRBgetdblattrarray ( model , GRB_DBL_ATTR_X , 0 , 3 , sol );
if ( error ) goto QUIT ;
printf ( " x =%.0 f , y =%.0 f , z =%.0 f \ 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 */
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 files. Gurobi C applications should always start by
including gurobi_c.h, along with the standard C include files (stdlib.h and stdio.h).
/* Create environment */
error = GRBemptyenv (& env );
if ( error ) goto QUIT ;
43
error = GRBsetstrparam ( env , " LogFile " , " mip1 . log " );
if ( error ) goto QUIT ;
Later requests to create optimization models will always require an active environment, so envi-
ronment creation should always be the first step when using the Gurobi optimizer.
Note that environment creation may fail, so you should check the return value of the call.
The first 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
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.
/* Add variables */
obj [0] = 1; obj [1] = 1; obj [2] = 2;
vtype [0] = GRB_BINARY ; vtype [1] = GRB_BINARY ; vtype [2] = GRB_BINARY ;
error = GRBaddvars ( model , 3 , 0 , NULL , NULL , NULL , obj , NULL , NULL , vtype ,
NULL );
if ( error ) goto QUIT ;
The first 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 coefficients associated with the new
variables. The third argument gives the number of non-zero constraint matrix entries associated
44
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 coefficient for each new variable.
Since our example aims to maximize the objective, and by default Gurobi will minimize the ob-
jective, we’ll need to change the objective sense. This is done in the next statement. Note we
could have multiplied the objective coefficients 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 specifies the types of the variables. In this example, the variables are all binary
(GRB_BINARY).
The final argument gives the names of the variables. In this case, we allow the variable names to
take their default values (x0, x1, and x2).
The first argument of GRBaddconstr() is the model to which the constraint is being added. The
second is the total number of non-zero coefficients associated with the new constraint. The next
two arguments describe the non-zeros in the new constraint. Constraint coefficients are specified
45
using a list of index-value pairs, one for each non-zero value. In our example, the first constraint to
be added is x + 2y + 3z ≤ 4. We have chosen to make x the first 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 first constraint are (0, 1.0), (1, 2.0), and (2, 3.0).
These pairs are placed in the ind and val arrays.
The fifth 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 final 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.
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 significant
advantages, so we recommend that you add one constraint at a time.
/* Optimize model */
error = GRBoptimize ( model );
if ( error ) goto QUIT ;
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...
The optimization status has many possible values. An optimal solution to the model may have been
found, or the model may 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 modified 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:
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:
46
error = GRBgetdblattrarray ( model , GRB_DBL_ATTR_X , 0 , 3 , sol );
if ( error ) goto QUIT ;
This routine retrieves the values of an array-valued attribute. The third and fourth arguments
indicate the index of the first 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.
While you may want to print a specialized error code at each point where an error may occur,
the Gurobi interface provides a more flexible facility for reporting errors. The GRBgeterrormsg()
routine returns a textual description of the most recent error associated with an environment:
/* Error reporting */
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).
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 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 + 2y + 3z ≤ 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)...
/* Copyright 2022 , Gurobi Optimization , LLC */
/* This example formulates and solves the following simple MIP model :
maximize x + y + 2 z
subject to x + 2 y + 3 z <= 4
x + y >= 1
x, y, z binary
*/
int
main ( int argc ,
char * argv [])
{
try {
// Create an environment
GRBEnv env = GRBEnv ( true );
env . set ( " LogFile " , " mip1 . log " );
env . start ();
48
// Create an empty model
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 " );
// Optimize model
model . optimize ();
cout << " Obj : " << model . get ( G RB_Do uble Attr _ObjV al ) << endl ;
} catch ( GRBException e ) {
cout << " Error code = " << e . getErrorCode () << endl ;
cout << e . getMessage () << endl ;
} catch (...) {
cout << " Exception during optimization " << endl ;
}
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 file gurobi_c++.h. Gurobi C++ applications should always start
by including this file.
49
// Create an environment
GRBEnv env = GRBEnv ( true );
env . set ( " LogFile " , " mip1 . log " );
env . start ();
In this call we requested an empty environment, choose a log file, and started the environment.
Later calls to create an optimization model will always require an environment, so environment
creation is typically the first step in a Gurobi application.
// 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 " );
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 first and second arguments to the addVar() call are the variable lower and upper bounds,
respectively. The third argument is the linear objective coefficient (zero here - we’ll set the objective
later). The fourth argument is the variable type. Our variables are all binary in this example. The
final argument is the name of the variable.
The addVar() method has been overloaded to accept several different argument lists. Please refer
to the Gurobi Reference Manual for further details.
50
// Set objective : maximize x + y + 2 z
model . setObjective ( x + y + 2 * z , GRB_MAXIMIZE );
The objective is built here using overloaded operators. The C++ API overloads the arithmetic
operators to allow you to build linear and quadratic 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:
As with variables, constraints are always associated with a specific model. They are created using
the addConstr() or addConstrs() methods on the model object.
We again use overloaded arithmetic operators to build 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:
// Optimize model
model . optimize ();
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
51
Reporting results - attributes
Once the optimization is complete, we can query the values of the attributes. In particular, we can
query the VarName and X attributes to obtain the name and solution value of each variable:
We can also query the ObjVal attribute on the model to obtain the objective value for the current
solution:
cout << " Obj : " << model . get ( G RB_Do uble Attr _ObjV al ) << 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:
} catch ( GRBException e ) {
cout << " Error code = " << e . getErrorCode () << endl ;
cout << e . getMessage () << endl ;
} catch (...) {
cout << " Exception during optimization " << endl ;
}
• A C++ program that uses Gurobi must link in both the Gurobi C++ library libgurobi_c++.a
and the Gurobi C library libgurobi95.so.
• The Gurobi Linux distribution includes multiple C++ libraries. You may need to choose
an alternate version (e.g., libgurobi_g++5.2.a), depending on the version of g++ you are
using. You should consult the supported platform list for additional information.
52
The C++ example directory <installdir>/examples/c++ contains a number of examples. We
encourage you to browse and modify them in order to become more familiar with the Gurobi C++
interface. We also encourage you to read the Gurobi Example Tour for more information.
53
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).
If you are using an integrated development environment like Eclipse R , we recommend that you
import the file <installdir>/lib/gurobi-javadoc.jar, which contains Javadoc documentation
for the Gurobi Java interface.
Our example optimizes the following model:
maximize x + y + 2z
subject to x + 2y + 3z ≤ 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)...
/* Copyright 2022 , Gurobi Optimization , LLC */
/* This example formulates and solves the following simple MIP model :
maximize x + y + 2 z
subject to x + 2 y + 3 z <= 4
x + y >= 1
x, y, z binary
*/
54
// Create empty model
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 " );
// Optimize model
model . optimize ();
System . out . println ( " Obj : " + model . get ( GRB . DoubleAttr . ObjVal ));
} 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
55
should always start with this line.
In this call we requested an empty environment, chose a log file, and started the environment.
Later calls to create an optimization model will always require an environment, so environment
creation is typically the first step in a Gurobi application.
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 first and second arguments to the addVar() call are the variable lower and upper bounds,
respectively. The third argument is the linear objective coefficient (zero here - we’ll set the objective
later). The fourth argument is the variable type. Our variables are all binary in this example. The
final argument is the name of the variable.
The addVar() method has been overloaded to accept several different argument lists. Please refer
to the Gurobi Reference Manual for further details.
56
Setting the objective
The next step in the example is to set the optimization objective:
// 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 );
The objective must be a linear or quadratic function of the variables in the model. In our example,
we build our objective by first 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 specific model. They are created using
the addConstr() or addConstrs() methods on the model object.
The first argument to addConstr() is the left-hand side of the constraint. We built the left-hand
side by first 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 final 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 " );
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
57
Reporting results - attributes
Once the optimization is complete, we can query the values of the attributes. In particular, we can
query the VarName and X attributes to obtain the name and solution value for each variable:
System . out . println ( x . get ( GRB . StringAttr . VarName )
+ " " + x . get ( GRB . DoubleAttr . X ));
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:
// Dispose of model and environment
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 opti-
mization, 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 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:
} catch ( GRBException e ) {
System . out . println ( " Error code : " + e . getErrorCode () + " . " +
e . getMessage ());
}
58
The Java example directory <installdir>/examples/java contains a number of examples. We
encourage you to browse and modify them in order to become more familiar with the Gurobi Java
interface. We also encourage you to read the Gurobi Example Tour for more information.
59
.NET Interface (C#)
This section assumes that you are already familiar with the C# programming language. If not, a
variety of books and websites are available for learning the language (for example, the Microsoft
online C# documentation).
While C# programs have historically only run on Windows machines, Microsoft has recently re-
leased an open-source, cross-platform .NET implementation (.NET Core) that allows you to run
C# programs on Linux and macOS as well. You will find the Gurobi library that supports .NET
Core 2 in <installdir>/lib/gurobi95.netstandard20.dll. For more information on how to
obtain and use .NET Core, please refer to the .NET Tutorial.
We will work through a simple C# example in order to illustrate the use of the Gurobi .NET
interface. The example builds a model, optimizes it, and outputs the optimal objective value.
Our example optimizes the following model:
maximize x + y + 2z
subject to x + 2y + 3z ≤ 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_cs.cs
This is the complete source code for our example (also available in
<installdir>/examples/c#/mip1_cs.cs)...
/* Copyright 2022 , Gurobi Optimization , LLC */
/* This example formulates and solves the following simple MIP model :
maximize x + y + 2 z
subject to x + 2 y + 3 z <= 4
x + y >= 1
x, y, z binary
*/
using System ;
using Gurobi ;
class mip1_cs
{
static void Main ()
{
60
try {
// 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 " );
// Optimize model
model . Optimize ();
} 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 applica-
tions should always start with this line.
61
Creating the environment
The first executable statement in our example obtains a Gurobi environment (using the GRBEnv()
constructor):
In this case, we create an empty environment, select a log file to use, and start the environment for
latter use.
Later calls to create an optimization model will always require an active environment, so environ-
ment creation is typically the first step in a Gurobi application.
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 first and second arguments to the AddVar() call are the variable lower and upper bounds,
respectively. The third argument is the linear objective coefficient (zero here - we’ll set the objective
later). The fourth argument is the variable type. Our variables are all binary in this example. The
final argument is the name of the variable.
The AddVar() method has been overloaded to accept several different argument lists. Please refer
to the Gurobi Reference Manual for further details.
62
Setting the objective
The next step in the example is to set the optimization objective:
// Set objective : maximize x + y + 2 z
model . SetObjective ( x + y + 2 * z , GRB . MAXIMIZE );
The objective is built here using overloaded operators. The C# API overloads the arithmetic
operators to allow you to build linear and quadratic 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:
As with variables, constraints are always associated with a specific model. They are created using
the AddConstr() or AddConstrs() methods on the model object.
We again use overloaded arithmetic operators to build linear expressions. The comparison operators
are also overloaded to make it 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:
This particular AddConstr() signature takes a linear expression that captures the left-hand side of
the constraint as its first argument, the sense of the constraint as its second argument, and a linear
expression that captures the right-hand side of the constraint as its third argument. The constraint
name is given as the fourth argument.
63
Optimizing the model
Now that the model has been built, the next step is to optimize it:
// Optimize model
model . Optimize ();
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
We can also query the ObjVal attribute on the model to obtain the objective value for the current
solution:
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:
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 opti-
mization, 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:
64
} catch ( GRBException e ) {
Console . WriteLine ( " Error code : " + e . ErrorCode + " . " + e . Message );
}
65
Python
Gurobi comes with a Python extension module called “gurobipy” that offers convenient object-
oriented modeling constructs and an API to all Gurobi features. The Gurobi distribution also
includes a Python interpreter and a basic set of Python modules (see the interactive shell), which
are sufficient to build and run simple optimization models. You can also install gurobipy into
an existing Python installation or virtual environment (https://docs.python.org/3/library/
venv.html).
In this section, we will first review installation options. We then point out some useful Python
tools and their installation. Finally, we introduce you to the basic usage of gurobipy by means of
a few concrete examples.
Most Python installations come with the Python package management system “pip”. You can use
pip to download and install the gurobipy extension simply by opening a terminal window and
issuing the following command:
python -m pip install gurobipy
This command instructs the called Python interpreter to download gurobipy from the public PyPI
server (https://pypi.org) and install it into your Python environment. Note that our gurobipy
installation package is self-contained, so you can use it without any other software installation
steps.
After the installation succeeds, you should see gurobipy among the installed packages listed upon
typing python -m pip list. For example:
66
Package Version
------------------- -----------
gurobipy 9.5.0
pip 20.2.1
setuptools 49.2.1
Our pip package includes a limited license that allows you to solve small optimization problems. If
are an academic user, you can obtain a free, unlimited academic license from our website. Otherwise,
you can obtain a free evaluation license by contacting [email protected].
Manual installation
If you don’t have internet access, or if you prefer to install the gurobipy extension manually, you
can use the installation script provided with the Gurobi installation package. Assuming you have
already completed the Gurobi installation instructions, your installation directory (referred to as
<installdir>) will contain a file setup.py. In order to run this installation script, you will need
to open a terminal window, change your current directory to the Gurobi <installdir>, and issue
the following command:
python setup.py install
Ensure that you have write permissions within this Python installation. You may need to install
the distutils package before running this command.
Once gurobipy is successfully installed, you can type import gurobipy as gp or from gurobipy
import * from your Python shell and access all of the gurobipy classes and methods.
Anaconda is a Python distribution platform that comes with a convenient package manager (“conda”),
and a diverse set of curated software packages. Gurobi offers an installation package for this plat-
form too. We will briefly explain the steps needed to install Anaconda and the Gurobi conda
package. Note that the conda package installs more than just gurobipy. For example, it will also
install the Gurobi command line tool gurobi_cl, some other tools, and documentation.
If you have already installed Anaconda, you may skip directly to step 2 below.
The first step is to download and install Anaconda. You can find detailed instructions here. Be
sure to check the box Add Anaconda to my PATH environment variable when prompted during
the installation process. Otherwise, Step 2 may not work.
67
Gurobi supports the 64-bit x86 version of Python 3.8. Once the download has completed, issue the
following command in the directory where you have stored the downloaded file:
bash Anaconda3-2020.07-Linux-x86_64.sh
Once the install is complete, and once you close your current terminal and open a new one, typing
python in your terminal window should invoke the Anaconda Python interpreter:
>python
Python 3.8.4 |Anaconda, Inc.|...
...
The next step is to install the Gurobi package into Anaconda. You do this by first adding the Gurobi
channel to your Anaconda channels and then installing the gurobi package from this channel.
From a terminal window issue the following command to add the Gurobi channel to your default
search list
conda config --add channels https://conda.anaconda.org/gurobi
You can remove the Gurobi package at any time by issuing the command
conda remove gurobi
68
12.2 Python Tools
A great productivity feature of the whole Python ecosystem is the availability and accessibility of
tools such as interactive notebooks and integrated development environments. In this section we
will briefly discuss two such tools, “Jupyter Notebook” and the “Spyder” IDE. Of course the latter
is not your only IDE choice. Other popular alternatives include Eric, Pyzo, PyCharm, and PyDev.
Jupyter Notebook
Jupyter Notebook is an open source web application that allows you to create interactive Python
documents. Distributions like Anaconda ship with Jupyter Notebook by default. To start Jupyter,
simply type jupyter-notebook in a terminal window.
If your Python environment doesn’t have Jupyter Notebook installed, you should be able to install
it via the command python -m pip install jupyter.
You can create a new notebook by clicking on the New icon (in the upper right) and choosing one of
the Notebook options. Once your new notebook starts, you can type standard Python commands
or Gurobi Interactive Shell commands directly into the In window:
69
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.
70
The Spyder IDE
To launch the Spyder Python IDE, which is included in the Anaconda distribution, simply type
spyder in a terminal window. Gurobi Interactive Shell commands can be typed directly into the
Spyder Console window:
If your Python environment doesn’t have Spyder installed, you should be able to install it via the
command python -m pip install spyder.
Note that a general-purpose Python IDE like Spyder requires one extra step to use Gurobi that
isn’t required when you launch the Gurobi shell from the gurobi.sh command: you must manually
load the Gurobi module by typing from gurobipy import * (or import gurobipy as gp) 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:
71
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 file sudoku1 as input ...
72
12.3 gurobipy, the Gurobi 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, with gurobipy among them. There are also a number of options for installing
gurobipy in your Python environment of choice.
When comparing our Python interface against our other language interfaces, you will find that our
Python interface provides a lot more options for building a model. You can work with individual
variables and constraints, like you do in other object-oriented interfaces, or you can work with
matrices, like you do in our matrix-oriented interfaces. Our Python interface also includes 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.
73
This section will work through three Python modeling examples. The first will present a Python
program that is similar to the C, C++, Java, and C# programs presented in previous sections. The
second shows how to build models using matrices. The third 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.
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.
maximize x + y + 2z
subject to x + 2y + 3z ≤ 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.py
This is the complete source code for our example (also available in
<installdir>/examples/python/mip1.py)...
# !/ usr / bin / env python3 .7
# This example formulates and solves the following simple MIP model :
# maximize
# x + y + 2 z
# subject to
# x + 2 y + 3 z <= 4
# x + y >= 1
# x, y, z binary
import gurobipy as gp
from gurobipy import GRB
74
try :
# Create variables
x = m . addVar ( vtype = GRB . BINARY , name = " x " )
y = m . addVar ( vtype = GRB . BINARY , name = " y " )
z = m . addVar ( vtype = GRB . BINARY , name = " z " )
# Set objective
m . setObjective ( x + y + 2 * z , GRB . MAXIMIZE )
# Optimize model
m . optimize ()
except gp . GurobiError as e :
print ( ’ Error code ’ + str ( e . errno ) + ’: ’ + str ( e ))
except AttributeError :
print ( ’ Encountered an attribute error ’)
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 Gurobi functions and classes:
import gurobipy as gp
from gurobipy import GRB
The first line makes all Gurobi functions and classes available through a gp. prefix (e.g., gp.Model()).
The second makes everything in class GRB available without a prefix (e.g., GRB.OPTIMAL). You can
also start a program with from gurobipy import * to remove the need for the gp. prefix, but if
your program uses multiple Python modules it is usually preferred to access each through its own
prefix.
In order for these commands to succeed, the Python application needs to know how to find the
Gurobi functions and classes. Recall that you have three options for installing them.
75
Creating the model
The first step in our example is to create a model. A Gurobi model holds a single optimization
problem. It consists of a set of variables, a set of constraints, and the associated attributes (variable
bounds, objective coefficients, variable integrality types, constraint senses, constraint right-hand
side values, etc.). We start this example with an empty model object:
# Create a new model
m = gp . Model ( " mip1 " )
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.
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);
The next step in the example is to add the linear constraints. The first constraint is added here:
76
# Add constraint : x + 2 y + 3 z <= 4
m . addConstr ( x + 2 * y + 3 * z <= 4 , " c0 " )
As with variables, constraints are always associated with a specific 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 " )
Now that the model has been built, the next step is to optimize it:
# Optimize model
m . optimize ()
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
Once the optimization is complete, we can query the values of the attributes. In particular, we
can query the varName and x variable attributes to obtain the name and solution value for each
variable:
We can also query the objVal attribute on the model to obtain the objective value for the current
solution:
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.
Cleaning up
In our other interfaces, we encourage you to explicitly dispose of your Gurobi environment when
you are done using it in order to release the associated resources. Our recommendation in the
Python interface is a bit more nuanced.
Most Gurobi Python programs use the default environment, which is automatically created when
you first construct a Gurobi Model object and automatically disposed when your program ends.
77
You can call disposeDefaultEnv() to dispose of it manually, but if you want detailed control of
environments (for example, if you are using a Compute Server or the Gurobi Instant Cloud), we
recommend that you work with explicit environment objects instead.
Please refer to the mip1_remote.py example for details on how you would do this.
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:
except gp . GurobiError as e :
print ( ’ Error code ’ + str ( e . errno ) + ’: ’ + str ( e ))
except AttributeError :
print ( ’ Encountered an attribute error ’)
When you run the example gurobi.sh mip1.py, you should see the following output:
Using license file /opt/gurobi/gurobi.lic
Solution count 2: 3
78
12.5 Python Matrix Example
You can also build optimization models in Python using dense and sparse matrices, much like you
would in our MATLAB and R interfaces. We’ll show an example that works through the same
simple model from the first part of this section:
maximize x + y + 2z
subject to x + 2y + 3z ≤ 4
x + y ≥ 1
x, y, z binary
Example matrix1.py
This is the complete source code for our example (also available in
<installdir>/examples/python/matrix1.py)...
# !/ usr / bin / env python3 .7
# This example formulates and solves the following simple MIP model
# using the matrix API :
# maximize
# x + y + 2 z
# subject to
# x + 2 y + 3 z <= 4
# x + y >= 1
# x , y , z binary
import gurobipy as gp
from gurobipy import GRB
import numpy as np
import scipy . sparse as sp
try :
# Create variables
x = m . addMVar ( shape =3 , vtype = GRB . BINARY , name = " x " )
# Set objective
obj = np . array ([1.0 , 1.0 , 2.0])
m . setObjective ( obj @ x , GRB . MAXIMIZE )
79
# Build rhs vector
rhs = np . array ([4.0 , -1.0])
# Add constraints
m . addConstr ( A @ x <= rhs , name = " c " )
# Optimize model
m . optimize ()
print ( x . X )
print ( ’ Obj : % g ’ % m . ObjVal )
except gp . GurobiError as e :
print ( ’ Error code ’ + str ( e . errno ) + " : " + str ( e ))
except AttributeError :
print ( ’ Encountered an attribute error ’)
You will need to have both the NumPy package and the SciPy sparse matrix package in your Python
environment to run this example. The easiest ways to obtain a suitable Python environment is to
install the Anaconda Python distribution, or to install these packages in your Python environment
through python -m pip install numpy scipy.
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, as well as the NumPy and
SciPy packages:
import gurobipy as gp
from gurobipy import GRB
import numpy as np
import scipy . sparse as sp
Gurobi Python applications should always start with the first two lines. If you want to use the
matrix interface, the last two lines are needed as well.
The first step in our example is to create a model. We start with an empty model object:
# Create a new model
m = gp . Model ( " matrix1 " )
80
# Create variables
x = m . addMVar ( shape =3 , vtype = GRB . BINARY , name = " x " )
A matrix variable is added through the addMVar() method on a model object. In this case the
matrix variable consists of a 1-D array of 3 binary variables. Variables are always associated with
a particular model.
The objective is built here by computing a dot product between a constant vector and our matrix
variable using the overloaded @ operator. Note that the constant vector must have the same length
as our matrix variable.
The second argument indicates that the sense is maximization.
The next step in the example is to add our two linear constraints. This is done by building a sparse
matrix that captures the constraint matrix:
# Build ( sparse ) constraint matrix
val = np . array ([1.0 , 2.0 , 3.0 , -1.0 , -1.0])
row = np . array ([0 , 0 , 0 , 1 , 1])
col = np . array ([0 , 1 , 2 , 0 , 1])
The matrix has two rows, one for each constraint, and three columns, one for each variable in our
matrix variable. The row and col arrays gives the row and column indices for the 5 non-zero values
in the sparse matrix, respectively. The val array gives the numerical values. Note that we multiply
the greater-than constraint by −1 to transform it to a less-than constraint.
We also capture the right-hand side in a NumPy array:
# Build rhs vector
rhs = np . array ([4.0 , -1.0])
We then use the overloaded @ operator to build a linear matrix expression, and then use the
overloaded less-than-or-equal operator to add two constraints (one for each row in the matrix
expression):
# Add constraints
m . addConstr ( A @ x <= rhs , name = " c " )
81
Optimizing the model
Now that the model has been built, the next step is to optimize it:
# Optimize model
m . optimize ()
This routine performs the optimization and populates several internal model attributes (including
the status of the optimization, the solution, etc.).
Once the optimization is complete, we can query the values of the attributes. In particular, we can
query the X variable attributes to obtain the solution value for each variable:
print ( x . X )
We can also query the objVal attribute on the model to obtain the objective value for the current
solution:
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:
except gp . GurobiError as e :
print ( ’ Error code ’ + str ( e . errno ) + " : " + str ( e ))
except AttributeError :
print ( ’ Encountered an attribute error ’)
When you run the example gurobi.sh matrix1.py, you should see the following output:
Using license file /opt/gurobi/gurobi.lic
82
RHS range [1e+00, 4e+00]
Found heuristic solution: objective 2.0000000
Presolve removed 2 rows and 3 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Solution count 2: 3
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 flow of multiple different commodities through
a supply network. You might have a variable x[’Pens’, ’Denver’, ’New York’] that captures
the flow 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
83
cumbersome.
To compound the challenge, you typically need to build constraints that involve subsets of these
decision variables. For example, in our network flow model you might want to put an upper bound
on the total flow 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
flow from that source city into the desired destination city. However, this is clearly wasteful if not all
origin-destination pairs are valid. In a large network problem, the inefficiency of this approach could
lead to major performance issues. Handling this efficiently 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 specific 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.
The list data structure is central to most Python programs; Gurobi Python programs are no
exception. We’ll also rely heavily on a similar data structure, the tuple. Tuples are crucial to
providing efficient and convenient access to Gurobi decision variables in Gurobi Python programs.
The difference between a list and a tuple is subtle but important. We’ll discuss it shortly.
Lists and tuples are both just ordered collections of Python objects. A list is created and dis-
played as a comma-separated list of member objects, enclosed in square brackets. A tuple is
similar, except that the member objects are enclosed in parenthesis. For example, [1, 2, 3] is
a list, while (1, 2, 3) is a tuple. Similarly, [’Pens’, ’Denver’, ’New York’] is a list, while
(’Pens’, ’Denver’, ’New York’) is a tuple.
You can retrieve individual entries from a list or tuple using square brackets and zero-based indices:
What’s the difference 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.
84
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 floating-point number, a string, or even a tuple.
To give an example, the following statements create a dictionary x, and then associates a value 1
with key (’Pens’, ’Denver’, ’New York’)
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 partic-
ular, they can hold Gurobi decision variables:
To initialize a dictionary, you can of course simply perform assignments for each relevant key:
gurobi> values = {}
gurobi> values[’zero’] = 0
gurobi> values[’one’] = 1
gurobi> values[’two’] = 2
We have included a utility routine in the Gurobi Python interface that simplifies dictionary initial-
ization 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
first result is the list of shared key values, followed by the n individual dictionaries:
gurobi> names, lower, upper = multidict({ ’x’: [0, 1], ’y’: [1, 2], ’z’: [0, 3] })
gurobi> print(names)
[’x’, ’y’, ’z’]
85
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 first result, and the original dictionary
as the second.
You will see this function in several of our Python examples.
List comprehension and generator expressions are important Python features that allows you to do
implicit enumeration in a concise fashion. To give a simple example, the following list comprehen-
sion builds a list containing the squares of the numbers from 1 through 5:
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 efficient to use a generator expression:
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:
Note that the for statements are executed left-to-right, and values from one can be used in the
next, so a more efficient way to write the above is:
Generator expressions are used extensively in our Python examples, primarily in the context of the
addConstrs method.
86
The tuplelist class
The next important item we would like to discuss is the tuplelist class. This is a custom sub-class
of the Python list class that is designed to allow you to efficiently build sub-lists from a list of
tuples. To be more specific, you can use the select method on a tuplelist object to retrieve all
tuples that match one or more specified values in specific fields.
Let us give a simple example. We’ll begin by creating a simple tuplelist (by passing a list of
tuples to the constructor):
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 can provide a list argument to indicate that multiple values are acceptable in that
position in the tuple, or a ’*’ string to indicate that any value is acceptable.
Each tuple in our example contains two entries, so we can perform the following selections:
You may have noticed that similar results could have been achieved using list comprehension. For
example:
87
>
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
inefficient for large lists. The select method builds internal data structures that make these
selections quite efficient.
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 )
>
The final important preliminary we would like to discuss is the tupledict class. This is a custom
sub-class of the Python dict class that allows you to efficiently work with subsets of Gurobi variable
objects. To be more specific, you can use the sum and prod methods on a tupledict object to
easily and concisely build linear expressions. The keys for a tupledict are stored as a tuplelist,
so the same select syntax can be used to choose subsets of entries. Specifically, by associating
a tuple with each Gurobi variable, you can efficiently create expressions that contain a subset of
matching variables. For example, using the sum method on a tupledict object, you could easily
build an expression that captures the sum over all Gurobi variables for which the first field of the
corresponding tuple is equal to 3 (using x.sum(3, ’*’)).
While you can directly build your own tupledict, the Gurobi interface provides an addVars method
that adds one Gurobi decision variable to the model for each tuple in the input argument(s) and
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:
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 prefix for the name
- the names are subscripted by the tuple keys (so the variables would be named d[1,2], d[1,3],
etc.). The final call to update synchronizes certain internal data structures; this detail can be
safely ignored for now.
You can then use this tupledict to build linear expressions. For example, you could do:
88
gurobi> sum(d.select(1, ’*’))
The select method returns a list of Gurobi variables where the first field 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 simplifies 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
coefficients that aren’t all 1.0. Coefficients 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 filter, 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,4]>])
In our upcoming network flow 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 flow on all arcs that empty into a specific
destination city as follows:
We now present an example that illustrates the use of all of the concepts discussed so far.
netflow.py example
Our example solves a multi-commodity flow 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 per-unit cost associated with it, as well as a maximum
total shipping capacity.
This is the complete source code for our example (also available in
<installdir>/examples/python/netflow.py)...
# !/ usr / bin / env python3 .7
89
# Copyright 2022 , Gurobi Optimization , LLC
# Solve a multi - commodity flow problem . Two products ( ’ Pencils ’ and ’ Pens ’)
# are produced in 2 cities ( ’ Detroit ’ and ’ Denver ’) and must be sent to
# warehouses in 3 cities ( ’ Boston ’, ’ New York ’, and ’ Seattle ’) to
# satisfy demand ( ’ inflow [h , i ] ’).
#
# Flows on the transportation network must respect arc capacity constraints
# ( ’ capacity [i , j ] ’). The objective is to minimize the sum of the arc
# transportation costs ( ’ cost [i , j ] ’).
import gurobipy as gp
from gurobipy import GRB
# Base data
commodities = [ ’ Pencils ’ , ’ Pens ’]
nodes = [ ’ Detroit ’ , ’ Denver ’ , ’ Boston ’ , ’ New York ’ , ’ Seattle ’]
90
# Create variables
flow = m . addVars ( commodities , arcs , obj = cost , name = " flow " )
# Alternate version :
# m . addConstrs (
# ( gp . quicksum ( flow [h , i , j ] for i , j in arcs . select ( ’* ’ , j )) + inflow [h , j ] ==
# gp . quicksum ( flow [h , j , k ] for j , k in arcs . select (j , ’* ’))
# for h in commodities for j in nodes ) , " node ")
# Print solution
if m . Status == GRB . 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 ]))
Let us now walk through the example, line by line, to understand how it achieves the desired result
of computing the optimal network flow. As with the simple Python example presented earlier, this
example begins by importing the Gurobi functions and classes:
import gurobipy as gp
from gurobipy import GRB
91
( ’ Detroit ’ , ’ New York ’ ): 80 ,
( ’ Detroit ’ , ’ Seattle ’ ): 120 ,
( ’ Denver ’ , ’ Boston ’ ): 120 ,
( ’ Denver ’ , ’ New York ’ ): 120 ,
( ’ Denver ’ , ’ Seattle ’ ): 120})
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 for triplets commodity - source - destination
cost = {
( ’ Pencils ’ , ’ Detroit ’ , ’ Boston ’ ): 10 ,
( ’ Pencils ’ , ’ Detroit ’ , ’ New York ’ ): 20 ,
( ’ Pencils ’ , ’ Detroit ’ , ’ Seattle ’ ): 60 ,
( ’ Pencils ’ , ’ Denver ’ , ’ Boston ’ ): 40 ,
( ’ Pencils ’ , ’ Denver ’ , ’ New York ’ ): 40 ,
( ’ Pencils ’ , ’ Denver ’ , ’ Seattle ’ ): 30 ,
( ’ Pens ’ , ’ Detroit ’ , ’ Boston ’ ): 20 ,
( ’ Pens ’ , ’ Detroit ’ , ’ New York ’ ): 20 ,
( ’ Pens ’ , ’ Detroit ’ , ’ Seattle ’ ): 80 ,
( ’ Pens ’ , ’ Denver ’ , ’ Boston ’ ): 60 ,
( ’ Pens ’ , ’ Denver ’ , ’ New York ’ ): 70 ,
( ’ Pens ’ , ’ Denver ’ , ’ Seattle ’ ): 30}
Once this dictionary has been created, the cost of moving one unit of 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/supply data:
# Demand for pairs of commodity - city
inflow = {
( ’ Pencils ’ , ’ Detroit ’ ): 50 ,
( ’ Pencils ’ , ’ Denver ’ ): 60 ,
( ’ Pencils ’ , ’ Boston ’ ): -50 ,
( ’ Pencils ’ , ’ New York ’ ): -50 ,
( ’ Pencils ’ , ’ Seattle ’ ): -10 ,
( ’ Pens ’ , ’ Detroit ’ ): 60 ,
( ’ Pens ’ , ’ Denver ’ ): 40 ,
( ’ Pens ’ , ’ Boston ’ ): -40 ,
( ’ Pens ’ , ’ New York ’ ): -30 ,
( ’ Pens ’ , ’ Seattle ’ ): -30}
The next step in our example (after creating an empty Model object) is to add decision variables
to the model. The variables are created using addVars, and are returned in a tupledict which
we’ll call flow:
92
# Create optimization model
m = gp . Model ( ’ netflow ’)
# Create variables
flow = m . addVars ( commodities , arcs , obj = cost , name = " flow " )
The first, 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 flow 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 also that flow[c,i,j] is a continuous decision variable; variables are
assumed to be continuous unless you state otherwise.
We begin with a straightforward set of constraints. The sum of the flow variables on an arc must
be less than or equal to the capacity of that arc:
# Arc - capacity constraints
m . addConstrs (
( flow . sum ( ’* ’ , i , j ) <= capacity [i , j ] for i , j in arcs ) , " cap " )
Note that this one statement uses several of the concepts that were introduced earlier in this section.
The first 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 first field) 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.
Specifically, this portion of the statement...
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 specific 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 final 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 flow 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:
93
Flow conservation constraints
The next set of constraints are the flow conservation constraints. They require that, for each
commodity and node, the sum of the flow into the node plus the quantity of external inflow at that
node must be equal to the sum of the flow out of the node:
# Flow - conservation constraints
m . addConstrs (
( flow . sum (h , ’* ’ , j ) + inflow [h , j ] == flow . sum (h , j , ’* ’)
for h in commodities for j in nodes ) , " node " )
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:
# Compute optimal solution
m . optimize ()
# Print solution
if m . Status == GRB . 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.sh netflow.py, you should see the following output:
94
Using license file /opt/gurobi/gurobi.lic
95
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. You need to install the 64-bit version of MATLAB to use Gurobi.
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 + 2y + 3z ≤ 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)...
function mip1 ()
% Copyright 2022 , Gurobi Optimization , LLC
% This example formulates and solves the following simple MIP model :
% maximize
% x + y + 2 z
% subject to
% x + 2 y + 3 z <= 4
% x + y >= 1
% x , y , z binary
96
names = { ’x ’; ’y ’; ’z ’ };
params . outputflag = 0;
disp ( result );
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.
97
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.
params.outputflag = 0;
params.resultfile = ’mip1.lp’;
In this example, we set the Gurobi OutputFlag parameter to 0 in order to shut off Gurobi output.
We also set the ResultFile parameter to request that Gurobi produce a file as output (in this case,
an LP format file that contains the optimization model). The Gurobi MATLAB interface allows
you to set as many Gurobi parameters as you like. The field names in the parameter structure
simply need to match Gurobi parameter names, and the values of the fields should be set to the
desired parameter values. 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 specified model and returns the computed result.
98
Running the example
The Gurobi MATLAB examples can be found in the <installdir>/examples/matlab/ directory of
your Gurobi installation (the default <installdir> for Gurobi 9.5.2 is /opt/gurobi952/linux64
for Linux). To run one of the examples, first change to this directory in MATLAB, then type its
name into the MATLAB prompt. For example, to run example mip1, you would say:
>> cd /opt/gurobi952/linux64/examples/matlab
>> mip1
If Gurobi was successfully set up for use in MATLAB, you should see the following output in the
command window:
status: ’OPTIMAL’
versioninfo: [1x1 struct]
runtime: 3.2401e-04
objval: 3
x: [3x1 double]
slack: [2x1 double]
poolobjbound: 3
pool: [1x2 struct]
mipgap: 0
objbound: 3
objboundc: 3
itercount: 0
baritercount: 0
nodecount: 0
x 1
y 0
z 1
Obj: 3.000000e+00
From all this data we only use the fields objval and x in our example. Please refer to the reference
manual for a complete description of all the other output fields.
In order to get more familiar with the Gurobi MATLAB interface, we encourage you to browse
through the files in the MATLAB example directory. Often these examples can be used as starting
points for your own optimization projects.
99
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.
install.packages(’<R-package-file>’, repos=NULL)
The R package file can be found in the <installdir>/R directory of your Gurobi installation. For
a default installation of Gurobi 9.5.2, the command would be:
install.packages(’/opt/gurobi952/linux64/R/gurobi_9.5-2_R_4.2.0.tar.gz’, repos=NULL)
You will need to adjust the path to match your installation 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. To use the Gurobi R package, you will need to use the 64-bit version of R.
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 config file. 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 + 2y + 3z ≤ 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/R/mip.R)...
# Copyright 2022 , Gurobi Optimization , LLC
#
# This example formulates and solves the following simple MIP model :
# maximize
100
# x + y + 2 z
# subject to
# x + 2 y + 3 z <= 4
# x + y >= 1
# x, y, z binary
library ( gurobi )
print ( ’ Solution : ’)
print ( result $ objval )
print ( result $ x )
# Clear space
rm ( model , result , params )
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.
101
Subsequent statements populate other components of the model variable, including the objective
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 component equal to ’max’ to indicate that we would like
to maximize the specified 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 infinite upper bound. If you’d like your
variables to have different 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 off 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 specified model and returns the computed result.
102
complete list of all possible status codes. If Gurobi was able to find 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).
> source(’mip.R’)
If the Gurobi package was successfully installed, you should see the following output:
[1] "Solution:"
[1] 3
[1] 1 0 1
103
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 field. 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, Tsit-
siklis, 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 busi-
ness problems, we recommend Model Building in Mathematical Programming by H.P. Williams.
104
File Overview
This section briefly describes the purposes of the more important files in the Gurobi distribution.
Note that the list below may not precisely agree with your installation. We’ve omitted a few less
important files. In addition, a few file names depend on the exact version of the Gurobi optimizer
that you installed.
The following files and directories are created in your installation directory
(typically /opt/gurobi952/linux64 for the 64-bit Linux distribution):
• bin
• docs
• examples
105
– c - source code for C examples
– c# - source code for C# examples
– c++ - source code for C++ examples
– data - data files 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 (for Windows)
• include
• lib
106
– python3.9_utf32 - Python 3.9 files (no need to look inside this directory)
– rootcert.pem - libcurl distributed certificate
• R - R Gurobi package
• setup.py - Python setup file - for installing the gurobipy module into your own Python envi-
ronment
• src
The following files and directories are created in your Remote Services installation (typically
/opt/gurobi_server952/linux64 for the 64-bit Linux distribution):
• bin
107
• docs
108