Gurobi Mex: A MATLAB interface for Gurobi

From Wikimization

(Difference between revisions)
Jump to: navigation, search
(Input Description)
m (Step 3b. Linux/Unix)
(148 intermediate revisions not shown.)
Line 1: Line 1:
-
Gurobi Mex is a MATLAB interface for Gurobi 2 written by [http://www.caam.rice.edu/ Wotao Yin]. It calls [http://www.gurobi.com/ Gurobi] to solve linear/mixed-integer optimization problems. Gurobi is one of the leading linear and mixed integer programming solvers. Gurobi has [http://www.gurobi.com/html/freetrial.html free trial], and its full version is [http://www.gurobi.com/html/academic.html free academic-wise].
+
[[Image:Gurobi_matlab_logos.jpg|right]] Gurobi Mex is a free MATLAB interface for '''Gurobi 2''', '''3''', and '''4''' written by [http://www.caam.rice.edu Wotao Yin] with contributions by Jon Dattorro, Imre Polik, and Tomáš Strnad. It calls [http://www.gurobi.com Gurobi] to solve linear/quadratic/mixed-integer optimization problems. Gurobi offers [http://www.gurobi.com/html/freetrial.html free trial] and [http://www.gurobi.com/html/academic.html free academic license].
-
The interface is open source and subject to [http://creativecommons.org/licenses/by-sa/3.0/us/ Creative Commons Attribution-Share Alike 3.0 United States License]. It is a tool for MATLAB users to quickly call Gurobi, and its source code serves as a start point for those who want to develop a customized MATLAB interface for Gurobi.
+
This interface is open source and subject to [http://creativecommons.org/licenses/by-sa/3.0/us Creative Commons Attribution-Share Alike 3.0 United States License]. It is a tool for MATLAB users to quickly call Gurobi. Its source code may also serve as a starting point for those who want to develop a customized MATLAB interface for Gurobi.
-
Its current version is 1.10 published on Jan 24, 2010.
+
It is not trivial to write a good interface (it is about two thousand lines of code). If you find this interface useful, please credit it in your publications [[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex.bib bibtex]] [[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex.enw Endnote]] [[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex.txt text]], as this will motivate the author to keep the interface up to date with the latest Gurobi, as well as improving its functions and making it easier to use.
 +
Current version 1.61 was published November 16, 2011. [[http://www.convexoptimization.com/wikimization/index.php/Gurobi_Mex:_A_MATLAB_interface_for_Gurobi#Download.2C_Installation.2C_and_Limitations Skip to Download Section]]
----
----
-
== Model ==
+
 
 +
== Model (LP, QP, MIP, MIQP) ==
<pre>
<pre>
-
min/max c'x
+
min/max x'Cx + c'x
subject to
subject to
-
Ax [>= / <= / =] b,
+
Ax >= / <= / = b,
lb <= x <= ub,
lb <= x <= ub,
-
x(i) is [continuous / binary / integer / semi-continuous / semi-integer].
+
SOS constraints,
 +
x(i) is continuous / binary / integer / semi-continuous / semi-integer.
</pre>
</pre>
- 
-
== Download, Installation, and Limitations ==
 
- 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/download_request.html Download C source code and MATLAB examples, the latest version]
 
- 
-
v1.10 Function upgrades: callback, runtime progress output, flexible log file, flexible input types, more options.
 
- 
-
:Part of the code was contributed by ''Tomáš Strnad'' from ''Czech Technical University in Prague''. Thanks, Tomáš!
 
-
=== History ===
 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.05.zip v1.05] Major bug fix: char array of constraint sense has been fixed
 
- 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.04.zip v1.04] support writing model to files in various formats such as MPS, REW, LP, ...
 
- 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.03.zip v1.03] support log file
 
- 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.02.zip v1.02] fixed a memory leak issue
 
- 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.01.zip v1.01] update: support output dual solution lambda; allow vartypes to be empty (for all continuous variables).
 
- 
-
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.0.zip v1.00] initial version.
 
- 
-
=== Building Gurobi Mex in MATLAB ===
 
-
==== Under Windows ====
 
- 
-
mex -O -I"<gurobi include path>" gurobi_mex.c "<absolute path\gurobi20.lib>"
 
- 
-
For 64-bit MATLAB, please add option "-largeArrayDims".
 
- 
-
Example include path: ''C:\Users\[Login Name]\Programs\Gurobi200\win32\include''
 
- 
-
Example path of gurobi20.lib: ''C:\Users\[Login Name]\Programs\Gurobi200\win32\lib\gurobi20.lib''
 
-
==== Under Unix ====
 
- 
-
mex -O -I"<gurobi include path>" gurobi_mex.c -L"<gurobi lib path>" -lgurobi20
 
- 
-
For 64-bit MATLAB, please add option "-largeArrayDims".
 
- 
-
Example include path: ''/opt/gurobi200/linux64/include''
 
- 
-
Example library path: ''/opt/gurobi200/linux64/lib''
 
-
==== Tested platforms ====
 
- 
-
* Windows 32-bit and gcc (included in free Mingw/GnuMex)
 
-
* Ubuntu Linux 9.10 64-bit and gcc.
 
- 
-
MATLAB's built-in ''lcc'' cannot link with Gurobi.
 
-
 
-
Please make sure that the dynamic library of Gurobi 2.x is in system path and the license of Gurobi is valid.
 
== Syntax ==
== Syntax ==
:x = gurobi_mex(c, objtype, A, b, contypes, lb, ub, vartypes);
:x = gurobi_mex(c, objtype, A, b, contypes, lb, ub, vartypes);
-
:x = gurobi_mex(c, objtype, A, b, contypes, lb, ub, vartypes, options);
+
:x = gurobi_mex(c, objtype, A, b, contypes, lb, ub, vartypes, opts);
:[x,val] = gurobi_mex(...);
:[x,val] = gurobi_mex(...);
:[x,val,flag] = gurobi_mex(...);
:[x,val,flag] = gurobi_mex(...);
Line 75: Line 30:
== Input Description ==
== Input Description ==
-
 
+
* '''c''': objective coefficient vector, double type.
-
* '''c''': objective coefficient vector, double.
+
:[] (empty array) means uniformly <font face="Times">0</font> coefficients, and ''scalar'' means all coefficients equal to ''scalar''.
-
:[] (empty array) means uniformly 0 coefficients, and ''scalar'' means all coefficients equal to ''scalar''.
+
* '''objtype''': 1 (minimization) or -1 (maximization).
* '''objtype''': 1 (minimization) or -1 (maximization).
-
* '''A''': constraint coefficient matrix, double, sparse.
+
* '''A''': constraint coefficient matrix, double type, sparse.
-
* '''b''': constraint right-hand side vector, double.
+
* '''b''': constraint right-hand side vector, double type.
-
:Gurobi takes a dense vector for this input. If a ''sparse'' vector is specified, it is converted to ''full'' by Gurobi Mex.
+
:Gurobi takes a dense vector for this input. If a ''sparse'' vector is specified, it will be converted to ''full'' by Gurobi Mex.
* '''contypes''': constraint types. Char array of '>', '<', '='.
* '''contypes''': constraint types. Char array of '>', '<', '='.
-
:Warning: '>=' means two constraints instead of one an inequality constraint.
+
:Warning: '>=' specifies two constraints, not one.
-
:Example: '>><=' means the first two constraints have ''greater or equal to'' signs, the third has ''less than or equal to'' sign, and the last is an equality constraint.
+
:Example: '>><=' specifies four constraints. The first two constraints have ''greater or equal to'' signs, the third has ''less than or equal to'' sign, and the last is an equality constraint.
-
:If a single character is specified, all constraints are uniformly signed to the corresponding type.
+
:If a single character is specified, it will be applied to all constraints uniformly.
-
* '''lb''': variable lower bound vector, double.
+
* '''lb''': variable lower bound, double type, either scalar or vector.
-
:[] (empty array) means 0 lower bound. -inf means no lower bound. ''scalar'' means a uniform lower bound equal to ''scalar''.
+
:[] (empty array) means <font face="Times">0</font> lower bound. -inf means no lower bound. If a scalar is specified, it will be the uniform lower bound for all variables.
-
* '''ub''': variable upper bound vector, double.
+
* '''ub''': variable upper bound, double type, either scalar or vector.
-
:[] (empty array) means no (or infinity) upper bound. ''scalar'' means a uniform upper bound equal to ''scalar''.
+
:[] (empty array) means no (or infinity) upper bound. If a scalar is specified, it will be the uniform upper bound for all variables.
-
* '''vartypes''': variable types. Char array of chars 'C', 'B', 'I', 'S', 'N'. C for continuous; B for binary; I for integer; S for semi-continuous; N for semi-integer. [] (empty array) means all variables are continuous.
+
* '''vartypes''': variable types, char array of 'C', 'B', 'I', 'S', 'N'. 'C' for continuous; 'B' for binary; 'I' for integer; 'S' for semi-continuous; 'N' for semi-integer. [] (empty array) means all variables are continuous.
-
:Example: 'CCCCC' stands for five continuous variables.
+
:Example: 'CCCCC' specifies five continuous variables.
-
:Note that semi-continuous variables are variables that must take a value between their minimum and maximum or zero. Semi-integer variables are similarly defined.
+
:Note that a semi-continuous variable is one that must be either zero or a value between its minimum and maximum. Semi-integer variables are similarly defined.
-
:If a single character is specified, all variables are uniformly signed to the corresponding type.
+
:If a single character is specified, all variables will be signed to the corresponding type uniformly.
-
* '''options''': ''optional'' structure that may contain one or more of the following fields: (see [http://www.gurobi.com/html/doc/refman/node378.html Gurobi's parameter help] for their allowed values. Also, see [[Gurobi_Mex:_A_MATLAB_interface_for_Gurobi#Three_Examples|examples]] below.)
+
=== [http://www.gurobi.com/doc/40/refman/node572.html Gurobi Parameters] ===
-
** '''options.IterationLimit''': see Gurobi's parameter help.
+
* '''opts''': optional structure that may have any number of following parameters.
-
** '''options.FeasibilityTol''': see Gurobi's parameter help.
+
** '''opts.[any Gurobi parameter]''': See [http://www.gurobi.com/doc/40/refman/node572.html Gurobi Parameters] for their allowed values.
-
** '''options.IntFeasTol''': see Gurobi's parameter help.
+
** '''opts.QP''': Quadratic objective terms. See [http://www.convexoptimization.com/wikimization/index.php/Gurobi_Mex:_A_MATLAB_interface_for_Gurobi#Quadratic_Programming here].
-
** '''options.OptimalityTol''': see Gurobi's parameter help.
+
** '''opts.SOS''': Special ordered set constraints. See [http://www.convexoptimization.com/wikimization/index.php/Gurobi_Mex:_A_MATLAB_interface_for_Gurobi#SOS_Constraints here].
-
** '''options.MIPGap''': see Gurobi's parameter help.
+
** '''opts.Start''': MIP start vector, or Gurobi's attribute 'Start'. See [http://www.convexoptimization.com/wikimization/index.php/Gurobi_Mex:_A_MATLAB_interface_for_Gurobi#MIP_Start_Vector here].
-
** '''options.LPMethod''': see Gurobi's parameter help.
+
** '''opts.TrapCtrlC''': true (to trap Ctrl-C) or false (not to trap Ctrl-C).
-
** '''options.Presolve''': see Gurobi's parameter help.
+
** '''opts.Display''': screen output level. <font face="Times">0</font> (no output); 1 (version and error messages only); 2 (default output). For complete silence, set '''opts.DisplayInterval=<font face="Times">0</font>''' and '''opts.OutputFlag=<font face="Times">0</font>''' (to silence Gurobi) and '''opts.Display=<font face="Times">0</font>''' (to make Gurobi Mex silent).
-
** '''options.TimeLimit''': see Gurobi's parameter help.
+
** '''opts.WriteToFile''': char array of the name of the file to which optimization data is written. See Gurobi C-Reference entry [http://www.gurobi.com/doc/40/refman/node39.html GRBwrite] for supported formats. This option helps one verify whether the model is correctly passed to Gurobi.
-
** '''options.Threads''': see Gurobi's parameter help.
+
-
** '''options.DisplayInterval''': Gurobi's Callback screen output interval. [http://www.gurobi.com/html/doc/refman/node381.html#sec:CallbackCodes See Gurobi's parameter help.] &nbsp; 0 means no Gurobi message.
+
-
** '''options.Display''': Gurobi Mex's screen output level. 0 for no output; 1 for error only; 2 (default) for normal output.
+
-
** '''options.LogFile''': char array of the name of log file. ''options.UseLogfile'' is no longer used.
+
-
** '''options.WriteToFile''': char array of the name of the file to which optimization data is written. See Gurobi C-Reference entry [http://www.gurobi.com/html/doc/refman/node35.html GRBwrite] for supported formats. This option helps one verify whether the model is correctly passed to Gurobi.
+
== Output Description ==
== Output Description ==
Line 113: Line 62:
* '''val''': optimal objective value; empty if Gurobi encounters errors or stops early.
* '''val''': optimal objective value; empty if Gurobi encounters errors or stops early.
* '''flag''': value meanings:
* '''flag''': value meanings:
 +
** [ ] (empty 1x1 array) general failure
** 1 for not started
** 1 for not started
** 2 for optimal
** 2 for optimal
Line 125: Line 75:
** 11 for user interruption
** 11 for user interruption
** 12 for numerical difficulties
** 12 for numerical difficulties
 +
** 13 for suboptimal solution ('''Gurobi 3''' and later)
* '''output''': structure contains the following fields
* '''output''': structure contains the following fields
** '''output.IterCount''': number of Simplex iterations
** '''output.IterCount''': number of Simplex iterations
** '''output.Runtime''': running time in seconds
** '''output.Runtime''': running time in seconds
** '''output.ErrorMsg''': contains Gurobi error message, if any
** '''output.ErrorMsg''': contains Gurobi error message, if any
-
* '''lambda''': Lagrange multipliers. Because solving MIPs gives no such output, ''do not'' ask for this output for MIPs.
+
** '''output.Versions.GurobiMex''': version of this interface (supported by v1.61 and later)
 +
** '''output.Versions.LibMajor''', '''output.Versions.LibMinor''', and '''output.Versions.LibTechi''': [http://www.gurobi.com/doc/46/refman/node89.html Gurobi library version] (supported by v1.61 and later)
 +
* '''lambda''': constraint dual variables (up to v1.50) or structure contains the following fields (v1.55 and later)
 +
** '''lambda.RC''': reduced cost
 +
** '''lambda.Pi''': constraint dual variables
 +
** '''lambda.Slack''': constraint slack variables
 +
 
 +
== Notes ==
 +
=== Quadratic Programming ===
 +
'''Gurobi 4''' and later solve quadratic programs. The quadratic terms in the objective function should be specified by '''opts.QP.qrow''', '''opts.QP.qcol''', and '''opts.QP.qval''', which correspond to the input arguments ''qrow'', ''qcol'', and ''qval'' of [http://gurobi.com/doc/40/refman/node11.html function GRBaddqpterms]. They are all 1D arrays. The first two arguments, ''qrow'' and ''qcol'', specify the row and column indices (starting from 0) of 2nd-order terms such as <math>x_1^2</math> and <math>x_1 x_2\,</math>. The third argument, ''qval'', gives their coefficients. An example is given [http://www.convexoptimization.com/wikimization/index.php/Gurobi_Mex:_A_MATLAB_interface_for_Gurobi#Example_5._Quadratic_programming below].
 +
 
 +
To solve a quadratic program with no constraints, set A = [], b = [], and contypes = [].
 +
 
 +
----
 +
 
 +
=== SOS Constraints ===
 +
SOS stands for [http://www.google.com/search?q=special+ordered+set+SOS Special Ordered Sets]. This mex program uses opts.SOS.weights and opts.SOS.types to pass SOS constraints to Gurobi. '''opts.SOS.weights''' is a ''sparse'' matrix describing the weights of SOS variables, and '''opts.SOS.types''' a 1D array of type int32 or int64 (if sizeof(int) is 4 for your system, then you should use int32; if 8, use int64), which specifies the constraint types. Here is an example with 4 variables and 3 SOS constraints:
 +
 
 +
SOS1: x1 = 0 or x2 = 0
 +
SOS1: x1 = 0 or x3 = 0
 +
SOS2: (x1, x3, x2, x4)
 +
 
 +
The corresponding code for a 32-bit system is
 +
opts.SOS.weights = sparse([
 +
1 1 1;
 +
2 0 3;
 +
0 2 2;
 +
0 0 4]);
 +
opts.SOS.types = int32([1 1 2]);
 +
The ''i''th column of '''opts.SOS.weights''' specifies the weights (i.e., orders) of the variables in the ''i''th SOS constraint.
 +
 
 +
----
 +
 
 +
=== MIP Start Vector ===
 +
To specify an MIP start vector (supported since v1.45), say x = [1 0 3 2], one can use one of the following two ways:
 +
 
 +
opts.Start = [1 0 3 2];
 +
 
 +
or
 +
 
 +
opts.Start.pos = int32([0 1 2 3]); % use int64 if sizeof(int) is 8 for your system
 +
opts.Start.val = [1 0 3 2];
 +
 
 +
To specify start values for a subset of variables, for example to set x = [? ? -1 2], where ? means undefined, one can choose either one of the following two ways
 +
 
 +
GRB_UNDEFINED = 1e101;
 +
opts.Start = [GRB_UNDEFINED GRB_UNDEFINED -1 2];
 +
 
 +
or
 +
 
 +
opts.Start.pos = int32([2 3]); % use int64 if sizeof(int) is 8 for your system
 +
opts.Start.val = [-1 2];
 +
 
 +
----
 +
 
 +
=== How to pass a parameter from MATLAB to Gurobi? ===
 +
v1.35 and v1.45 support all parameters of '''Gurobi 3''' and '''4''', respectively. However, if you want to specify a new or undocumented Gurobi parameter of your interest, you can DIY very easily. Suppose that we want to set a double-type parameter called '''SecretPara''' in MATLAB and pass it through this mex interface to Gurobi. Because the parameter '''TimeLimit''' has the same (double) type and it is already supported by this mex program, we can copy the code for '''TimeLimit''', replace TimeLimit by SecretPara in the code, and paste it at Line 1250 of v1.35 (or Line 510 of v1.30), just before the mex program checks unrecognized input option fields. After compiling ''gurobi.c'', the modified mex will let you assign a double value to '''opts.SecretPara'''. We compare the code for '''TimeLimit''' and '''SecretPara''' below where the differences are italicized:
 +
 
 +
/* Option ''TimeLimit'' */
 +
field_n = mxGetFieldNumber(IN_OPTS, "''TimeLimit''");
 +
if (field_n != -1) {
 +
field = mxGetFieldByNumber(IN_OPTS,0,field_n);
 +
bOpts[field_n] = true;
 +
if (!mxIsDouble(field) || mxIsComplex(field) || mxIsEmpty(field)) {
 +
mexPrintf("''Option TimeLimit must be real positive double (0 to inf).''");
 +
goto QUIT;
 +
}
 +
error = GRBsetdblparam(env, "''TimeLimit''", mxGetScalar(field));
 +
if (error) goto QUIT;
 +
}
 +
 
 +
/* Option ''SecretPara'' */
 +
field_n = mxGetFieldNumber(IN_OPTS, "''SecretPara''");
 +
if (field_n != -1) {
 +
field = mxGetFieldByNumber(IN_OPTS,0,field_n);
 +
bOpts[field_n] = true;
 +
if (!mxIsDouble(field) || mxIsComplex(field) || mxIsEmpty(field)) {
 +
mexPrintf("''Option SecretPara must real double (?? through ??).''");
 +
goto QUIT;
 +
}
 +
error = GRBsetdblparam(env, "''SecretPara''", mxGetScalar(field));
 +
if (error) goto QUIT;
 +
}
 +
 
 +
Note that you must start from a parameter of the ''same'' type (int, double, or string). In case memory allocation is needed, use ''mxCalloc'' and make sure that ''mxFree'' has been called whenever the mex program exits, normally or not.
== Callbacks ==
== Callbacks ==
-
Callback are useful to obtain the progress of Gurobi and to modify its behavior during runtime. Gurobi Mex uses a callback function ''mycallback'' to obtain Gurobi's progress messages and print them on the MATLAB screen. The print frequency is set by options.DisplayInterval (in seconds).
+
Callbacks are useful to obtain the progress of Gurobi (e.g., by calling GRBcbget) and to modify its behavior during runtime (e.g., by calling GRBcbcut and GRBcbsolution).
 +
 
 +
Gurobi Mex implements a callback function ''mycallback'' to obtain Gurobi's progress messages and print them on the MATLAB screen. The print frequency is set in '''opts.DisplayInterval''' (in seconds). The same function is also used to detect user input Ctrl-C.
-
Information for Gurobi callbacks can be found [http://www.gurobi.com/html/doc/refman/node80.html here] in Gurobi's help. An example can be found [http://www.gurobi.com/html/doc/exampletour/node8.html here].
+
Information for Gurobi callbacks can be found [http://www.gurobi.com/doc/40/refman/node84.html here] in Gurobi's help. An example can be found [http://www.gurobi.com/doc/40/examples/node8.html here].
-
== Four Examples ==
+
== Examples ==
=== Example 1. Linear programming ===
=== Example 1. Linear programming ===
Line 167: Line 204:
opts.IntFeasTol = 1e-5;
opts.IntFeasTol = 1e-5;
opts.OptimalityTol = 1e-6;
opts.OptimalityTol = 1e-6;
-
opts.LPMethod = 1; % 0 - primal, 1 - dual
+
opts.Method = 1; % 0 - primal, 1 - dual
opts.Presolve = -1; % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
opts.Presolve = -1; % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
opts.Display = 1;
opts.Display = 1;
-
opts.LogFile = 'test_gurobi_mex_LP.log';
+
opts.LogFile = 'test_gurobi_mex_LP.log'; % optional
-
opts.WriteToFile = 'test_gurobi_mex_LP.mps';
+
opts.WriteToFile = 'test_gurobi_mex_LP.mps'; % optional; it can cause a long delay if problem is large
[x,val,exitflag,output,lambda] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
[x,val,exitflag,output,lambda] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
Line 197: Line 234:
=== Example 2. Integer programming ===
=== Example 2. Integer programming ===
-
This example is borrowed from ''mip1_c.c'' of Gurobi 2.0.
+
This example is borrowed from ''mip1_c.c'' of '''Gurobi 2'''.
Problem:
Problem:
Line 224: Line 261:
opts.IntFeasTol = 1e-5;
opts.IntFeasTol = 1e-5;
opts.OptimalityTol = 1e-6;
opts.OptimalityTol = 1e-6;
-
opts.LPMethod = 1; % 0 - primal, 1 - dual
+
opts.Method = 1; % 0 - primal, 1 - dual
opts.Presolve = -1; % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
opts.Presolve = -1; % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
opts.Display = 1;
opts.Display = 1;
opts.LogFile = 'test_gurobi_mex_MIP.log';
opts.LogFile = 'test_gurobi_mex_MIP.log';
-
opts.WriteToFile = 'test_gurobi_mex_MIP.mps';
+
opts.WriteToFile = 'test_gurobi_mex_MIP.mps'; % this option can cause a long delay if problem is large
[x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
[x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
Line 272: Line 309:
objtype = -1; % 1 for minimize, -1 for maximize
objtype = -1; % 1 for minimize, -1 for maximize
A = sparse([5 4 0 5; 5 3 1 4; 3 5 2 -5]);
A = sparse([5 4 0 5; 5 3 1 4; 3 5 2 -5]);
-
b = [-21; -14; 11]; % stands for uniformly 0 lower bound
+
b = [-21; -14; 11];
-
lb = [];
+
lb = []; % stands for 0 lower bound uniformly
-
ub = []; % stands for uniformly inf upper bound
+
ub = []; % stands for inf upper bound uniformly
contypes = '>==';
contypes = '>==';
-
vtypes = []; % same as vtypes = 'CCCC'; empty means 'C...C'
+
vtypes = []; % same as vtypes = 'CCCC'
clear opts
clear opts
Line 283: Line 320:
opts.Display = 1;
opts.Display = 1;
opts.LogFile = 'test_gurobi_mex_Feasibility.log';
opts.LogFile = 'test_gurobi_mex_Feasibility.log';
-
opts.WriteToFile = 'test_gurobi_mex_Feasibility.mps';
+
opts.WriteToFile = 'test_gurobi_mex_Feasibility.mps'; % this option can cause a long delay if problem is large
[x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
[x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
Line 303: Line 340:
Log file: ''test_gurobi_mex_Feasibility.log''. MPS file: ''test_gurobi_mex_Feasibility.mps''.
Log file: ''test_gurobi_mex_Feasibility.log''. MPS file: ''test_gurobi_mex_Feasibility.mps''.
-
=== Example 4. Compressive sensing ===
+
=== Example 4. SOS constraint test ===
 +
Problem:
 +
<pre>
 +
min –3 x1 – 1 x2 – 1 x3,
 +
 
 +
subject to
 +
x1 + x2 + x3 <= 2,
 +
0 <= x1 <= 1, 0 <= x2 <= 1, 0 <= x3 <= 2,
 +
SOS type 1: x1 = 0 or x2 = 0,
 +
SOS type 1: x1 = 0 or x3 = 0.
 +
</pre>
 +
MATLAB code:
 +
<pre>
 +
c = [-3; -1; -1];
 +
objtype = 1;
 +
A = sparse([1 1 1]);
 +
b = 2;
 +
lb = []; % means 0 lower bound
 +
ub = [1 1 2];
 +
contypes = '<';
 +
vtypes = []; % same as vtypes = 'CCC'
 +
sos.weights = sparse([1 1; 2 0; 0 2]);
 +
sos.types = int32([1 1]); % Both the SOS constraints are of type 1
 +
 
 +
clear opts
 +
opts.FeasibilityTol = 1e-6;
 +
opts.Presolve = -1; % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
 +
opts.Display = 1;
 +
opts.LogFile = 'test_gurobi_mex_Feasibility.log';
 +
opts.WriteToFile = 'test_gurobi_mex_Feasibility.mps';
 +
 
 +
[x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
 +
</pre>
 +
 
 +
Results:
 +
<pre>
 +
Optimal solution found (tolerance 1.00e-04)
 +
Best objective -3.0000000000e+00, best bound -3.0000000000e+00, gap 0.0%
 +
 +
Solution:
 +
1 0 0
 +
</pre>
 +
Log file: ''test_gurobi_mex_SOS.log''. MPS file: ''test_gurobi_mex_SOS.mps''.
 +
 
 +
=== Example 5. Quadratic programming ===
 +
This example appears in MATLAB Help entry for ''quadprog''.
 +
 
 +
Problem:
 +
<pre>
 +
min 0.5 x0^2 - x0*x1 + x1^2 - 2*x0 - 6*x1,
 +
 
 +
subject to
 +
x0 + x1 <= 2,
 +
-x0 + 2x1 <= 2,
 +
2x0 + x1 <= 3,
 +
x0 >= 0, x1 >= 0.
 +
</pre>
 +
MATLAB code:
 +
<pre>
 +
clear opts
 +
 
 +
c = [-2 -6]; % objective linear term
 +
objtype = 1; % minimization
 +
A = sparse([1 1; -1 2; 2 1]); % constraint coefficients
 +
b = [2; 2; 3]; % constraint right-hand side
 +
lb = []; % [] means 0 lower bound
 +
ub = []; % [] means inf upper bound
 +
contypes = '<<<'; % three <= inequalities
 +
vtypes = []; % [] means all variables are continuous
 +
% note that 0.5 x0^2 - x0*x1 + x1^2 = 0.5 x0*x0 - x0*x1 + x1*x1
 +
opts.QP.qrow = int32([0 0 1]); % indices of leading variables (x0), (x0), (x1) in 0.5 (x0)*x0 - (x0)*x1 + (x1)*x1
 +
opts.QP.qcol = int32([0 1 1]); % indices of following variables (x0), (x1), (x1) in 0.5 x0*(x0) - x0*(x1) + x1*(x1)
 +
opts.QP.qval = [0.5 -1 1]; % coefficients of 0.5 x0^2 - x0*x1 + x1^2
 +
 
 +
opts.IterationLimit = 200;
 +
opts.FeasibilityTol = 1e-6;
 +
opts.IntFeasTol = 1e-5;
 +
opts.OptimalityTol = 1e-6;
 +
 
 +
[x,val,exitflag,output,lambda] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);
 +
 
 +
disp('Solution:');disp(x')
 +
disp('Optimal obj value:');disp(val)
 +
disp('Exit flag:');disp(exitflag)
 +
disp('Optimization info:');disp(output)
 +
disp('Lagrange multiplers:');disp(lambda')
 +
</pre>
 +
 
 +
Results:
 +
<pre>
 +
Solution:
 +
0.6667 1.3333
 +
Optimal obj value:
 +
-8.2222
 +
Exit flag:
 +
2
 +
Optimization info:
 +
IterCount: 4
 +
Runtime: 0.0630
 +
ErrorMsg: []
 +
Lagrange multiplers:
 +
-3.1111 -0.4444 0
 +
</pre>
 +
 
 +
=== Example 6. Mixed integer quadratic programming ===
 +
See example m-file ''test_gurobi_mex_MIQP.m''.
 +
 
 +
=== Example 7. Compressive sensing ===
See example m-file ''test_gurobi_mex_CS.m''.
See example m-file ''test_gurobi_mex_CS.m''.
== Feedback ==
== Feedback ==
-
I would be delighted to hear from you if you find Gurobi Mex useful, or if you have any suggestions, contributions, or bug reports. Please send these to
+
[http://www.convexoptimization.com/wikimization/index.php/Special:Emailuser/Wotao.yin Wotao Yin] would be delighted to hear from you if you find Gurobi Mex useful, or if you have any suggestions, contributions, or bug reports.
-
Wotao Yin (''wotao.yin AT rice.edu'')
+
-
== How to cite ==
+
== Download, Installation, and Limitations ==
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/download_request.html v1.61] ('''Gurobi 4''') latest version C source code and MATLAB examples.
-
Wotao Yin. ''Gurobi Mex: A MATLAB interface for Gurobi'', URL: http://www.caam.rice.edu/~wy1/gurobi_mex, 2009-2010.
+
Updated 4th output argument to make it easy to access version numbers.
 +
 
 +
=== History ===
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/download_request.html v1.60] ('''Gurobi 4''') New features: support four new attributes introduced in Gurobi v4.6: Sifting, SiftMethod, ZeroObjNodes, and PreSparsify; versions of Gurobi library and this interface are displayed and returned.
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.55.zip v1.55] ('''Gurobi 4''') New features: support the new options introduced in Gurobi v4.5; support the output of reduced costs and constraint slacks.
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.50.zip v1.50] ('''Gurobi 4''') New features: quadratic programming with no linear constraints. Fixed bugs on handling SOS constraints on 64-bit systems.
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.45.zip v1.45] ('''Gurobi 4''') New features: quadratic programming, MIP start vector. Fixed a bug on reporting unsupported options. Dattorro added support for all Gurobi options. Gurobi 4 changed parameter name "LPMethod" to "Method".
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.35.zip v1.35] ('''Gurobi 2&3''') New features: support of [http://www.google.com/search?q=special+ordered+set+SOS Special Ordered Sets (SOS)] constraints of types 1 and 2; support all Gurobi parameters and a new option TrapCtrlC; detection of unrecognized options. Fixed minor display issues. Dattorro added support for all Gurobi options.
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.30.zip v1.30] Short release for SOS support.
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.20.zip v1.20] New features: [http://www.caam.rice.edu/~wy1/links/mex_ctrl_c_trick/ Ctrl-C detection], '''Gurobi 3''' support. Improved error and exception handling. Empty array [] is returned if an output argument is not available. Fixed the display interval option.
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.10.zip v1.10] New features: callback, runtime progress output, flexible log file, flexible input types, more options. Part of the code was contributed by ''Tomáš Strnad''.
 +
Known bug: print an empty line even if options '''DisplayInterval''' and '''Display''' are both set to
 +
<font face="Times">0</font>. Fix: remove Line 736 of ''gurobi_mex.c'': mexPrintf("\n");
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.05.zip v1.05] Major bug fix: char array of constraint sense has been fixed
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.04.zip v1.04] support writing model to files in various formats such as MPS, REW, LP, ...
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.03.zip v1.03] support log file
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.02.zip v1.02] fixed a memory leak issue
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.01.zip v1.01] update: support output dual solution lambda; allow vartypes to be empty (for all continuous variables).
 +
 
 +
[http://www.caam.rice.edu/~wy1/gurobi_mex/gurobi_mex_v1.0.zip v1.00] initial version.
 +
 
 +
=== Future Release ===
 +
Please send your suggested features to [http://www.convexoptimization.com/wikimization/index.php/Special:Emailuser/Wotao.yin Wotao Yin].
 +
 
 +
=== Install Gurobi Mex in MATLAB ===
 +
 
 +
==== Step 1. Install Gurobi ====
 +
Download and install Gurobi. Refer to Gurobi's installation guide. Make sure that (i) proper environment variables are set, and (ii) your copy of Gurobi has a valid license.
 +
 
 +
==== Step 2. Install C++ Compiler ====
 +
Download and install a supported C/C++ compiler for your copy of MATLAB. Do not use the built-in compiler ''lcc'', which cannot link with Gurobi's library. A list of compatible compilers can be found [http://www.mathworks.com/support/compilers/ here].
 +
 
 +
For Linux and Mac, ''gcc'' is a typical choice. Mac users can get ''gcc'' in Apple Xcode.
 +
 
 +
For Windows, one can use Microsoft's Visual C++ compiler. It is included in the free Microsoft Visual C++ Express (MSVC Express).
 +
 
 +
On 64-bit Windows, both MSVC Express and Windows SDK are needed. Google for "Windows SDK" and you will find a Microsoft webpage from where you can download and install the SDK (7.1 is the latest version as of Spring 2012). Only the compiler, headers and library, and .NET parts of the SDK are needed. An example can be found [http://www.mathworks.com/support/solutions/en/data/1-ECUGQX/ here].
 +
 
 +
Once a compiler is installed, run ''mex -setup'' in MATLAB, which shall automatically locates a compiler and generates a configuration file.
 +
 
 +
==== Step 3. Compiling Gurobi Mex ====
 +
Automated compiling (still under test; your feedback is welcome): download [http://www.caam.rice.edu/~wy1/gurobi_mex/compile_mex.zip this zip-file] and unzip in the same folder of gurobi_mex.c. In MATLAB, run ''compile_mex'' and then ''gurobi_mex''. If no error, congratulations! You are good to go.
 +
 
 +
In MATLAB, go to the folder where ''gurobi_mex.c'' is saved and call ''mex'' as follows:
 +
 
 +
===== Step 3a. Windows =====
 +
 
 +
mex -O -I"<gurobi include path>" "<gurobi_mex.c>" "<gurobi C library file>" "<MATLAB libut.lib>"
 +
 
 +
For 64-bit MATLAB, add option "-largeArrayDims".
 +
 
 +
Example with '''Gurobi 4.51''', MSVC2010 Express, MATLAB 2011a, and '''64-bit Windows''':
 +
 
 +
mex -O -largeArrayDims -I"C:\Gurobi451\win64\include" "C:\folder\gurobi_mex.c"...
 +
"C:\Gurobi451\win64\lib\gurobi45.lib" "C:\Program Files\MATLAB\R2011a\extern\lib\win64\microsoft\libut.lib"
 +
 
 +
Example with '''Gurobi 4.52''', MSVC2010 Express, MATLAB 2011a, and '''32-bit Windows''':
 +
 
 +
mex -O -I"C:\Gurobi452\win32\include" "C:\folder\gurobi_mex.c" "C:\Gurobi452\win32\lib\gurobi45.lib"...
 +
"C:\Program Files\MATLAB\R2011a\extern\lib\win32\microsoft\libut.lib"
 +
 
 +
===== Missing libut.lib? =====
 +
Ctrl-C detection requires libut.lib. If it is not found under your copy of MATLAB, you can download one for [http://www.caam.rice.edu/~wy1/gurobi_mex/libut_32bit/libut.lib 32-bit Windows] and [http://www.caam.rice.edu/~wy1/gurobi_mex/libut_64bit/libut.lib 64-bit Windows] (courtesy of Imre Polik).
 +
 
 +
Alternatively, libut.lib can be manually generated by creating a .def text file including the following five lines
 +
LIBRARY libut.dll
 +
EXPORTS
 +
utIsInterruptPending
 +
utSetInterruptPending
 +
[empty line]
 +
and then calling lib.exe (included in MSVC) like
 +
"C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\lib" /def:libut.def /out:libut.lib /machine:x86
 +
where /machine:x86 should be replaced by /machine:x64 for 64-bit Windows.
 +
 
 +
===== Step 3b. Linux/Unix/OS X =====
 +
 
 +
mex -O -I"<gurobi include path>" "<gurobi_mex.c>" -L"<gurobi lib path>" -l<gurobi C library file> -lut
 +
 
 +
For 64-bit MATLAB, add option "-largeArrayDims".
 +
 
 +
Example with '''Gurobi 3''', GCC, MATLAB 2009B, and 64-bit Linux
 +
 
 +
mex -O -I"/opt/gurobi300/linux64/include" "/home/wotao/gurobi mex/gurobi_mex.c" -L"/opt/gurobi300/linux64/lib" -lgurobi30 -lut -largeArrayDims
 +
 
 +
For OS X, see http://www.mathworks.com/support/solutions/en/data/1-FR6LXJ/ for a patch. This patch fixes general problems with mex for Mac.
 +
 
 +
==== Tested platforms ====
 +
 
 +
* 64-bit Ubuntu Linux 9.10, 64-bit MATLAB, and gcc.
 +
* 32-bit Windows, 32-bit MATLAB, and gcc (part of free [http://gnumex.sourceforge.net Mingw/GnuMex], alternatively [http://tdm-gcc.tdragon.net TDM-GCC]).
 +
* 32-bit Windows, 32-bit MATLAB, and MSVC 2008 SP1 (the express Edition is free).
 +
* 64-bit Windows, 64-bit MATLAB, and MSVC 2008 SP1 (the express Edition is free). Courtesy of Imre Polik.
 +
* 64-bit Windows, 64-bit MATLAB, and MSVC 2010 Express.
 +
* 64-bit OS-X Lion (10.7.5), 64-bit MATLAB, and gcc (required patch: http://www.mathworks.com/support/solutions/en/data/1-FR6LXJ/)
 +
For 64-bit MATLAB, Jon Dattorro suggests a [http://www.mathworks.com/support/solutions/en/data/1-8FJXQE/index.html?solution=1-8FJXQE bug fix].
 +
 
 +
== FAQs ==
 +
=== compiling is successful, but gurobi_mex cannot run ===
 +
 
 +
'''Solution''': check and correct Gurobi license and environment variables
 +
 
 +
Step 1. Check and validate [http://www.gurobi.com/doc/40/quickstart/node2.html Gurobi license]
 +
 
 +
Step 2. Check [http://gurobi.com/doc/40/quickstart/node1.html system environment variables for Gurobi]
 +
 
 +
Step 3. Verify MATLAB knows the correct system environment variables by running
 +
>> getenv('GUROBI_HOME')
 +
>> getenv('GRB_LICENSE_FILE')
 +
>> getenv('PATH')
 +
>> getenv('LD_LIBRARY_PATH') % on Unix/Linux/Mac
 +
You may need to restart MATLAB '''from the terminal''' to get all environment variables loaded to MATLAB.
 +
 
 +
=== "int32" or "int64" errors ===
 +
 
 +
'''Solution''': use int32 if sizeof(int) is 4 for your system; use int64 if sizeof(int) is 8. To determine sizeof(int), take the following steps
 +
 
 +
Step 1. create "check_sizeof_int.c" with the following lines
 +
 
 +
#include "mex.h"
 +
void mexFunction(
 +
int nlhs, mxArray *plhs[],
 +
int nrhs, const mxArray *prhs[]
 +
)
 +
{
 +
mexPrintf("Size of int is %d\n", sizeof(int));
 +
return;
 +
}
 +
 
 +
Step 2. Launch Matlab, run '''mex check_sizeof_int.c''', and then run '''check_sizeof_int'''
 +
 
 +
=== MATLAB reports "out of memory" ===
 +
 
 +
'''Solution''': run ''clear mex'' after each call to gurobi_mex
 +
 
 +
Running out of memory is often the result of memory leaks. However, the interface has been checked numerous times for memory leaks. If there still appears to be a leak, we are not sure if it is with the interface, Gurobi, or MATLAB itself.
 +
 
 +
=== Gurobi Mex in a loop returns incorrect solutions ===
 +
 
 +
'''Try''': double check whether the fields of ''opts'' are correctly updated in the loop; one often forgets cleaning up some fields, so data in the previous iteration is inadvertently used the new iteration. if not work
 +
 
 +
'''Try''': use ''opts.WriteToFile=my_data.mps'' to generate data files and inspect the input data for errors. if not work
 +
 
 +
'''Then Try''': run ''clear mex'' after each call to gurobi_mex
== License ==
== License ==
-
Creative Commons Attribution-Share Alike 3.0 United States License
+
Creative Commons Attribution-Share Alike 3.0 United States License.
Allow commercial use of this work. Permit others to copy, distribute, display, and perform the work, including for commercial purposes.
Allow commercial use of this work. Permit others to copy, distribute, display, and perform the work, including for commercial purposes.
Allow modification, as long as others share alike. Permit others to distribute derivative works only under the same license or one compatible with the one that governs the licensor's work.
Allow modification, as long as others share alike. Permit others to distribute derivative works only under the same license or one compatible with the one that governs the licensor's work.
 +
 +
== How to cite ==
 +
 +
Wotao Yin. ''Gurobi Mex: A MATLAB interface for Gurobi'', URL: http://convexoptimization.com/wikimization/index.php/gurobi_mex, 2009-2011.
 +
 +
(Your formal citing of this free interface in your research papers will motivate the author to keep this interface up to date with Gurobi, as well as enriching its functions and making it easier to use.)

Revision as of 15:40, 25 September 2012

Gurobi Mex is a free MATLAB interface for Gurobi 2, 3, and 4 written by Wotao Yin with contributions by Jon Dattorro, Imre Polik, and Tomáš Strnad. It calls Gurobi to solve linear/quadratic/mixed-integer optimization problems. Gurobi offers free trial and free academic license.

This interface is open source and subject to Creative Commons Attribution-Share Alike 3.0 United States License. It is a tool for MATLAB users to quickly call Gurobi. Its source code may also serve as a starting point for those who want to develop a customized MATLAB interface for Gurobi.

It is not trivial to write a good interface (it is about two thousand lines of code). If you find this interface useful, please credit it in your publications [bibtex] [Endnote] [text], as this will motivate the author to keep the interface up to date with the latest Gurobi, as well as improving its functions and making it easier to use.

Current version 1.61 was published November 16, 2011. [Skip to Download Section]



Contents

Model (LP, QP, MIP, MIQP)

 min/max  x'Cx + c'x

 subject to  
  Ax >= / <= / = b,  
  lb <= x <= ub,
  SOS constraints,
  x(i) is continuous / binary / integer / semi-continuous / semi-integer.

Syntax

x = gurobi_mex(c, objtype, A, b, contypes, lb, ub, vartypes);
x = gurobi_mex(c, objtype, A, b, contypes, lb, ub, vartypes, opts);
[x,val] = gurobi_mex(...);
[x,val,flag] = gurobi_mex(...);
[x,val,flag,output] = gurobi_mex(...);
[x,val,flag,output,lambda] = gurobi_mex(...);

Input Description

  • c: objective coefficient vector, double type.
[] (empty array) means uniformly 0 coefficients, and scalar means all coefficients equal to scalar.
  • objtype: 1 (minimization) or -1 (maximization).
  • A: constraint coefficient matrix, double type, sparse.
  • b: constraint right-hand side vector, double type.
Gurobi takes a dense vector for this input. If a sparse vector is specified, it will be converted to full by Gurobi Mex.
  • contypes: constraint types. Char array of '>', '<', '='.
Warning: '>=' specifies two constraints, not one.
Example: '>><=' specifies four constraints. The first two constraints have greater or equal to signs, the third has less than or equal to sign, and the last is an equality constraint.
If a single character is specified, it will be applied to all constraints uniformly.
  • lb: variable lower bound, double type, either scalar or vector.
[] (empty array) means 0 lower bound. -inf means no lower bound. If a scalar is specified, it will be the uniform lower bound for all variables.
  • ub: variable upper bound, double type, either scalar or vector.
[] (empty array) means no (or infinity) upper bound. If a scalar is specified, it will be the uniform upper bound for all variables.
  • vartypes: variable types, char array of 'C', 'B', 'I', 'S', 'N'. 'C' for continuous; 'B' for binary; 'I' for integer; 'S' for semi-continuous; 'N' for semi-integer. [] (empty array) means all variables are continuous.
Example: 'CCCCC' specifies five continuous variables.
Note that a semi-continuous variable is one that must be either zero or a value between its minimum and maximum. Semi-integer variables are similarly defined.
If a single character is specified, all variables will be signed to the corresponding type uniformly.

Gurobi Parameters

  • opts: optional structure that may have any number of following parameters.
    • opts.[any Gurobi parameter]: See Gurobi Parameters for their allowed values.
    • opts.QP: Quadratic objective terms. See here.
    • opts.SOS: Special ordered set constraints. See here.
    • opts.Start: MIP start vector, or Gurobi's attribute 'Start'. See here.
    • opts.TrapCtrlC: true (to trap Ctrl-C) or false (not to trap Ctrl-C).
    • opts.Display: screen output level. 0 (no output); 1 (version and error messages only); 2 (default output). For complete silence, set opts.DisplayInterval=0 and opts.OutputFlag=0 (to silence Gurobi) and opts.Display=0 (to make Gurobi Mex silent).
    • opts.WriteToFile: char array of the name of the file to which optimization data is written. See Gurobi C-Reference entry GRBwrite for supported formats. This option helps one verify whether the model is correctly passed to Gurobi.

Output Description

  • x: primal solution vector; empty if Gurobi encounters errors or stops early (in this case, check output flag).
  • val: optimal objective value; empty if Gurobi encounters errors or stops early.
  • flag: value meanings:
    • [ ] (empty 1x1 array) general failure
    • 1 for not started
    • 2 for optimal
    • 3 for infeasible
    • 4 for infeasible or unbounded
    • 5 for unbounded
    • 6 for objective worse than user-specified cutoff
    • 7 for reaching iteration limit
    • 8 for reaching node limit
    • 9 for reaching time limit
    • 10 for reaching solution limit
    • 11 for user interruption
    • 12 for numerical difficulties
    • 13 for suboptimal solution (Gurobi 3 and later)
  • output: structure contains the following fields
    • output.IterCount: number of Simplex iterations
    • output.Runtime: running time in seconds
    • output.ErrorMsg: contains Gurobi error message, if any
    • output.Versions.GurobiMex: version of this interface (supported by v1.61 and later)
    • output.Versions.LibMajor, output.Versions.LibMinor, and output.Versions.LibTechi: Gurobi library version (supported by v1.61 and later)
  • lambda: constraint dual variables (up to v1.50) or structure contains the following fields (v1.55 and later)
    • lambda.RC: reduced cost
    • lambda.Pi: constraint dual variables
    • lambda.Slack: constraint slack variables

Notes

Quadratic Programming

Gurobi 4 and later solve quadratic programs. The quadratic terms in the objective function should be specified by opts.QP.qrow, opts.QP.qcol, and opts.QP.qval, which correspond to the input arguments qrow, qcol, and qval of function GRBaddqpterms. They are all 1D arrays. The first two arguments, qrow and qcol, specify the row and column indices (starting from 0) of 2nd-order terms such as LaTeX: x_1^2 and LaTeX: x_1 x_2\,. The third argument, qval, gives their coefficients. An example is given below.

To solve a quadratic program with no constraints, set A = [], b = [], and contypes = [].


SOS Constraints

SOS stands for Special Ordered Sets. This mex program uses opts.SOS.weights and opts.SOS.types to pass SOS constraints to Gurobi. opts.SOS.weights is a sparse matrix describing the weights of SOS variables, and opts.SOS.types a 1D array of type int32 or int64 (if sizeof(int) is 4 for your system, then you should use int32; if 8, use int64), which specifies the constraint types. Here is an example with 4 variables and 3 SOS constraints:

SOS1: x1 = 0 or x2 = 0
SOS1: x1 = 0 or x3 = 0
SOS2: (x1, x3, x2, x4)

The corresponding code for a 32-bit system is

 opts.SOS.weights = sparse([
  1 1 1; 
  2 0 3; 
  0 2 2; 
  0 0 4]);
 opts.SOS.types = int32([1 1 2]);

The ith column of opts.SOS.weights specifies the weights (i.e., orders) of the variables in the ith SOS constraint.


MIP Start Vector

To specify an MIP start vector (supported since v1.45), say x = [1 0 3 2], one can use one of the following two ways:

opts.Start = [1 0 3 2];

or

opts.Start.pos = int32([0 1 2 3]); % use int64 if sizeof(int) is 8 for your system
opts.Start.val = [1 0 3 2];

To specify start values for a subset of variables, for example to set x = [? ? -1 2], where ? means undefined, one can choose either one of the following two ways

GRB_UNDEFINED = 1e101;
opts.Start = [GRB_UNDEFINED  GRB_UNDEFINED  -1 2];

or

opts.Start.pos = int32([2 3]); % use int64 if sizeof(int) is 8 for your system
opts.Start.val = [-1 2];

How to pass a parameter from MATLAB to Gurobi?

v1.35 and v1.45 support all parameters of Gurobi 3 and 4, respectively. However, if you want to specify a new or undocumented Gurobi parameter of your interest, you can DIY very easily. Suppose that we want to set a double-type parameter called SecretPara in MATLAB and pass it through this mex interface to Gurobi. Because the parameter TimeLimit has the same (double) type and it is already supported by this mex program, we can copy the code for TimeLimit, replace TimeLimit by SecretPara in the code, and paste it at Line 1250 of v1.35 (or Line 510 of v1.30), just before the mex program checks unrecognized input option fields. After compiling gurobi.c, the modified mex will let you assign a double value to opts.SecretPara. We compare the code for TimeLimit and SecretPara below where the differences are italicized:

       /* Option TimeLimit */
       field_n = mxGetFieldNumber(IN_OPTS, "TimeLimit");
       if (field_n != -1) {
           field = mxGetFieldByNumber(IN_OPTS,0,field_n);
           bOpts[field_n] = true;
           if (!mxIsDouble(field) || mxIsComplex(field) || mxIsEmpty(field)) {
                mexPrintf("Option TimeLimit must be real positive double (0 to inf).");
                goto QUIT;
           }
           error = GRBsetdblparam(env, "TimeLimit", mxGetScalar(field));
           if (error) goto QUIT;
       }
       /* Option SecretPara */
       field_n = mxGetFieldNumber(IN_OPTS, "SecretPara");
       if (field_n != -1) {
           field = mxGetFieldByNumber(IN_OPTS,0,field_n);
           bOpts[field_n] = true;
           if (!mxIsDouble(field) || mxIsComplex(field) || mxIsEmpty(field)) {
                mexPrintf("Option SecretPara must real double (?? through ??).");
                goto QUIT;
           }
           error = GRBsetdblparam(env, "SecretPara", mxGetScalar(field));
           if (error) goto QUIT;
       }

Note that you must start from a parameter of the same type (int, double, or string). In case memory allocation is needed, use mxCalloc and make sure that mxFree has been called whenever the mex program exits, normally or not.

Callbacks

Callbacks are useful to obtain the progress of Gurobi (e.g., by calling GRBcbget) and to modify its behavior during runtime (e.g., by calling GRBcbcut and GRBcbsolution).

Gurobi Mex implements a callback function mycallback to obtain Gurobi's progress messages and print them on the MATLAB screen. The print frequency is set in opts.DisplayInterval (in seconds). The same function is also used to detect user input Ctrl-C.

Information for Gurobi callbacks can be found here in Gurobi's help. An example can be found here.

Examples

Example 1. Linear programming

This example is borrowed from MATLAB's linprog help.

Problem:

 min –5 x1 – 4 x2 –6 x3,

 subject to
  x1 – x2 + x3 ≤ 20
  3 x1 + 2 x2 + 4 x3 ≤ 42
  3 x1 + 2 x2 ≤ 30
  0 ≤ x1, 0 ≤ x2, 0 ≤ x3.

MATLAB code:

 c = [-5; -4; -6];
 objtype = 1;
 A =  sparse([1 -1  1; 3  2  4; 3  2  0]);
 b = [20; 42; 30];
 lb = zeros(3,1);           % same as lb = [];
 ub = [];
 contypes = '<<<';
 vtypes = [];               % same as vtypes = 'CCC'; [] means 'C...C'

 clear opts
 opts.IterationLimit = 20;
 opts.FeasibilityTol = 1e-6;
 opts.IntFeasTol = 1e-5;
 opts.OptimalityTol = 1e-6;
 opts.Method = 1;         % 0 - primal, 1 - dual
 opts.Presolve = -1;        % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
 opts.Display = 1;
 opts.LogFile = 'test_gurobi_mex_LP.log';     % optional
 opts.WriteToFile = 'test_gurobi_mex_LP.mps'; % optional; it can cause a long delay if problem is large

 [x,val,exitflag,output,lambda] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);

Results:

 x' = 
    0 15 3

 val = 
    -78

 exitflag =
    2

 output =
    IterCount: 2
      Runtime: 0
     ErrorMsg: []

 lambda' =
    0   -1.5000   -0.5000

Log file: test_gurobi_mex_LP.log. MPS file: test_gurobi_mex_LP.mps.

Example 2. Integer programming

This example is borrowed from mip1_c.c of Gurobi 2.

Problem:

 max  x + y + 2z,

 subject to
  x + 2 y + 3 z <= 4
  x +   y       >= 1
  x, y, z binary.

MATLAB code:

 c = [1; 1; 2];
 objtype = -1;              % 1 for minimize, -1 for maximize
 A =  sparse([1 2 3; 1 1 0]);
 b = [4; 1];
 lb = [];
 ub = [];
 contypes = '<>';
 vtypes = 'BBB';

 clear opts
 opts.IterationLimit = 20;
 opts.FeasibilityTol = 1e-6;
 opts.IntFeasTol = 1e-5;
 opts.OptimalityTol = 1e-6;
 opts.Method = 1;         % 0 - primal, 1 - dual
 opts.Presolve = -1;        % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
 opts.Display = 1;
 opts.LogFile = 'test_gurobi_mex_MIP.log';
 opts.WriteToFile = 'test_gurobi_mex_MIP.mps';  % this option can cause a long delay if problem is large

 [x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);

Gurobi does not give lambda (Pi, or Lagrange multipliers) for MIPs, unless model fix is called.

Results:

 disp('Solution:');disp(x')
 disp('Optimal obj value:');disp(val)
 disp('Exit flag:');disp(exitflag)
 disp('Optimization info:');disp(output)

 Solution:
     1     0     1

 Optimal obj value:
     3

 Exit flag:
     2

 Optimization info:
    IterCount: 0
      Runtime: 0
     ErrorMsg: []

Log file: test_gurobi_mex_MIP.log. MPS file: test_gurobi_mex_MIP.mps.

Example 3. Feasibility test

Problem:

Find a solution or report infeasibility of

  5 x1 + 4 x2        + 5 x4 >= -21
  5 x1 + 3 x2 + 1 x3 + 4 x4  = -14
  3 x1 + 5 x2 + 2 x3 - 5 x4  =  11
  x1,x2,x3,x4 >= 0.

MATLAB code:

 c = [];                    % use [] or 0 for null objective
 objtype = -1;              % 1 for minimize, -1 for maximize
 A =  sparse([5 4 0 5; 5 3 1 4; 3 5 2 -5]);
 b = [-21; -14; 11];        
 lb = [];                   % stands for 0 lower bound uniformly 
 ub = [];                   % stands for inf upper bound uniformly 
 contypes = '>==';
 vtypes = [];               % same as vtypes = 'CCCC'

 clear opts
 opts.FeasibilityTol = 1e-6;
 opts.Presolve = -1;        % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
 opts.Display = 1;
 opts.LogFile = 'test_gurobi_mex_Feasibility.log';
 opts.WriteToFile = 'test_gurobi_mex_Feasibility.mps';  % this option can cause a long delay if problem is large

 [x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);

Results:

 disp('Solution:');disp(x')
 disp('Optimal obj value:');disp(val)
 disp('Exit flag:');disp(exitflag)

 Model is infeasible. No solution will be returned.

 Solution:
 Optimal obj value:
 Exit flag:
     3

Log file: test_gurobi_mex_Feasibility.log. MPS file: test_gurobi_mex_Feasibility.mps.

Example 4. SOS constraint test

Problem:

min –3 x1 – 1 x2 – 1 x3,

subject to
  x1 + x2 + x3 <= 2,
  0 <= x1 <= 1, 0 <= x2 <= 1, 0 <= x3 <= 2,
  SOS type 1: x1 = 0 or x2 = 0,
  SOS type 1: x1 = 0 or x3 = 0.

MATLAB code:

 c = [-3; -1; -1];
 objtype = 1;
 A =  sparse([1 1 1]);
 b = 2;
 lb = []; % means 0 lower bound
 ub = [1 1 2];
 contypes = '<';
 vtypes = []; % same as vtypes = 'CCC'
 sos.weights = sparse([1 1; 2 0; 0 2]);
 sos.types = int32([1 1]);   % Both the SOS constraints are of type 1

 clear opts
 opts.FeasibilityTol = 1e-6;
 opts.Presolve = -1;        % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
 opts.Display = 1;
 opts.LogFile = 'test_gurobi_mex_Feasibility.log';
 opts.WriteToFile = 'test_gurobi_mex_Feasibility.mps';

 [x,val,exitflag,output] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);

Results:

 Optimal solution found (tolerance 1.00e-04)
 Best objective -3.0000000000e+00, best bound -3.0000000000e+00, gap 0.0%
 
 Solution:
     1     0     0

Log file: test_gurobi_mex_SOS.log. MPS file: test_gurobi_mex_SOS.mps.

Example 5. Quadratic programming

This example appears in MATLAB Help entry for quadprog.

Problem:

min 0.5 x0^2 - x0*x1 + x1^2 - 2*x0 - 6*x1,

subject to
   x0 +  x1 <= 2,
  -x0 + 2x1 <= 2,
  2x0 +  x1 <= 3,
  x0 >= 0, x1 >= 0.

MATLAB code:

 clear opts

 c = [-2 -6];    % objective linear term
 objtype = 1;    % minimization
 A =  sparse([1 1; -1 2; 2 1]); % constraint coefficients
 b = [2; 2; 3];  % constraint right-hand side
 lb = [];        % [] means 0 lower bound
 ub = [];        % [] means inf upper bound
 contypes = '<<<'; % three <= inequalities
 vtypes = [];      % [] means all variables are continuous
 % note that 0.5 x0^2 - x0*x1 + x1^2 = 0.5 x0*x0 - x0*x1 + x1*x1
 opts.QP.qrow = int32([0 0 1]); % indices of leading   variables (x0), (x0), (x1) in 0.5 (x0)*x0 - (x0)*x1 + (x1)*x1
 opts.QP.qcol = int32([0 1 1]); % indices of following variables (x0), (x1), (x1) in 0.5 x0*(x0) - x0*(x1) + x1*(x1)
 opts.QP.qval = [0.5 -1 1];     % coefficients of 0.5 x0^2 - x0*x1 + x1^2

 opts.IterationLimit = 200;
 opts.FeasibilityTol = 1e-6;
 opts.IntFeasTol = 1e-5;
 opts.OptimalityTol = 1e-6;

 [x,val,exitflag,output,lambda] = gurobi_mex(c,objtype,A,b,contypes,lb,ub,vtypes,opts);

 disp('Solution:');disp(x')
 disp('Optimal obj value:');disp(val)
 disp('Exit flag:');disp(exitflag)
 disp('Optimization info:');disp(output)
 disp('Lagrange multiplers:');disp(lambda')

Results:

 Solution:
    0.6667    1.3333
 Optimal obj value:
   -8.2222
 Exit flag:
     2
 Optimization info:
    IterCount: 4
      Runtime: 0.0630
     ErrorMsg: []
 Lagrange multiplers:
   -3.1111   -0.4444         0

Example 6. Mixed integer quadratic programming

See example m-file test_gurobi_mex_MIQP.m.

Example 7. Compressive sensing

See example m-file test_gurobi_mex_CS.m.

Feedback

Wotao Yin would be delighted to hear from you if you find Gurobi Mex useful, or if you have any suggestions, contributions, or bug reports.

Download, Installation, and Limitations

v1.61 (Gurobi 4) latest version C source code and MATLAB examples.

Updated 4th output argument to make it easy to access version numbers.

History

v1.60 (Gurobi 4) New features: support four new attributes introduced in Gurobi v4.6: Sifting, SiftMethod, ZeroObjNodes, and PreSparsify; versions of Gurobi library and this interface are displayed and returned.

v1.55 (Gurobi 4) New features: support the new options introduced in Gurobi v4.5; support the output of reduced costs and constraint slacks.

v1.50 (Gurobi 4) New features: quadratic programming with no linear constraints. Fixed bugs on handling SOS constraints on 64-bit systems.

v1.45 (Gurobi 4) New features: quadratic programming, MIP start vector. Fixed a bug on reporting unsupported options. Dattorro added support for all Gurobi options. Gurobi 4 changed parameter name "LPMethod" to "Method".

v1.35 (Gurobi 2&3) New features: support of Special Ordered Sets (SOS) constraints of types 1 and 2; support all Gurobi parameters and a new option TrapCtrlC; detection of unrecognized options. Fixed minor display issues. Dattorro added support for all Gurobi options.

v1.30 Short release for SOS support.

v1.20 New features: Ctrl-C detection, Gurobi 3 support. Improved error and exception handling. Empty array [] is returned if an output argument is not available. Fixed the display interval option.

v1.10 New features: callback, runtime progress output, flexible log file, flexible input types, more options. Part of the code was contributed by Tomáš Strnad. Known bug: print an empty line even if options DisplayInterval and Display are both set to 0. Fix: remove Line 736 of gurobi_mex.c: mexPrintf("\n");

v1.05 Major bug fix: char array of constraint sense has been fixed

v1.04 support writing model to files in various formats such as MPS, REW, LP, ...

v1.03 support log file

v1.02 fixed a memory leak issue

v1.01 update: support output dual solution lambda; allow vartypes to be empty (for all continuous variables).

v1.00 initial version.

Future Release

Please send your suggested features to Wotao Yin.

Install Gurobi Mex in MATLAB

Step 1. Install Gurobi

Download and install Gurobi. Refer to Gurobi's installation guide. Make sure that (i) proper environment variables are set, and (ii) your copy of Gurobi has a valid license.

Step 2. Install C++ Compiler

Download and install a supported C/C++ compiler for your copy of MATLAB. Do not use the built-in compiler lcc, which cannot link with Gurobi's library. A list of compatible compilers can be found here.

For Linux and Mac, gcc is a typical choice. Mac users can get gcc in Apple Xcode.

For Windows, one can use Microsoft's Visual C++ compiler. It is included in the free Microsoft Visual C++ Express (MSVC Express).

On 64-bit Windows, both MSVC Express and Windows SDK are needed. Google for "Windows SDK" and you will find a Microsoft webpage from where you can download and install the SDK (7.1 is the latest version as of Spring 2012). Only the compiler, headers and library, and .NET parts of the SDK are needed. An example can be found here.

Once a compiler is installed, run mex -setup in MATLAB, which shall automatically locates a compiler and generates a configuration file.

Step 3. Compiling Gurobi Mex

Automated compiling (still under test; your feedback is welcome): download this zip-file and unzip in the same folder of gurobi_mex.c. In MATLAB, run compile_mex and then gurobi_mex. If no error, congratulations! You are good to go.

In MATLAB, go to the folder where gurobi_mex.c is saved and call mex as follows:

Step 3a. Windows
mex -O -I"<gurobi include path>" "<gurobi_mex.c>" "<gurobi C library file>" "<MATLAB libut.lib>"

For 64-bit MATLAB, add option "-largeArrayDims".

Example with Gurobi 4.51, MSVC2010 Express, MATLAB 2011a, and 64-bit Windows:

mex -O -largeArrayDims -I"C:\Gurobi451\win64\include" "C:\folder\gurobi_mex.c"...
"C:\Gurobi451\win64\lib\gurobi45.lib" "C:\Program Files\MATLAB\R2011a\extern\lib\win64\microsoft\libut.lib"

Example with Gurobi 4.52, MSVC2010 Express, MATLAB 2011a, and 32-bit Windows:

mex -O -I"C:\Gurobi452\win32\include" "C:\folder\gurobi_mex.c" "C:\Gurobi452\win32\lib\gurobi45.lib"...
"C:\Program Files\MATLAB\R2011a\extern\lib\win32\microsoft\libut.lib"
Missing libut.lib?

Ctrl-C detection requires libut.lib. If it is not found under your copy of MATLAB, you can download one for 32-bit Windows and 64-bit Windows (courtesy of Imre Polik).

Alternatively, libut.lib can be manually generated by creating a .def text file including the following five lines

LIBRARY libut.dll
EXPORTS
utIsInterruptPending
utSetInterruptPending
[empty line]

and then calling lib.exe (included in MSVC) like

"C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\lib" /def:libut.def /out:libut.lib /machine:x86

where /machine:x86 should be replaced by /machine:x64 for 64-bit Windows.

Step 3b. Linux/Unix/OS X
mex -O -I"<gurobi include path>" "<gurobi_mex.c>" -L"<gurobi lib path>" -l<gurobi C library file> -lut

For 64-bit MATLAB, add option "-largeArrayDims".

Example with Gurobi 3, GCC, MATLAB 2009B, and 64-bit Linux

mex -O -I"/opt/gurobi300/linux64/include" "/home/wotao/gurobi mex/gurobi_mex.c" -L"/opt/gurobi300/linux64/lib" -lgurobi30 -lut -largeArrayDims

For OS X, see http://www.mathworks.com/support/solutions/en/data/1-FR6LXJ/ for a patch. This patch fixes general problems with mex for Mac.

Tested platforms

  • 64-bit Ubuntu Linux 9.10, 64-bit MATLAB, and gcc.
  • 32-bit Windows, 32-bit MATLAB, and gcc (part of free Mingw/GnuMex, alternatively TDM-GCC).
  • 32-bit Windows, 32-bit MATLAB, and MSVC 2008 SP1 (the express Edition is free).
  • 64-bit Windows, 64-bit MATLAB, and MSVC 2008 SP1 (the express Edition is free). Courtesy of Imre Polik.
  • 64-bit Windows, 64-bit MATLAB, and MSVC 2010 Express.
  • 64-bit OS-X Lion (10.7.5), 64-bit MATLAB, and gcc (required patch: http://www.mathworks.com/support/solutions/en/data/1-FR6LXJ/)

For 64-bit MATLAB, Jon Dattorro suggests a bug fix.

FAQs

compiling is successful, but gurobi_mex cannot run

Solution: check and correct Gurobi license and environment variables

Step 1. Check and validate Gurobi license

Step 2. Check system environment variables for Gurobi

Step 3. Verify MATLAB knows the correct system environment variables by running

>> getenv('GUROBI_HOME')
>> getenv('GRB_LICENSE_FILE')
>> getenv('PATH')
>> getenv('LD_LIBRARY_PATH') % on Unix/Linux/Mac

You may need to restart MATLAB from the terminal to get all environment variables loaded to MATLAB.

"int32" or "int64" errors

Solution: use int32 if sizeof(int) is 4 for your system; use int64 if sizeof(int) is 8. To determine sizeof(int), take the following steps

Step 1. create "check_sizeof_int.c" with the following lines

#include "mex.h"
 void mexFunction(
      int nlhs,       mxArray *plhs[],
      int nrhs, const mxArray *prhs[]
      )
{
   mexPrintf("Size of int is %d\n", sizeof(int));
   return;
}

Step 2. Launch Matlab, run mex check_sizeof_int.c, and then run check_sizeof_int

MATLAB reports "out of memory"

Solution: run clear mex after each call to gurobi_mex

Running out of memory is often the result of memory leaks. However, the interface has been checked numerous times for memory leaks. If there still appears to be a leak, we are not sure if it is with the interface, Gurobi, or MATLAB itself.

Gurobi Mex in a loop returns incorrect solutions

Try: double check whether the fields of opts are correctly updated in the loop; one often forgets cleaning up some fields, so data in the previous iteration is inadvertently used the new iteration. if not work

Try: use opts.WriteToFile=my_data.mps to generate data files and inspect the input data for errors. if not work

Then Try: run clear mex after each call to gurobi_mex

License

Creative Commons Attribution-Share Alike 3.0 United States License. Allow commercial use of this work. Permit others to copy, distribute, display, and perform the work, including for commercial purposes. Allow modification, as long as others share alike. Permit others to distribute derivative works only under the same license or one compatible with the one that governs the licensor's work.

How to cite

Wotao Yin. Gurobi Mex: A MATLAB interface for Gurobi, URL: http://convexoptimization.com/wikimization/index.php/gurobi_mex, 2009-2011.

(Your formal citing of this free interface in your research papers will motivate the author to keep this interface up to date with Gurobi, as well as enriching its functions and making it easier to use.)

Personal tools