### Table of Contents

- Introduction
- How to Run a Model with Gurobi
- Overview of GAMS/Gurobi
- Multiple Objectives
- GAMS Options
- Summary of GUROBI Options
- GAMS/Gurobi Log File
- Detailed Descriptions of GUROBI Options

**Gurobi Optimization**, www.gurobi.com

# Introduction

The Gurobi suite of optimization products include state-of-the-art simplex and parallel barrier solvers for linear programming (LP) and quadratic programming (QP), parallel barrier solver for quadratically constrained programming (QCP), as well as parallel mixed-integer linear programming (MILP), mixed-integer quadratic programming (MIQP) and mixed-integer quadratically constrained programming (MIQCP) solvers.

The Gurobi MIP solver includes shared memory parallelism, capable of simultaneously exploiting any number of processors and cores per processor. The implementation is deterministic: two separate runs on the same model will produce identical solution paths.

While numerous solving options are available, Gurobi automatically calculates and sets most options at the best values for specific problems. All Gurobi options available through GAMS/Gurobi are summarized at the end of this chapter.

We offer a GAMS/GUROBI link that works in combination with a Gurobi callable library license from Gurobi Optimization Inc. Starting with GAMS distribution 24.7 even demo sized models require a license from Gurobi.

An attempt to use the GAMS/Gurobi solver with a link license that has not been set up properly will result in a licensing error with a message describing the problem. For example, the following message is sent to the log when attempting to solve a model that requires a license:

... --- Executing GUROBI: elapsed 0:00:00.077 Gurobi 24.7.1 r55213 Released Mar 16, 2016 VS8 x86/MS Windows Gurobi link license. *** Cannot initialize Gurobi environment. *** Could be a missing or invalid license. (status=10009|10009) ...

An attempt to solve a demo sized model without a Gurobi license installed results in:

... --- Executing GUROBI: elapsed 0:00:00.013 Gurobi 24.7.1 r55213 Released Mar 16, 2016 VS8 x86/MS Windows GAMS/Gurobi demo requires a Gurobi license from Gurobi Optimization. *** Cannot initialize Gurobi environment. *** Could be a missing or invalid license. (status=10009|10009)

To make GAMS/Gurobi aware of a Gurobi callable library license an environment variable `GRB_LICENSE_FILE`

pointing to license file need to be present. Please consult our support wiki for details. Moreover, GAMS will use it's own Gurobi DLL/shared library, so the Gurobi license has to be valid for the Gurobi version GAMS uses.

Finally, a bare-bone interface to the LP and MIP solver of Gurobi is available under the name OSIGUROBI. It comes free of charge with any GAMS system.

# How to Run a Model with Gurobi

The following statement can be used inside your GAMS program to specify using Gurobi

Option LP = Gurobi; { or MIP or RMIP or QCP or MIQCP or RMIQCP }

The above statement should appear before the `solve`

statement. If Gurobi was specified as the default solver during GAMS installation, the above statement is not necessary.

# Overview of GAMS/Gurobi

## Linear, Quadratic and Quadratic Constrained Programming

Gurobi can solve LP and QP problems using several alternative algorithms, while the only choice for solving QCP is the parallel barrier algorithm. The majority of LP problems solve best using Gurobi's state-of-the-art dual simplex algorithm, while most QP problems solve best using the parallel barrier algorithm. Certain types of LP problems benefit from using the parallel barrier or the primal simplex algorithms, while for some types of QP, the dual or primal simplex algorithm can be a better choice. If you are solving LP problems on a multi-core system, you should also consider using the concurrent optimizer. It runs different optimization algorithms on different cores, and returns when the first one finishes.

GAMS/Gurobi also provides access to the Gurobi infeasibility finder. The infeasibility finder takes an infeasible linear program and produces an irreducibly inconsistent set of constraints (IIS). An IIS is a set of constraints and variable bounds which is infeasible but becomes feasible if any one member of the set is dropped. GAMS/Gurobi reports the IIS in terms of GAMS equation and variable names and includes the IIS report as part of the normal solution listing. The infeasibility finder is activated by the option IIS. Another option for analyzing infeasible model the FeasOpt option which instructs GAMS/Gurobi to find a minimal feasible relaxation of an infeasible model. See section Feasible Relaxation for details.

GAMS/Gurobi supports sensitivity analysis (post-optimality analysis) for linear programs which allows one to find out more about an optimal solution for a problem. In particular, objective ranging and constraint ranging give information about how much an objective coefficient or a right-hand-side and variable bounds can change without changing the optimal basis. In other words, they give information about how sensitive the optimal basis is to a change in the objective function or the bounds and right-hand side. GAMS/Gurobi reports the sensitivity information as part of the normal solution listing. Sensitivity analysis is activated by the option Sensitivity. More about using sensitivity analysis can be found in the section Sensitivity Analysis with GAMS/CPLEX or GAMS/GUROBI.

The Gurobi presolve can sometimes diagnose a problem as being infeasible *or* unbounded. When this happens, GAMS/Gurobi can, in order to get better diagnostic information, rerun the problem with presolve turned off. The rerun without presolve is controlled by the option ReRun. In default mode only problems that are small (i.e. demo sized) will be rerun.

Gurobi can either presolve a model or start from an advanced basis or primal/dual solution pair. Often the solve from scratch of a presolved model outperforms a solve from an unpresolved model started from an advanced basis/solution. It is impossible to determine a priori if presolve or starting from a given advanced basis/solution without presolve will be faster. By default, GAMS/Gurobi will automatically use an advanced basis or solution from a previous `solve`

statement. The GAMS BRatio option can be used to specify when not to use an advanced basis/solution. The GAMS/Gurobi option UseBasis can be used to ignore or force a basis/solution passed on by GAMS (it overrides BRatio). In case of multiple solves in a row and slow performance of the second and subsequent solves, the user is advised to set the GAMS BRatio option to 1.

## Mixed-Integer Programming

The methods used to solve pure integer and mixed integer programming problems require dramatically more mathematical computation than those for similarly sized pure linear or quadratic programs. Many relatively small integer programming models take enormous amounts of time to solve.

For problems with discrete variables, Gurobi uses a branch and cut algorithm which solves a series of subproblems, LP subproblems for MILP, QP subproblems for MIQP, and QCP subproblems or LP outer approximation subproblems for MIQCP. Because a single mixed integer problem generates many subproblems, even small mixed integer problems can be very compute intensive and require significant amounts of physical memory.

GAMS/Gurobi supports Special Order Sets of type 1 and type 2 as well as semi-continuous and semi-integer variables.

You can provide a known solution (for example, from a MIP problem previously solved or from your knowledge of the problem) to serve as the first integer solution.

If you specify some or all values for the discrete variables together with GAMS/Gurobi option MipStart, Gurobi will check the validity of the values as an integer-feasible solution. If this process succeeds, the solution will be treated as an integer solution of the current problem.

The Gurobi MIP solver includes shared memory parallelism, capable of simultaneously exploiting any number of processors and cores per processor. The implementation is deterministic: two separate runs on the same model will produce identical solution paths.

## Feasible Relaxation

The Infeasibility Finder identifies the causes of infeasibility by means of inconsistent set of constraints (IIS). However, you may want to go beyond diagnosis to perform automatic correction of your model and then proceed with delivering a solution. One approach for doing so is to build your model with explicit slack variables and other modeling constructs, so that an infeasible outcome is never a possibility. An automated approach offered in GAMS/Gurobi is known as FeasOpt (for Feasible Optimization) and turned on by parameter FeasOpt in a GAMS/Gurobi option file.

With the FeasOpt option GAMS/Gurobi accepts an infeasible model and selectively relaxes the bounds and constraints in a way that minimizes a weighted penalty function. In essence, the feasible relaxation tries to suggest the least change that would achieve feasibility. It returns an infeasible solution to GAMS and marks the relaxations of bounds and constraints with the INFES marker in the solution section of the listing file.

By default all equations are candidates for relaxation and weighted equally but none of the variables can be relaxed. This default behavior can be modified by assigning relaxation preferences to variable bounds and constraints. These preferences can be conveniently specified with the `.feaspref`

option. The input value denotes the users willingness to relax a constraint or bound. The larger the preference, the more likely it will be that a given bound or constraint will be relaxed. More precisely, the reciprocal of the specified value is used to weight the relaxation of that constraint or bound. The user may specify a preference value less than or equal to 0 (zero), which denotes that the corresponding constraint or bound must not be relaxed. It is not necessary to specify a unique preference for each bound or range. In fact, it is conventional to use only the values 0 (zero) and 1 (one) except when your knowledge of the problem suggests assigning explicit preferences.

Preferences can be specified through a GAMS/Gurobi solver option file using dot options. The syntax is:

*(variable or equation)*`.feaspref`

*(value)*

For example, suppose we have a GAMS declaration:

Set i /i1*i5/; Set j /j2*j4/; variable v(i,j); equation e(i,j);

Then, the relaxation preference in the *gurobi.opt* file can be specified by:

feasopt 1 v.feaspref 1 v.feaspref('i1',*) 2 v.feaspref('i1','j2') 0 e.feaspref(*,'j1') 0 e.feaspref('i5','j4') 2

First we turn the feasible relaxtion on. Futhermore, we specify that all variables `v(i,j)`

have preference of 1, except variables over set element `i1`

, which have a preference of 2. The variable over set element `i1`

and `j2`

has preference 0. Note that preferences are assigned in a procedural fashion so that preferences assigned later overwrite previous preferences. The same syntax applies for assigning preferences to equations as demonstrated above. If you want to assign a preference to all variables or equations in a model, use the keywords `variables`

or `equations`

instead of the individual variable and equations names (e.g. `variables.feaspref 1`

).

The parameter FeasOptMode allows different strategies in finding feasible relaxation in one or two phases. In its first phase, it attempts to minimize its relaxation of the infeasible model. That is, it attempts to find a feasible solution that requires minimal change. In its second phase, it finds an optimal solution (using the original objective) among those that require only as much relaxation as it found necessary in the first phase. Values of the parameter FeasOptMode indicate two aspects: (1) whether to stop in phase one or continue to phase two and (2) how to measure the relaxation (as a *sum* of required relaxations; as the *number* of constraints and bounds required to be relaxed; as a *sum of the squares* of required relaxations). Please check description of parameter FeasOptMode for details. Also check example models `feasopt*`

in the GAMS Model library.

## Parameter Tuning Tool

The Gurobi Optimizer provides a wide variety of parameters that allow you to control the operation of the optimization engines. The level of control varies from extremely coarse-grained (e.g., the Method parameter, which allows you to choose the algorithm used to solve continuous models) to very fine-grained (e.g., the MarkowitzTol parameter, which allows you to adjust the precise tolerances used during simplex basis factorization). While these parameters provide a tremendous amount of user control, the immense space of possible options can present a significant challenge when you are searching for parameter settings that improve performance on a particular model. The purpose of the Gurobi tuning tool is to automate this search.

The Gurobi tuning tool performs multiple solves on your model, choosing different parameter settings for each, in a search for settings that improve runtime. The longer you let it run, the more likely it is to find a significant improvement.

A number of tuning-related parameters allow you to control the operation of the tuning tool. The most important is probably TuneTimeLimit, which controls the amount of time spent searching for an improving parameter set. Other parameters include TuneTrials (which attempts to limit the impact of randomness on the result), TuneResults (which limits the number of results that are returned), and TuneOutput (which controls the amount of output produced by the tool).

While parameter settings can have a big performance effect for many models, they aren't going to solve every performance issue. One reason is simply that there are many models for which even the best possible choice of parameter settings won't produce an acceptable result. Some models are simply too large and/or difficult to solve, while others may have numerical issues that can't be fixed with parameter changes.

Another limitation of automated tuning is that performance on a model can experience significant variations due to random effects (particularly for MIP models). This is the nature of search. The Gurobi algorithms often have to choose from among multiple, equally appealing alternatives. Seemingly innocuous changes to the model (such as changing the order of the constraint or variables), or subtle changes to the algorithm (such as modifying the random number seed) can lead to different choices. Often times, breaking a single tie in a different way can lead to an entirely different search. We've seen cases where subtle changes in the search produce 100X performance swings. While the tuning tool tries to limit the impact of these effects, the final result will typically still be heavily influenced by such issues.

The bottom line is that automated performance tuning is meant to give suggestions for parameters that could produce consistent, reliable improvements on your models. It is not meant to be a replacement for efficient modeling or careful performance testing.

## Compute Server

The Gurobi Compute Server allows you to use one or more servers to offload all of your Gurobi computations.

Gurobi compute servers support queuing and load balancing. You can set a limit on the number of simultaneous jobs each compute server will run. When this limit has been reached, subsequent jobs will be queued. If you have multiple compute servers, the current job load is automatically balanced among the available servers. By default, the Gurobi job queue is serviced in a First-In, First-Out (FIFO) fashion. However, jobs can be given different priorities (CSPriority). Jobs with higher priorities are then selected from the queue before jobs with lower priorities.

Gurobi Compute Server licenses and software are not included in GAMS/Gurobi. Contact suppo to inquire about the software and license. Relevant options are rt@g ams.c omComputeServer and options starting with CS.

## Distributed Parallel Algorithms

Gurobi Optimizer implements a number of distributed algorithms that allow you to use multiple machines to solve a problem faster. Available distributed algorithms are:

- A
**distributed MIP solver**, which allows you to divide the work of solving a single MIP model among multiple machines. A manager machine passes problem data to a set of worker machines in order to coordinate the overall solution process. - A
**distributed concurrent solver**, which allows you to use multiple machines to solve an LP or MIP model. Unlike the distributed MIP solver, the concurrent solver doesn't divide the work associated with solving the problem among the machines. Instead, each machine uses a different strategy to solve the whole problem, with the hope that one strategy will be particularly effective and will finish much earlier than the others. For some problems, this concurrent approach can be more effective than attempting to divide up the work. **Distributed parameter tuning**, which automatically searches for parameter settings that improve performance on your optimization model. Tuning solves your model with a variety of parameter settings, measuring the performance obtained by each set, and then uses the results to identify the settings that produce the best overall performance. The distributed version of tuning performs these trials on multiple machines, which makes the overall tuning process run much faster.

These distributed parallel algorithms are designed to be almost entirely transparent to the user. The user simply modifies a few parameters, and the work of distributing the computation to multiple machines is handled behind the scenes by Gurobi.

### Specifying the Worker Pool

Once you've set up a set of one or more distributed workers, you should list their names in the WorkerPool parameter. You can provide either machine names or IP addresses, and they should be comma-separated.

You can provide the worker access password through the WorkerPassword parameter. All servers in the worker pool must have the same access password.

### Requesting Distributed Algorithms

Once you've set up the worker pool through the appropriate parameters, the last step to use a distributed algorithm is to set the TuneJobs, ConcurrentJobs, or DistributedMIPJobs parameter. These parameters are used to indicate how many distinct tuning, concurrent, or distributed MIP jobs should be started on the available workers.

If some of the workers in your worker pool are running at capacity when you launch a distributed algorithm, the algorithm won't create queued jobs. Instead, it will launch as many jobs as it can (up to the requested value), and it will run with these jobs.

These distributed algorithms have been designed to be nearly indistinguishable from the single machine versions. Our hope is that, if you know how to use the single machine version, you'll find it straightforward to use the distributed version. The distributed algorithms respect all of the usual parameters. For distributed MIP, you can adjust strategies, adjust tolerances, set limits, etc. For concurrent MIP, you can allow Gurobi to choose the settings for each machine automatically or specify a set of options. For distributed tuning, you can use the usual tuning parameters, including TuneTimeLimit, TuneTrails, and TuneOutput.

There are a few things to be aware of when using distributed algorithms, though. One relates to relative machine performance. Distributed algorithms work best if all of the workers give very similar performance. For example, if one machine in your worker pool were much slower than the others in a distributed tuning run, any parameter sets tested on the slower machine would appear to be less effective than if they were run on a faster machine. Similar considerations apply for distributed MIP and distributed concurrent. We strongly recommend that you use machines with very similar performance. Note that if your machines have similarly performing cores but different numbers of cores, we suggest that you use the Threads parameter to make sure that all machines use the same number of cores.

Logging for distributed MIP is very similar to the standard MIP logging. The main differences are in the progress section. The header for the standard MIP logging looks like this:

Nodes | Current Node | Objective Bounds | Work Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time

By contrast, the distributed MIP header looks like this:

Nodes | Utilizaiton | Objective Bounds | Work Expl Unexpl | Active Sync Comm | Incumbent BestBd Gap | It/Node Time

You'll note that columns three through five show different information. In the distributed MIP log, these columns give information about the utilization of the distributed workers, expressed as percentages. The first of these columns shows the fraction of the preceding time period (the time since the previous progress log line) that the workers spent actively processing MIP nodes. The second column shows the time the workers spent waiting for other workers to complete tasks assigned to them. The final column shows the time spent communicating data between machines. The numbers sum to 100%.

Here is an example of a distributed MIP progress log:

Nodes | Utilization | Objective Bounds | Work Expl Unexpl | Active Sync Comm | Incumbent BestBd Gap | It/Node Time * 0 - 157344.61033 - - - 0s * 0 - 41359.940833 - - - 0s * 0 - 25050.545455 - - - 0s * 0 - 18150.083886 - - - 0s * 0 - 14372.871258 - - - 0s * 0 - 13725.475382 - - - 0s * 261 - 13570.462316 - - - 0s * 0 - 13308.140897 - - - 0s * 747 - 12821.371258 - - - 0s 262 149 99% 0% 0% 12821.3713 10617.6273 17.2% 3.4 0s * 1060 - 12356.371258 10617.6273 14.1% - 0s * 2413 - 12010.589689 10617.6273 11.6% - 0s Ramp-up phase complete - continuing with instance 4 (best bd 10669.8) * 6881 - 11956.589689 10669.8486 10.8% - 2s * 6951 - 11945.263051 10669.8486 10.7% - 2s *101868 - 11891.263051 10943.0036 7.97% - 2s *614787 - 11857.371258 11136.5161 6.08% - 4s 1140819 388613 99% 1% 0% 11857.3713 11231.3942 5.28% 4.6 5s *1946490 - 11801.185729 11306.6196 4.19% - 8s 2683258 497092 86% 14% 1% 11801.1857 11364.3331 3.70% 4.6 10s 4143934 185856 69% 4% 26% 11801.1857 11468.7845 2.82% 4.4 15s 4569003 21 57% 2% 41% 11801.1857 11800.6434 0.00% 4.4 18s

One thing you may find in the progress section is that node counts may not increase monotonically. In this example, a solution found at node 261 is reported before a solution found at node 0. Distributed MIP tries to create a single, unified view of node numbers, but with multiple machines processing nodes independently, possibly at different rates, some inconsistencies are inevitable.

Another difference is the line that indicates that the distributed ramp-up phase is complete. At this point, the distributed strategy transitions from a concurrent approach to a distributed approach. The log line indicates which worker was the winner in the concurrent approach. Distributed MIP continues by dividing the partially explored MIP search tree from this worker among all of the workers.

Another difference in the distributed log is in the summary section. The distributed MIP log includes a breakdown of how runtime was spent:

Runtime breakdown: Active: 13.73s (75%) Sync: 1.16s (6%) Comm: 3.45s (19%)

This is an aggregated view of the utilization data that is displayed in the progress log lines. In this example, the workers spent 75% of runtime actively working on MIP nodes, 6% waiting to synchronize with other workers, and 19% communicating data between machines.

### Configuring a Distributed Worker Pool

Once you've identified your distributed worker machines, you'll need to start *Gurobi Remote Services* on these machines. Gurobi Remote Services allow a machine to perform Gurobi computations on behalf of other machines. It is a Windows Service on Windows systems, and a daemon on Linux and Mac systems. You will need some extra software to run the Gurobi Remote Services. Contact suppo to get access to this software. The instructions of how to start the Gurobi Remote Services on the worker vary by operating system. rt@g ams.c om

**Windows:**On a Windows system, you will need to start Gurobi Remote Services by running`grb_rs.exe`

. Running this program requires administrative privileges. The next step after starting Gurobi Remote Services depends on your anti-virus software and firewall settings. Most anti-virus software will ask you to confirm that you are allowing programs`grb_rs.exe`

and`grb_rsw.exe`

to receive network traffic. Once you confirm this, Gurobi Remote Services will start serving requests. If you don't receive such a prompt, you will need to add`grb_rs.exe`

and`grb_rsw.exe`

to the firewall exceptions list. Select*Allow a program through Windows firewall*under the*Security area*of the*Control Panel*(labeled*Allow an app through Windows firewall*in Windows 8 and up).Some machines have more restrictive firewalls that may require additional action. Gurobi Remote Services uses ports 61000-65000 by default. If you are unable to reach the Compute Server after taking the steps described, ask your network administrator for more information on how to open the required ports.

Once Gurobi Remote Services has been started, you should see the grb_rs service listed in the Services tab of the Task Manager. To start or stop the service, click on the Services button at the bottom-right of the Services tab, and then right-click on the Gurobi Remote Services item on this screen.

You can also start or stop Gurobi Remote Services from a Console window with administrator privileges. Running

`grb_rs -h`

lists command-line options. Issuing a`grb_rs -s`

command stops Gurobi Remote Services.**Mac:**On Mac systems, Gurobi Remote Services is a daemon that allows a server to perform Gurobi computations on behalf of other client machines. To start the Gurobi Remote Services daemon, run the program`grb_rs`

(with no arguments) on your server. You only need to do this once – Gurobi Remote Services will keep running until you stop it (or until the machine is shut down). Note that Gurobi Remote Services runs as a user process, so you do not need root privileges to start it.If you would like Gurobi Remote Services to restart automatically when the machine is rebooted, there are a number of options for doing so (including

`launchd`

and`/etc/rc.local`

). You could start adding the following lines to`/etc/rc.local`

:/path/to/gurobi/software/grb_rs

To stop Gurobi Remote Services if it is already running, you can issue the

`grb_rs -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 Gurobi Remote Services goes to the system log (

`/var/log/system.log`

). You will need to modify`/etc/syslog.conf`

to see these messages, since by default OS X only allows error message in the system log. Once you have modified`syslog.conf`

, you should see a message similar to the following when you start the server:Mar 9 12:37:21 mymachine grb[7917]: Gurobi Remote Services started: Sat Mar 9 12:37:21 2015

By default, Gurobi Remote Services only produces logging output when it starts. Start Gurobi Remote Services with the

`-v`

switch to obtain more detailed logging information. For example, this option will generate a log message each time a client job starts.If you run into trouble accessing Gurobi Remote Services, check to see if the server is running firewall software that might be blocking access to some ports. Gurobi Remote Services uses port numbers 61000-65000 by default, so you'll need to open access to these ports on the server. Please consult the documentation for your firewall software to determine how to do this.

**Linux:**On Linux systems, Gurobi Remote Services is a daemon that allows a server to perform Gurobi computations on behalf of other client machines. To start the Gurobi Remote Services daemon, run the program`grb_rs`

(with no arguments) on your server. You only need to do this once – Gurobi Remote Services will keep running until you stop it (or until the machine is shut down). Note that Gurobi Remote Services runs as a user process, so you do not need root privileges to start it.If you would like Gurobi Remote Services 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 Gurobi Remote Services if it is already running, you can issue the

`grb_rs -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 Gurobi Remote Services goes to the system log (

`/var/log/syslog`

). You should see a message similar to the following when you start the server:Mar 9 12:37:21 mymachine grb[7917]: Gurobi Remote Services started: Sat Mar 9 12:37:21 2015

By default, Gurobi Remote Services only produces logging output when it starts. Start Gurobi Remote Services with the

`-v`

switch to obtain more detailed logging information. For example, this option will generate a log message each time a client job starts.If you run into trouble accessing Gurobi Remote Services, check to see if the server is running firewall software that might be blocking access to some ports. Gurobi Remote Services uses port numbers 61000-65000 by default, so you'll need to open access to these ports on the server. Please consult the documentation for your firewall software to determine how to do this.

### Gurobi Instant Cloud

An alternative to setting up your own pool of machines is to use the Gurobi Instant Cloud. You only need a GAMS/Gurobi link license when you solve your problems in the Gurobi Instant Cloud. The cost for the Gurobi license is paid on a per use basis directly to Gurobi. If you follow through the steps on the Gurobi web site, you eventually get the names of the machines Gurobi has started for you in the cloud. In order to use these machines from GAMS/Gurobi, you need to supply a GAMS/Gurobi option file with the following options (this example has started 4 machines):

workerpool ec2-52-91-156-32.compute-1.amazonaws.com,ec2-54-85-44-125.compute-1.amazonaws.com workerpool ec2-54-88-214-0.compute-1.amazonaws.com,ec2-54-88-11-24.compute-1.amazonaws.com workerpassword 8f30654f computeserver ec2-52-91-156-32.compute-1.amazonaws.com cspassword 8f30654f DistributedMIPJobs 4

Clearly the machine names in the WorkerPool and ComputeServer option will change as well as the password in WorkerPassword and CSPassword.

## Solution Pool

While the default goal of the Gurobi Optimizer is to find one proven optimal solution to your model, with a possible side-effect of finding other solutions along the way, the solver provides a number of parameters that allow you to change this behavior.

By default, the Gurobi MIP solver will try to find one proven optimal solution to your model. It will typically find multiple sub-optimal solutions along the way, which can be retrieved later. However, these solutions aren't produced in a systematic way. The set of solutions that are found depends on the exact path the solver takes through the MIP search. You could solve a MIP model once, obtaining a set of interesting sub-optimal solutions, and then solve the same problem again with different parameter settings, and find only the optimal solution.

If you'd like more control over how solutions are found and retained, the Gurobi Optimizer has a number of parameters available for this. The first and simplest is PoolSolutions, which controls the size of the solution pool. Changing this parameter won't affect the number of solutions that are found - it simply determines how many of those are retained.

You can use the PoolSearchMode parameter to control the approach used to find solutions. In its default setting (0), the MIP search simply aims to find one optimal solution. Setting the parameter to 1 causes the MIP search to expend additional effort to find more solutions, but in a non-systematic way. You will get more solutions, but not necessarily the best solutions. Setting the parameter to 2 causes the MIP to do a systematic search for the n best solutions. For both non-default settings, the PoolSolutions parameter sets the target for the number of solutions to find.

If you are only interested in solutions that are within a certain gap of the best solution found, you can set the PoolGap parameter. Solutions that are not within the specified gap are discarded.

Obtaining an OPTIMAL optimization return status when using PoolSearchMode=2 indicates that the MIP solver succeeded in finding the desired number of best solutions, or it proved that the model doesn't have that many distinct feasible solutions. If the solver terminated early (e.g., due to a time limit), you *PoolObjBound* attribute (printed to the log) to evaluate the quality of the solutions that were found. This attribute gives a bound on the objective of any solution that isn't already in the solution pool. The difference between this attribute and ObjBound is that the latter gives a bound on the objective for any solution, and which is often looser than PoolObjBound. The *PoolObjBound* attribute gives a bound on the objective of undiscovered solutions. Further tree exploration won't find better solutions. You can use this bound to get a count of how many of the n best solutions you found: any solutions whose objective values are at least as good as *PoolObjBound* are among the $n$ best.

### Solution Pool Example

Let's continue with a few examples of how these parameters would be used. Imagine that you are solving a MIP model with an optimal (minimization) objective of 100. Further imagine that, using default settings, the MIP solver finds four solutions to this model with objectives 100, 110, 120, and 130.

If you set the PoolSolutions parameter to 3 and solve the model again, the MIP solver would discard the worst solution and return with 3 solutions in the solution pool. If you instead set the PoolGap parameter to value 0.2, the MIP solver would discard any solutions whose objective value is worse than 120 (which would also leave 3 solutions in the solution pool).

If you set the PoolSearchMode parameter to 2 and the PoolSolutions parameter to 10, the MIP solver would attempt to find the 10 best solutions to the model. An OPTIMAL return status would indicate that either (i) it found the 10 best solutions, or (ii) it found all feasible solutions to the model, and there were fewer than 10. If you also set the PoolGap parameter to a value of 0.1, the MIP solver would try to find 10 solutions with objective no worse than 110. While this may appear equivalent to asking for 10 solutions and simply ignoring those with objective worse than 110, the solve will typically complete significantly faster with this parameter set, since the solver does not have to expend effort looking for solutions beyond the requested gap.

### Solution Pool Subtleties

There are a few subtleties associated with finding multiple solutions that we'll cover now.

**Continuous Variables**

One subtlety arises when considering multiple solutions for models with continuous variables. Specifically, you may have two solutions that take identical values on the integer variables but where some continuous variables differ. By choosing different points on the line between these two solutions, you actually have an infinite number of choices for feasible solutions to the problem. To avoid this issue, we define two solutions as being equivalent if they take the same values on all integer variables (and on all continuous variables that participate in SOS constraints). A solution will be discarded if it is equivalent to another solution that is already in the pool.

**Optimality Gap**

The interplay between the optimality gap (MIPGap or MIPGapAbs) and multiple solutions can be a bit subtle. When using the default PoolSearchMode, a non-zero optimality gap indicates that you are willing to allow the MIP solver to declare a solution optimal, even though the model may have other, better solutions. The claim the solver makes upon termination is that no other solution would improve the incumbent objective by more than the optimality gap. Terminating at this point is ultimately a pragmatic choice - we'd probably rather have the true best solution, but the cost of reducing the optimality gap to zero can often be prohibitive.

This pragmatic choice can produce a bit of confusion when finding multiple optimal solutions. Specifically, if you ask for the n best solutions, the optimality gap plays a similar role as it does in the default case, but the implications may be a bit harder to understand. Specifically, a non-zero optimality gap means that you are willing to allow the solver to declare that it has found the n best solutions, even though there may be solutions that are better than those that were returned. The claim in this case is that any solution not among the reported $n$ best would improve on the objective for the worst among the n best by less than the optimality gap.

If you want to avoid this source of potential confusion, you should set the optimality gap to 0 when using `PoolSearchMode=2`

.

**Logging**

If you browse the log from a MIP solve with PoolSearchMode set to a non-default value, you may see the lower bound on the objective exceed the upper bound. This can't happen with the default `PoolSearchMode`

- if you are only looking for one optimal solution, the search is done as soon as the lower bound reaches the upper bound. However, if you are looking for the n best solutions, you have to prove that the model has no solution better than the n-th best. The objective for that n-th solution could be much worse than that of the incumbent. In this situation, the log file will include a line of the form:

Optimal solution found at node 123 - now completing solution pool...

**Distributed MIP**

One limitation that we should point out related to multiple solutions is that the distributed MIP solver has not been extended to support non-default PoolSearchMode settings. Distributed MIP will typically produce many more feasible solutions than non-distributed MIP, but there's no way to ask it to find the n best solutions.

# Multiple Objectives

While typical optimization models have a single objective function, real-world optimization problems often have multiple, competing objectives. For example, in a production planning model, you may want to both maximize profits and minimize late orders, or in a workforce scheduling application, you may want to both minimize the number of shifts that are short-staffed while also respecting worker's shift preferences.

The main challenge you face when working with multiple, competing objectives is deciding how to manage the tradeoffs between them. Gurobi provides tools that simplify the task: Gurobi allows you to blend multiple objectives, to treat them *hierarchically*, or to combine the two approaches. In a blended approach, you optimize a weighted combination of the individual objectives. In a hierarchical or *lexicographic* approach, you set a priority for each objective, and optimize in priority order. When optimizing for one objective, you only consider solutions that would not degrade the objective values of higher-priority objectives. Gurobi allows you to enter and manage your objectives, to provide weights for a blended approach, or to set priorities for a hierarchical approach. Gurobi will only solve multi-objective models with strictly linear objectives. Moreover, for continous models, Gurobi will report a primal only solution (not dual information).

Following the workforce application the specifications of the objectives would be done as follows:

equations defObj, defNumShifts, defSumPreferences; variables obj, numShifts, sumPreferences; defobj.. obj =e= numShifts - 1/100*sumPreferences; defNumShifts.. numShifts =e= ...; defSumPreferences.. sumPreferences =e= ...; model workforce /all/; solve workforce minimizing obj using mip;

With the default setting GUROBI will solve the blended objective. Using the parameter MultObj GUROBI will use a hierarchical approach. A hierarchical or lexicographic approach assigns a priority to each objective, and optimizes for the objectives in decreasing priority order. At each step, it finds the best solution for the current objective, but only from among those that would not degrade the solution quality for higher-priority objectives. The priority is specified by the absolute value of the objective coeffiecient in the blended objective function (`defObj`

). In the example, the `numShifts`

objective with coeffiecient 1 has higher priority than the `sumPreferences`

objective with absolute objective coefficient 1/100. The sign of the objective coefficient determines the direction of the particular objective function. So here `numShifts`

will be minimized (same direction as on the `solve`

statement) while `sumPreferences`

will be maximized. GAMS needs to identify the various objective functions, therefore the objective variables can only appear in the blended objective functions and in the particular objective defining equation.

By default, the hierarchical approach won't allow later objectives to degrade earlier objectives. This behavior can be relaxed through a pair of attributes: ObjNRelTol and ObjNAbsTol. By setting one of these for a particular objective, you can indicate that later objectives are allowed to degrade this objective by the specified relative or absolute amount, respectively. In our earlier example, if the optimal value for `numShifts`

is 100, and if we set ObjNAbsTol for this objective to 20, then the second optimization step maximizing `sumPreferences`

would find the best solution for the second objective from among all solutions with objective 120 or better for `numShifts`

. Note that if you modify both tolerances, later optimizations would use the looser of the two values (i.e., the one that allows the larger degradation).

# GAMS Options

The following GAMS options are used by GAMS/Gurobi:

Determines whether or not to use an advanced basis. A value of 1.0 causes GAMS to instruct Gurobi not to use an advanced basis. A value of 0.0 causes GAMS to construct a basis from whatever information is available. The default value of 0.25 will nearly always cause GAMS to pass along an advanced basis if a solve statement has previously been executed. This GAMS option is overridden by the GAMS/Gurobi option UseBasis

Sets the simplex iteration limit. Simplex algorithms will terminate and pass on the current solution to GAMS. For MIP problems, if the number of the cumulative simplex iterations exceeds the limit, Gurobi will terminate. This GAMS option is overridden by the GAMS/Gurobi option IterationLimit

Maximum number of nodes to process for a MIP problem. This GAMS option is overridden by the GAMS/Gurobi option NodeLimit.

Absolute optimality criterion for a MIP problem. The OptCA option asks Gurobi to stop when

\begin{equation*} |BP - BF| < \mbox{OptCA} \end{equation*}

where \(BF\) is the objective function value of the current best integer solution while \(BP\) is the best possible integer solution. This GAMS option is overridden by the GAMS/Gurobi option MipGapAbs.

Relative optimality criterion for a MIP problem. Notice that Gurobi uses a different definition than GAMS normally uses. The OptCR option asks Gurobi to stop when

\begin{equation*} |BP - BF| < |BF|*\mbox{OptCR} \end{equation*}

where \(BF\) is the objective function value of the current best integer solution while \(BP\) is the best possible integer solution. The GAMS definition is:

\begin{equation*} |BP - BF| < |BP|*\mbox{OptCR} \end{equation*}

This GAMS option is overridden by the GAMS/Gurobi option MipGap.

Sets the time limit in seconds. The algorithm will terminate and pass on the current solution to GAMS. Gurobi measures time in wall time on all platforms. Some other GAMS solvers measure time in CPU time on some Unix systems. This GAMS option is overridden by the GAMS/Gurobi option TimeLimit.

Will echo Gurobi messages to the GAMS listing file. This option may be useful in case of a solver failure.

Cutoff value. When the branch and bound search starts, the parts of the tree with an objective worse than x are deleted. This can sometimes speed up the initial phase of the branch and bound algorithm. This GAMS option is overridden by the GAMS/Gurobi option CutOff.

Instructs GAMS/Gurobi to read the option file. The name of the option file is

`gurobi.opt`

.

Instructs GAMS/Gurobi to use the priority branching information passed by GAMS through variable suffix values

variable`.prior`

.

# Summary of GUROBI Options

## Termination options

Option | Description | Default |
---|---|---|

bariterlimit | Limits the number of barrier iterations performed | `infinity` |

cutoff | Sets a target objective value | `0` |

iterationlimit | Limits the number of simplex iterations performed | `infinity` |

nodelimit | Limits the number of MIP nodes explored | `maxdouble` |

solutionlimit | Limits the number of feasible solutions found | `maxint` |

timelimit | Limits the total time expended in seconds | `GAMS reslim` |

## Tolerance options

Option | Description | Default |
---|---|---|

barconvtol | Controls barrier termination | `1e-8` |

barqcpconvtol | Convergence tolerance for the barrier algorithm when solving a QCP | `1e-6` |

feasibilitytol | Primal feasibility tolerance | `1e-6` |

intfeastol | Integer feasibility tolerance | `1e-5` |

markowitztol | Threshold pivoting tolerance | `0.0078125` |

mipgap | Relative MIP optimality gap | `GAMS optcr` |

mipgapabs | Absolute MIP optimality gap | `GAMS optca` |

optimalitytol | Dual feasibility tolerance | `1e-6` |

psdtol | limit on the amount of diagonal perturbation | `1e-6` |

## Simplex options

Option | Description | Default |
---|---|---|

normadjust | Pricing norm variants | `-1` |

objscale | Objective coefficients scaling | `0` |

perturbvalue | Magnitude of simplex perturbation when required | `0.0002` |

quad | Quad precision computation in simplex | `-1` |

scaleflag | Enables or disables model scaling | `1` |

sifting | Sifting within dual simplex | `-1` |

siftmethod | LP method used to solve sifting sub-problems | `-1` |

simplexpricing | Determines variable pricing strategy | `-1` |

## Barrier options

Option | Description | Default |
---|---|---|

barcorrectors | Limits the number of central corrections performed in each barrier iteration | `-1` |

barhomogeneous | Homogeneous barrier algorithm selection | `-1` |

barorder | Chooses the barrier sparse matrix fill-reducing algorithm | `-1` |

crossover | Determines the crossover strategy used to transform the barrier solution into a basic solution | `-1` |

crossoverbasis | Determines the initial basis construction strategy for crossover | `0` |

qcpdual | Determines whether dual variable values are computed for QCP models | `1` |

## MIP options

Option | Description | Default |
---|---|---|

bestbdstop | Objective bound to stop optimization | `maxdouble` |

bestobjstop | Objective value to stop optimization | `mindouble` |

branchdir | Determines which child node is explored first in the branch-and-cut search | `0` |

cliquecuts | Controls clique cut generation | `-1` |

concurrentjobs | Distributed concurrent MIP job count | `0` |

concurrentmip | Enables the concurrent MIP solver | `1` |

covercuts | Controls cover cut generation | `-1` |

cutaggpasses | Maximum number of aggregation passes during cut generation | `-1` |

cutpasses | Maximum number of cutting plane passes performed during root cut generation | `-1` |

cuts | Global cut generation control | `-1` |

degenmoves | Degenerate simplex moves | `-1` |

disconnected | Disconnected component strategy | `-1` |

distributedmipjobs | Distributed MIP job count | `0` |

fixoptfile | Option file for fixed problem optimization | |

flowcovercuts | Controls flow cover cut generation | `-1` |

flowpathcuts | Controls flow path cut generation | `-1` |

gomorypasses | Maximum number of Gomory cut passes | `-1` |

gubcovercuts | Controls GUB cover cut generation | `-1` |

heuristics | Controls the amount of time spent in MIP heuristics | `0.05` |

impliedcuts | Controls implied bound cut generation | `-1` |

improvestartgap | Optimality gap at which the MIP solver resets a few MIP parameters | `maxdouble` |

improvestartnodes | Solution improvement strategy control | `maxdouble` |

improvestarttime | Elapsed time after which the MIP solver resets a few MIP parameters | `maxdouble` |

infproofcuts | Infeasibility proof cut generation | `-1` |

.lazy | Lazy constraints value | `0` |

lazyconstraints | Indicator to use lazy constraints | `0` |

minrelnodes | Number of nodes to explore in the Minimum Relaxation heuristic | `0` |

mipfocus | Controls the focus of the MIP solver | `0` |

mipsepcuts | Controls MIP separation cut generation | `-1` |

mipstart | Use mip starting values | `0` |

miqcpmethod | Determines whether outer approximation is used to solve an MIQCP model. | `-1` |

mircuts | Controls MIR cut generation | `-1` |

modkcuts | Controls the generation of mod-k cuts | `-1` |

networkcuts | Controls network cut generation | `-1` |

nodefiledir | Nodefile directory | `.` |

nodefilestart | Nodefile starting indicator | `maxdouble` |

nodemethod | Algorithm used to solve node relaxations in a MIP model | `1` |

norelheuristic | No relaxation heuristic attempts to find feasible solutions without solving root relaxation | `0` |

poolgap | Maximum gap for stored solutions | `maxdouble` |

poolsearchmode | Selects different modes for exploring the MIP search tree | `0` |

poolsolutions | Number of MIP solutions to store | `10` |

presos1bigm | Threshold for SOS1-to-binary reformulation | `-1` |

presos2bigm | Threshold for SOS2-to-binary reformulation | `0` |

presparsify | Enables the presolve sparsify reduction for MIP models | `0` |

.prior | Branching priorities | `1` |

pumppasses | Number of passes of the feasibility pump heuristic | `0` |

rins | Frequency of the RINS heuristic | `-1` |

solnpool | Controls export of alternate MIP solutions | |

solvefixed | Indicator for solving the fixed problem for a MIP to get a dual solution | `1` |

strongcgcuts | Strong-CG cut generation | `-1` |

submipcuts | Controls the generation of sub-MIP cutting planes | `-1` |

submipnodes | Limits the number of nodes explored by the heuristics | `500` |

symmetry | Controls MIP symmetry detection | `-1` |

varbranch | Controls the branch variable selection strategy | `-1` |

zerohalfcuts | Controls zero-half cut generation | `-1` |

zeroobjnodes | Number of nodes to explore in the zero objective heuristic | `0` |

## Other options

Option | Description | Default |
---|---|---|

aggfill | Controls the amount of fill allowed during presolve aggregation | `10` |

aggregate | Enables or disables aggregation in presolve | `1` |

computeserver | List of Gurobi compute servers | |

cspassword | Password for Gurobi compute servers | |

csport | The port number used to connect to the compute server | `-1` |

cspriority | Job priority on the compute server | `0` |

cstimeoutfrac | Fraction of reslim that job will wait to reach front of the compute server queue | `0.1` |

displayinterval | Controls the frequency at which log lines are printed in seconds | `5` |

feasopt | Computes a minimum-cost relaxation to make an infeasible model feasible | `0` |

feasoptmode | Mode of FeasOpt | `0` |

.feaspref | feasibility preference | `1` |

freegamsmodel | Preserves memory by dumping the GAMS model instance representation temporarily to disk | `0` |

.genconstrtype | General constraint type | `0` |

iis | Run the Irreducible Inconsistent Subsystem (IIS) finder if the problem is infeasible | `0` |

iismethod | Controls use of IIS method | `-1` |

kappa | Display approximate condition number estimates for the optimal simplex basis | `0` |

kappaexact | Display exact condition number estimates for the optimal simplex basis | `0` |

method | Algorithm used to solve continuous models | `-1` |

multobj | Controls the hierarchical optimization of multiple objectives | `0` |

names | Indicator for loading names | `1` |

numericfocus | Set the numerical focus | `0` |

objnabstol | Allowable absolute degradation for objective | |

objnreltol | Allowable relative degradation for objective | |

precrush | Presolve constraint option | `0` |

predeprow | Controls the presolve dependent row reduction | `-1` |

predual | Controls whether presolve forms the dual of a continuous model | `-1` |

premiqcpform | Determines the format of the presolved version of an MIQCP model | `-1` |

premiqpmethod | Transformation presolve performs on MIQP models | `-1` |

prepasses | Controls the number of passes performed by presolve | `-1` |

preqlinearize | Controls linearization of Q matrices in the quadratic constraints or a quadratic objective | `-1` |

presolve | Controls the presolve level | `-1` |

printoptions | List values of all options to GAMS listing file | `0` |

readparams | Read Gurobi parameter file | |

rerun | Resolve without presolve in case of unbounded or infeasible | `0` |

seed | Random number seed | `0` |

sensitivity | Provide sensitivity information | `0` |

threads | Controls the number of threads to apply to parallel MIP or Barrier | `GAMS threads` |

tunecriterion | Tuning criterion | `-1` |

tunejobs | Distributed tuning job count | `0` |

tuneoutput | Tuning output level | `2` |

tuneresults | Number of improved parameter sets returned | `1` |

tunetimelimit | Time limit for tuning | `-1` |

tunetrials | Perform multiple runs on each parameter set to limit the effect of random noise | `2` |

tuning | Parameter Tuning | |

usebasis | Use basis from GAMS | `GAMS bratio` |

varhint | Guide heuristics and branching through variable hints | `0` |

workerpassword | Compute server password Pool of compute servers to use for distributed algorithms | |

workerpool | Pool of compute servers to use for distributed algorithms | |

workerport | Non-default port number for distributed workers | `-1` |

writeparams | Write Gurobi parameter file | |

writeprob | Save the problem instance |

## The GAMS/Gurobi Options File

The GAMS/Gurobi options file consists of one option or comment per line. An asterisk (*) at the beginning of a line causes the entire line to be ignored. Otherwise, the line will be interpreted as an option name and value separated by any amount of white space (blanks or tabs).

Following is an example options file *gurobi.opt*.

simplexpricing 3 method 0

It will cause Gurobi to use quick-start steepest edge pricing and will use the primal simplex algorithm.

# GAMS/Gurobi Log File

Gurobi reports its progress by writing to the GAMS log file as the problem solves. Normally the GAMS log file is directed to the computer screen.

The log file shows statistics about the presolve and continues with an iteration log.

For the simplex algorithms, each log line starts with the iteration number, followed by the objective value, the primal and dual infeasibility values, and the elapsed wall clock time. The dual simplex uses a bigM approach for handling infeasibility, so the objective and primal infeasibility values can both be very large during phase I. The frequency at which log lines are printed is controlled by the DisplayInterval option. By default, the simplex algorithms print a log line roughly every five seconds, although log lines can be delayed when solving models with particularly expensive iterations.

The simplex screen log has the following appearance:

Presolve removed 977 rows and 1539 columns Presolve changed 3 inequalities to equalities Presolve time: 0.078000 sec. Presolved: 1748 Rows, 5030 Columns, 32973 Nonzeros Iteration Objective Primal Inf. Dual Inf. Time 0 3.8929476e+31 1.200000e+31 1.485042e-04 0s 5624 1.1486966e+05 0.000000e+00 0.000000e+00 2s Solved in 5624 iterations and 1.69 seconds Optimal objective 1.148696610e+05

The barrier algorithm log file starts with barrier statistics about dense columns, free variables, nonzeros in *AA'* and the Cholesky factor matrix, computational operations needed for the factorization, memory estimate and time estimate per iteration. Then it outputs the progress of the barrier algorithm in iterations with the primal and dual objective values, the magnitude of the primal and dual infeasibilites and the magnitude of the complementarity violation. After the barrier algorithm terminates, by default, Gurobi will perform crossover to obtain a valid basic solution. It first prints the information about pushing the dual and primal superbasic variables to the bounds and then the information about the simplex progress until the completion of the optimization.

The barrier screen log has the following appearance:

Presolve removed 2394 rows and 3412 columns Presolve time: 0.09s Presolved: 3677 Rows, 8818 Columns, 30934 Nonzeros Ordering time: 0.20s Barrier statistics: Dense cols : 10 Free vars : 3 AA' NZ : 9.353e+04 Factor NZ : 1.139e+06 (roughly 14 MBytes of memory) Factor Ops : 7.388e+08 (roughly 2 seconds per iteration) Objective Residual Iter Primal Dual Primal Dual Compl Time 0 1.11502515e+13 -3.03102251e+08 7.65e+05 9.29e+07 2.68e+09 2s 1 4.40523949e+12 -8.22101865e+09 3.10e+05 4.82e+07 1.15e+09 3s 2 1.18016996e+12 -2.25095257e+10 7.39e+04 1.15e+07 3.37e+08 4s 3 2.24969338e+11 -2.09167762e+10 1.01e+04 2.16e+06 5.51e+07 5s 4 4.63336675e+10 -1.44308755e+10 8.13e+02 4.30e+05 9.09e+06 6s 5 1.25266057e+10 -4.06364070e+09 1.52e+02 8.13e+04 2.21e+06 7s 6 1.53128732e+09 -1.27023188e+09 9.52e+00 1.61e+04 3.23e+05 9s 7 5.70973983e+08 -8.11694302e+08 2.10e+00 5.99e+03 1.53e+05 10s 8 2.91659869e+08 -4.77256823e+08 5.89e-01 5.96e-08 8.36e+04 11s 9 1.22358325e+08 -1.30263121e+08 6.09e-02 7.36e-07 2.73e+04 12s 10 6.47115867e+07 -4.50505785e+07 1.96e-02 1.43e-06 1.18e+04 13s ...... 26 1.12663966e+07 1.12663950e+07 1.85e-07 2.82e-06 1.74e-04 2s 27 1.12663961e+07 1.12663960e+07 3.87e-08 2.02e-07 8.46e-06 2s Barrier solved model in 27 iterations and 1.86 seconds Optimal objective 1.12663961e+07 Crossover log... 1592 DPushes remaining with DInf 0.0000000e+00 2s 0 DPushes remaining with DInf 2.8167333e-06 2s 180 PPushes remaining with PInf 0.0000000e+00 2s 0 PPushes remaining with PInf 0.0000000e+00 2s Push phase complete: Pinf 0.0000000e+00, Dinf 2.8167333e-06 2s Iteration Objective Primal Inf. Dual Inf. Time 1776 1.1266396e+07 0.000000e+00 0.000000e+00 2s Solved in 2043 iterations and 2.00 seconds Optimal objective 1.126639605e+07

For MIP problems, the Gurobi solver prints regular status information during the branch and bound search. The first two output columns in each log line show the number of nodes that have been explored so far in the search tree, followed by the number of nodes that remain unexplored. The next three columns provide information on the most recently explored node in the tree. The solver prints the relaxation objective value for this node, followed by its depth in the search tree, followed by the number of integer variables with fractional values in the node relaxation solution. The next three columns provide information on the progress of the global MIP bounds. They show the objective value for the best known integer feasible solution, the best bound on the value of the optimal solution, and the gap between these lower and upper bounds. Finally, the last two columns provide information on the amount of work performed so far. The first column gives the average number of simplex iterations per explored node, and the next column gives the elapsed wall clock time since the optimization began.

At the default value for option DisplayInterval, the MIP solver prints one log line roughly every five seconds. Note, however, that log lines are often delayed in the MIP solver due to particularly expensive nodes or heuristics.

Presolve removed 12 rows and 11 columns Presolve tightened 70 bounds and modified 235 coefficients Presolve time: 0.02s Presolved: 114 Rows, 116 Columns, 424 Nonzeros Objective GCD is 1 Nodes | Current Node | Objective Bounds | Work Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time H 0 0 -0.0000 - - - 0s Root relaxation: 208 iterations, 0.00 seconds 0 0 29.6862 0 64 -0.0000 29.6862 - - 0s H 0 0 8.0000 29.6862 271% - 0s H 0 0 17.0000 29.6862 74.6% - 0s 0 2 27.4079 0 60 17.0000 27.4079 61.2% - 0s H 27 17 18.0000 26.0300 44.6% 51.6 0s * 87 26 45 20.0000 26.0300 30.2% 28.4 0s * 353 71 29 21.0000 25.0000 19.0% 19.3 0s 1268 225 24.0000 28 43 21.0000 24.0000 14.3% 32.3 5s 2215 464 22.0000 43 30 21.0000 24.0000 14.3% 33.2 10s Cutting planes: Gomory: 175 Cover: 25 Implied bound: 87 MIR: 150 Explored 2550 nodes (84600 simplex iterations) in 11.67 seconds Thread count was 1 (of 4 available processors) Optimal solution found (tolerance 1.00e-01) Best objective 2.1000000000e+01, best bound 2.3000000000e+01, gap 9.5238%

# Detailed Descriptions of GUROBI Options

**aggfill** *(integer)*: Controls the amount of fill allowed during presolve aggregation ↵

Default:

`10`

**aggregate** *(integer)*: Enables or disables aggregation in presolve ↵

Default:

`1`

**barconvtol** *(real)*: Controls barrier termination ↵

The barrier solver terminates when the relative difference between the primal and dual objective values is less than the specified tolerance.

Default:

`1e-8`

**barcorrectors** *(integer)*: Limits the number of central corrections performed in each barrier iteration ↵

The default value is chosen automatically, depending on problem characteristics.

Default:

`-1`

**barhomogeneous** *(integer)*: Homogeneous barrier algorithm selection ↵

Determines whether to use the homogeneous barrier algorithm. At the default setting (-1), it is only used when barrier solves a node relaxation for a MIP model. Setting the parameter to 0 turns it off, and setting it to 1 forces it on. The homogeneous algorithm is useful for recognizing infeasibility or unboundedness. It is a bit slower than the default algorithm.

Default:

`-1`

value meaning `-1`

Auto `0`

Homogeneous Barrier off `1`

Force Homogeneous Barrier on

**bariterlimit** *(integer)*: Limits the number of barrier iterations performed ↵

Default:

`infinity`

**barorder** *(integer)*: Chooses the barrier sparse matrix fill-reducing algorithm ↵

Default:

`-1`

value meaning `-1`

Auto `0`

Approximate Minimum Degree ordering `1`

Nested Dissection ordering

**barqcpconvtol** *(real)*: Convergence tolerance for the barrier algorithm when solving a QCP ↵

When solving a QCP model, the barrier solver terminates when the relative difference between the primal and dual objective values is less than the specified tolerance. Tightening this tolerance may lead to a more accurate solution, but it may also lead to a failure to converge.

Default:

`1e-6`

**bestbdstop** *(real)*: Objective bound to stop optimization ↵

Terminates as soon as the engine determines that the best bound on the objective value is at least as good as the specified value.

Default:

`maxdouble`

**bestobjstop** *(real)*: Objective value to stop optimization ↵

Terminate as soon as the engine finds a feasible solution whose objective value is at least as good as the specified value.

Default:

`mindouble`

**branchdir** *(integer)*: Determines which child node is explored first in the branch-and-cut search ↵

This option allows more control over how the branch-and-cut tree is explored. Specifically, when a node in the MIP search is completed and two child nodes, corresponding to the down branch and the up branch are created, this parameter allows you to determine whether the MIP solver will explore the down branch first, the up branch first, or whether it will choose the next node based on a heuristic determination of which sub-tree appears more promising.

Default:

`0`

value meaning `-1`

Always explore the down branch first `0`

Automatic `1`

Always explore the up branch first

**cliquecuts** *(integer)*: Controls clique cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**computeserver** *(string)*: List of Gurobi compute servers ↵

This option will use the Gurobi compute server facility to solve the model. The value of the option is a comma separated list of IP addresses or computer names of Gurobi compute servers. On the compute servers, a full Gurobi installation (not just GAMS/Gurobi) is required with an appropriate Gurobi compute server license.

**concurrentjobs** *(integer)*: Distributed concurrent MIP job count ↵

Enables distributed concurrent optimization, which can be used to solve LP or MIP models on multiple machines. A value of

ncauses the solver to createnindependent models, using different parameter settings for each. Each of these models is sent to a distributed worker for processing. Optimization terminates when the first solve completes. Use the WorkerPool parameter to provide a list of available distributed workers.By default, Gurobi chooses the parameter settings used for each independent solve automatically. The intent of concurrent MIP solving is to introduce additional diversity into the MIP search. By bringing the resources of multiple machines to bear on a single model, this approach can sometimes solve models much faster than a single machine.

Default:

`0`

**concurrentmip** *(integer)*: Enables the concurrent MIP solver ↵

This parameter enables the concurrent MIP solver. When the parameter is set to value

n, the MIP solver performsnindependent MIP solves in parallel, with different parameter settings for each. Optimization terminates when the first solve completes. Gurobi chooses the parameter settings used for each independent solve automatically. The intent of concurrent MIP solving is to introduce additional diversity into the MIP search. This approach can sometimes solve models much faster than applying all available threads to a single MIP solve, especially on very large parallel machines.The concurrent MIP solver divides available threads evenly among the independent solves. For example, if you have 6 threads available and you set ConcurrentMIP to 2, the concurrent MIP solver will allocate 3 threads to each independent solve. Note that the number of independent solves launched will not exceed the number of available threads.

The concurrent MIP solver produces a slightly different log from the standard MIP solver. The log only provides periodic summary information. Each concurrent MIP log line shows the objective for the best feasible solution found by any of the independent solves to that point, the best objective bound proved by any of the independent solves, and the relative gap between these two values. Gurobi also includes node counts from one of the independent solves, as well as elapsed times, to give some indication of forward progress.

Default:

`1`

**covercuts** *(integer)*: Controls cover cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**crossover** *(integer)*: Determines the crossover strategy used to transform the barrier solution into a basic solution ↵

Use value 0 to disable crossover; the solver will return an interior solution. Other options control whether the crossover algorithm tries to push primal or dual variables to bounds first, and then which simplex algorithm is used once variable pushing is complete. Options 1 and 2 push dual variables first, then primal variables. Option 1 finishes with primal, while option 2 finishes with dual. Options 3 and 4 push primal variables first, then dual variables. Option 3 finishes with primal, while option 4 finishes with dual The default value of -1 chooses automatically.

Default:

`-1`

**crossoverbasis** *(integer)*: Determines the initial basis construction strategy for crossover ↵

The default value (0) chooses an initial basis quickly. A value of 1 can take much longer, but often produces a much more numerically stable start basis.

Default:

`0`

**cspassword** *(string)*: Password for Gurobi compute servers ↵

**csport** *(integer)*: The port number used to connect to the compute server ↵

You should use the default value, which indicates that the default port should be used, unless your server administrator has changed our recommended port settings.

Default:

`-1`

**cspriority** *(integer)*: Job priority on the compute server ↵

Gurobi compute servers support job priorities. You can assign an integer priority between -100 and 100 to each job (the default is 0). When choosing among queued jobs, the compute server will run the highest priority job first. Note that servers will never preempt running jobs.

We have chosen to give priority 100 a special meaning. A priority 100 job will start immediately, even if this means that a server will exceed its job limit. You should be cautious with priority 100 jobs, since submitting too many at once could lead to very high server loads, which could lead to poor performance and even crashes in extreme cases.

Default:

`0`

**cstimeoutfrac** *(real)*: Fraction of reslim that job will wait to reach front of the compute server queue ↵

If the compute servers are all busy, new jobs will be queued. This option controls the fraction of the available time (ResLim) that one is willing to wait in the queue before the optimization can start. This waiting time does not count towards the actual time available to the optimizer.

Default:

`0.1`

**cutaggpasses** *(integer)*: Maximum number of aggregation passes during cut generation ↵

A non-negative value indicates the maximum number of constraint aggregation passes performed during cut generation. See the description of the global Cuts parameter for further information.

Default:

`-1`

**cutoff** *(real)*: Sets a target objective value ↵

Optimization will terminate if the engine determines that the optimal objective value for the model is worse than the specified cutoff. This option overwrites the GAMS cutoff option.

Default:

`0`

**cutpasses** *(integer)*: Maximum number of cutting plane passes performed during root cut generation ↵

Default:

`-1`

**cuts** *(integer)*: Global cut generation control ↵

The parameters,

`Cuts`

, CliqueCuts, CoverCuts, FlowCoverCuts, FlowPathCuts, GUBCoverCuts, ImpliedCuts, InfProofCuts, MIPSepCuts, MIRCuts, ModKCuts, NetworkCuts, GomoryPasses, StrongCGCuts, SubMIPCuts, CutAggPasses and ZeroHalfCuts, affect the generation of MIP cutting planes. In all cases except GomoryPasses and CutAggPasses, a value of -1 corresponds to an automatic setting, which allows the solver to determine the appropriate level of aggressiveness in the cut generation. Unless otherwise noted, settings of 0, 1, and 2 correspond to no cut generation, conservative cut generation, or aggressive cut generation, respectively. The`Cuts`

parameter provides global cut control, affecting the generation of all cuts. This parameter also has a setting of 3, which corresponds to very aggressive cut generation. The other parameters override the global`Cuts`

parameter (so setting`Cuts`

to 2 and CliqueCuts to 0 would generate all cut types aggressively, except clique cuts which would not be generated at all. Setting`Cuts`

to 0 and GomoryPasses to 10 would not generate any cuts except Gomory cuts for 10 passes).Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive `3`

Very aggressive

**degenmoves** *(integer)*: Degenerate simplex moves ↵

Limits degenerate simplex moves. These moves are performed to improve the integrality of the current relaxation solution. By default, the algorithm chooses the number of moves to perform automatically.

Changing the value of this parameter can help performance in cases where an excessive amount of time is spent after the initial root relaxation has been solved but before the cut generation process or the root heuristics have started.

Default:

`-1`

**disconnected** *(integer)*: Disconnected component strategy ↵

A MIP model can sometimes be made up of multiple, completely independent sub-models. This parameter controls how aggressively we try to exploit this structure. A value of 0 ignores this structure entirely, while larger values try more aggressive approaches. The default value of -1 chooses automatically. This only affects mixed integer programming (MIP) models.

Default:

`-1`

value meaning `-1`

Auto `0`

Ignores structure entirely `1`

Conservative `2`

Aggressive

**displayinterval** *(integer)*: Controls the frequency at which log lines are printed in seconds ↵

Default:

`5`

**distributedmipjobs** *(integer)*: Distributed MIP job count ↵

Enables distributed MIP. A value of

ncauses the MIP solver to divide the work of solving a MIP model amongnmachines. Use the WorkerPool parameter to provide the list of available machines.Default:

`0`

**feasibilitytol** *(real)*: Primal feasibility tolerance ↵

All constrains must be satisfied to a tolerance of

`FeasibilityTol`

.Range: [

`1e-9`

,`1e-2`

]Default:

`1e-6`

**feasopt** *(boolean)*: Computes a minimum-cost relaxation to make an infeasible model feasible ↵

With

`Feasopt`

turned on, a minimum-cost relaxation of the right hand side values of constraints or bounds on variables is computed in order to make an infeasible model feasible. It marks the relaxed right hand side values and bounds in the solution listing.Several options are available for the metric used to determine what constitutes a minimum-cost relaxation which can be set by option FeasOptMode.

Feasible relaxations are available for all problem types.

Default:

`0`

value meaning `0`

Turns Feasible Relaxation off `1`

Turns Feasible Relaxation on

**feasoptmode** *(integer)*: Mode of FeasOpt ↵

The parameter

`FeasOptMode`

allows different strategies in finding feasible relaxation in one or two phases. In its first phase, it attempts to minimize its relaxation of the infeasible model. That is, it attempts to find a feasible solution that requires minimal change. In its second phase, it finds an optimal solution (using the original objective) among those that require only as much relaxation as it found necessary in the first phase. Values of the parameter`FeasOptMode`

indicate two aspects: (1) whether to stop in phase one or continue to phase two and (2) how to measure the minimality of the relaxation (as asumof required relaxations; as thenumberof constraints and bounds required to be relaxed; as asum of the squaresof required relaxations).Default:

`0`

value meaning `0`

Minimize sum of relaxations

Minimize the sum of all required relaxations in first phase only`1`

Minimize sum of relaxations and optimize

Minimize the sum of all required relaxations in first phase and execute second phase to find optimum among minimal relaxations`2`

Minimize number of relaxations

Minimize the number of constraints and bounds requiring relaxation in first phase only`3`

Minimize number of relaxations and optimize

Minimize the number of constraints and bounds requiring relaxation in first phase and execute second phase to find optimum among minimal relaxations`4`

Minimize sum of squares of relaxations

Minimize the sum of squares of required relaxations in first phase only`5`

Minimize sum of squares of relaxations and optimize

Minimize the sum of squares of required relaxations in first phase and execute second phase to find optimum among minimal relaxations

**.feaspref** *(real)*: feasibility preference ↵

You can express the costs associated with relaxing a bound or right hand side value during a FeasOpt run through the

`.feaspref`

option. The syntax for dot options is explained in the Introduction chapter of the Solver Manual. The input value denotes the users willingness to relax a constraint or bound. More precisely, the reciprocal of the specified value is used to weight the relaxation of that constraint or bound. The user may specify a preference value less than or equal to 0 (zero), which denotes that the corresponding constraint or bound must not be relaxed.Default:

`1`

**fixoptfile** *(string)*: Option file for fixed problem optimization ↵

**flowcovercuts** *(integer)*: Controls flow cover cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**flowpathcuts** *(integer)*: Controls flow path cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**freegamsmodel** *(boolean)*: Preserves memory by dumping the GAMS model instance representation temporarily to disk ↵

Default:

`0`

**.genconstrtype** *(integer)*: General constraint type ↵

Mathematical programming has traditionally defined a set of fundamental constraint types: variable bound constraints, linear constraints, quadratic constraints, integrality constraints, and SOS constraints. These are typically treated directly by the underlying solver (although not always), and are fundamental to the overall algorithm.

Gurobi accepts a number of additional constraint types, which we collectively refer to as

general constraints. These are typically not treated directly by the solver. Rather, they are transformed by presolve into mathematically equivalent sets of constraints (and variables), chosen from among the fundamental types listed above. These general constraints are provided as a convenience to users. If such constraints appear in your model, but if you prefer to reformulate them yourself using fundamental constraint types instead, you can certainly do so. However, note that Gurobi can sometimes exploit information contained in the other constraints in the model to build a more efficient formulation than what you might create. Gurobi does not allow general logical constraints but needs the constraint with a single operator (eithermaxorminor ...). In order to pass the general constraint type to Gurobi we interpret a linear constraint plus the value of the`GenConstrType`

option. Such a linear constraint has a resultant variable (r or rb) on the left hand side of`=E=`

) and the variables involved in the operation on the right hand side:

MAX constraint:eqMax.. r =e= max(x1,x2,x3,c);is represented in the following form:

eqMax.. r =e= x1+x2+x3+c;with GAMS/GUROBI option

`eqMax.GenConstrType=1`

.

MIN constraint:eqMin.. r =e= min(x1,x2,x3,c);is represented in the following form:

eqMin.. r =e= x1+x2+x3+c;with GAMS/GUROBI option

`eqMin.GenConstrType=2`

.

ABS constraint:eqAbs.. r =e= abs(x1);is represented in the following form:

eqAbs.. r =e= x1;with GAMS/GUROBI option

`eqAbs.GenConstrType=3`

.

AND constraint:eqAnd.. br =e= b1 and b2 and b3 and b4;is represented in the following form:

eqAnd.. br =e= b1+b2+b3+b4;with GAMS/GUROBI option

`eqAnd.GenConstrType=4`

.

OR constraint:eqOr.. br =e= b1 or b2 or b3 or b4;is represented in the following form:

eqOr.. br =e= b1+b2+b3+b4;with GAMS/GUROBI option

`eqOr.GenConstrType=5`

.Note that for the AND and OR constraint the resultant variable needs to be a binary variable. The default value for parameter

`GenConstrType`

of a constraint is 0 marking it as a regular constraint (linear or quadratic).Default:

`0`

**gomorypasses** *(integer)*: Maximum number of Gomory cut passes ↵

A non-negative value indicates the maximum number of Gomory cut passes performed. See the description of the global Cuts parameter for further information.

Default:

`-1`

**gubcovercuts** *(integer)*: Controls GUB cover cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**heuristics** *(real)*: Controls the amount of time spent in MIP heuristics ↵

Larger values produce more and better feasible solutions, at a cost of slower progress in the best bound.

Range: [

`0`

,`1`

]Default:

`0.05`

**iis** *(boolean)*: Run the Irreducible Inconsistent Subsystem (IIS) finder if the problem is infeasible ↵

Default:

`0`

value meaning `0`

Do not run the IIS finder `1`

Run the IIS finder

**iismethod** *(integer)*: Controls use of IIS method ↵

Chooses the IIS method to use. Method 0 is often faster, while method 1 can produce a smaller IIS. The default value of -1 chooses automatically.

Default:

`-1`

**impliedcuts** *(integer)*: Controls implied bound cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**improvestartgap** *(real)*: Optimality gap at which the MIP solver resets a few MIP parameters ↵

The MIP solver can change parameter settings in the middle of the search in order to adopt a strategy that gives up on moving the best bound and instead devotes all of its effort towards finding better feasible solutions. This parameter allows you to specify an optimality gap at which the MIP solver will switch to this strategy. For example, setting this parameter to 0.1 will cause the MIP solver to switch once the relative optimality gap is smaller than 0.1.

Default:

`maxdouble`

**improvestartnodes** *(real)*: Solution improvement strategy control ↵

The MIP solver can change parameter settings in the middle of the search in order to adopt a strategy that gives up on moving the best bound and instead devotes all of its effort towards finding better feasible solutions. This parameter allows you to specify the node count at which the MIP solver switches to a solution improvement strategy. For example, setting this parameter to 10 will cause the MIP solver to switch strategies once the node count is larger than 10.

Default:

`maxdouble`

**improvestarttime** *(real)*: Elapsed time after which the MIP solver resets a few MIP parameters ↵

The MIP solver can change parameter settings in the middle of the search in order to adopt a strategy that gives up on moving the best bound and instead devotes all of its effort towards finding better feasible solutions. This parameter allows you to specify a time limit when the MIP solver will switch to this strategy. For example, setting this parameter to 10 will cause the MIP solver to switch 10 seconds after starting the optimization.

Default:

`maxdouble`

**infproofcuts** *(integer)*: Infeasibility proof cut generation ↵

Controls infeasibility proof cut generation. Use 0 to disable these cuts, 1 for moderate cut generation, or 2 for aggressive cut generation. The default -1 value chooses automatically. Overrides the Cuts parameter.

Default:

`-1`

**intfeastol** *(real)*: Integer feasibility tolerance ↵

An integrality restriction on a variable is considered satisfied when the variable's value is less than

`IntFeasTol`

from the nearest integer value.Range: [

`1e-9`

,`1e-1`

]Default:

`1e-5`

**iterationlimit** *(real)*: Limits the number of simplex iterations performed ↵

Default:

`infinity`

**kappa** *(boolean)*: Display approximate condition number estimates for the optimal simplex basis ↵

Default:

`0`

value meaning `0`

Do not compute and display approximate condition number `1`

Compute and display approximate condition number

**kappaexact** *(boolean)*: Display exact condition number estimates for the optimal simplex basis ↵

Default:

`0`

value meaning `0`

Do not compute and display exact condition number `1`

Compute and display exact condition number

**.lazy** *(integer)*: Lazy constraints value ↵

Determines whether a linear constraint is treated as a lazy constraint. At the beginning of the MIP solution process, any constraint whose Lazy attribute is set to 1, 2, or 3 (the default value is 0) is removed from the model and placed in the lazy constraint pool. Lazy constraints remain inactive until a feasible solution is found, at which point the solution is checked against the lazy constraint pool. If the solution violates any lazy constraints, the solution is discarded and one of more of the violated lazy constraints are pulled into the active model.

Larger values for this attribute cause the constraint to be pulled into the model more aggressively. With a value of 1, the constraint can be used to cut off a feasible solution, but it won't necessarily be pulled in if another lazy constraint also cuts off the solution. With a value of 2, all lazy constraints that are violated by a feasible solution will be pulled into the model. With a value of 3, lazy constraints that cut off the relaxation solution are also pulled in.

Only affects MIP models. Lazy constraints are only active if option LazyConstraints is enabled and are specified through the option

`.lazy`

. The syntax for dot options is explained in the Introduction chapter of the Solver Manual.Default:

`0`

**lazyconstraints** *(boolean)*: Indicator to use lazy constraints ↵

Default:

`0`

**markowitztol** *(real)*: Threshold pivoting tolerance ↵

Used to limit numerical error in the simplex algorithm. A larger value may avoid numerical problems in rare situations, but it will also harm performance.

Range: [

`1e-4`

,`0.999`

]Default:

`0.0078125`

**method** *(integer)*: Algorithm used to solve continuous models ↵

Synonyms: lpmethod rootmethod

Concurrent optimizers run multiple solvers on multiple threads simultaneously, and choose the one that finishes first. Deterministic concurrent (4) gives the exact same result each time, while concurrent (3) is often faster but can produce different optimal bases when run multiple times. In the current release, the default Automatic (-1) will choose non-deterministic concurrent (3) for an LP, barrier (2) for a QP, and dual (1) for the MIP root node. Only simplex and barrier algorithms are available for continuous QP models. Only primal and dual simplex are available for solving the root of an MIQP model. Only barrier is available for continuous QCP models.

The default setting is rarely significantly slower than the best possible setting, so you generally won't see a big gain from changing this parameter. There are classes of models where one particular algorithm is consistently fastest, though, so you may want to experiment with different options when confronted with a particularly difficult model.

Note that if memory is tight on an LP model, you should consider choosing the dual simplex method (

`Method=1`

). The default will invoke the concurrent optimizer, which typically consumes a lot more memory than dual simplex alone.Default:

`-1`

value meaning `-1`

Automatic `0`

Primal simplex `1`

Dual simplex `2`

Barrier `3`

Concurrent `4`

Deterministic concurrent

**minrelnodes** *(integer)*: Number of nodes to explore in the Minimum Relaxation heuristic ↵

This parameter controls the Minimum Relaxation heuristic that can be useful for finding solutions to MIP models where other strategies fail to find feasible solutions in a reasonable amount of time. This heuristic is only applied at the end of the MIP root, and only when no other root heuristic finds a feasible solution.

Default:

`0`

**mipfocus** *(integer)*: Controls the focus of the MIP solver ↵

Default:

`0`

value meaning `0`

Balance between finding good feasible solutions and proving optimality `1`

Focus towards finding feasible solutions `2`

Focus towards proving optimality `3`

Focus on moving the best objective bound

**mipgap** *(real)*: Relative MIP optimality gap ↵

The MIP engine will terminate (with an optimal result) when the gap between the lower and upper objective bound is less than

`MipGap`

times the upper bound.Range: [

`0`

, ∞]Default:

`GAMS optcr`

**mipgapabs** *(real)*: Absolute MIP optimality gap ↵

The MIP solver will terminate (with an optimal result) when the gap between the lower and upper objective bound is less than

`MIPGapAbs`

.Range: [

`0`

, ∞]Default:

`GAMS optca`

**mipsepcuts** *(integer)*: Controls MIP separation cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**mipstart** *(boolean)*: Use mip starting values ↵

Default:

`0`

value meaning `0`

Do not use the values `1`

Use the values

**miqcpmethod** *(integer)*: Determines whether outer approximation is used to solve an MIQCP model. ↵

Controls the method used to solve MIQCP models. Value 1 uses a linearized, outer-approximation approach, while value 0 solves continuous QCP relaxations at each node. The default setting (-1) chooses automatically.

Default:

`-1`

value meaning `-1`

Auto `0`

Linearized, outer-approximation approach `1`

Continuous QCP relaxations at each node

**mircuts** *(integer)*: Controls MIR cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**modkcuts** *(integer)*: Controls the generation of mod-k cuts ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

**multobj** *(boolean)*: Controls the hierarchical optimization of multiple objectives ↵

Default:

`0`

**names** *(boolean)*: Indicator for loading names ↵

Default:

`1`

value meaning `0`

Do not load GAMS names into Gurobi model `1`

Load GAMS names into Gurobi model

**networkcuts** *(integer)*: Controls network cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**nodefiledir** *(string)*: Nodefile directory ↵

Determines the directory into which nodes are written when node memory usage exceeds the specified NodefileStart value.

Default:

`.`

**nodefilestart** *(real)*: Nodefile starting indicator ↵

Controls the point at which MIP tree nodes are written to disk. Whenever node storage exceeds the specified value (in GBytes), nodes are written to disk.

Default:

`maxdouble`

**nodelimit** *(real)*: Limits the number of MIP nodes explored ↵

Default:

`maxdouble`

**nodemethod** *(integer)*: Algorithm used to solve node relaxations in a MIP model ↵

Algorithm used for MIP node relaxations. Note that barrier is not an option for MIQP node relaxations.

Default:

`1`

value meaning `0`

Primal simplex `1`

Dual simplex `2`

Barrier

**norelheuristic** *(boolean)*: No relaxation heuristic attempts to find feasible solutions without solving root relaxation ↵

Gurobi 5.6.2 introduces an experimental no relaxation heuristic that attempts to find good quality feasible solutions to MIP models without first solving the root relaxation. This can be useful in situations where the root relaxation is extremely large or difficult.

Default:

`0`

value meaning `0`

Do not use no relaxation heuristic `1`

Try no relaxation heuristic

**normadjust** *(integer)*: Pricing norm variants ↵

Chooses from among multiple pricing norm variants. The default value of -1 chooses automatically.

Default:

`-1`

**numericfocus** *(integer)*: Set the numerical focus ↵

The

`NumericFocus`

parameter controls the degree to which the code attempts to detect and manage numerical issues. The default setting makes an automatic choice, with a slight preference for speed. Settings 1-3 increasingly shift the focus towards being more careful in numerical computations. With higher values, the code will spend more time checking the numerical accuracy of intermediate results, and it will employ more expensive techniques in order to avoid potential numerical issues.Default:

`0`

**objnabstol** *(string)*: Allowable absolute degradation for objective ↵

This parameter is used to set the allowable degradation for an objective when doing hierarchical multi-objective optimization (MultObj). The syntax for this parameter is

`ObjNAbsTol ObjVarName value`

.Hierarchical multi-objective optimization will optimize for the different objectives in the model one at a time, in priority order. If it achieves objective value z when it optimizes for this objective, then subsequent steps are allowed to degrade this value by at most

`ObjNAbsTol`

.

**objnreltol** *(string)*: Allowable relative degradation for objective ↵

This parameter is used to set the allowable degradation for an objective when doing hierarchical multi-objective optimization (MultObj). The syntax for this parameter is

`ObjNRelTol ObjVarName value`

.Hierarchical multi-objective optimization will optimize for the different objectives in the model one at a time, in priority order. If it achieves objective value z when it optimizes for this objective, then subsequent steps are allowed to degrade this value by at most

`ObjNRelTol*|z|`

.

**objscale** *(real)*: Objective coefficients scaling ↵

Divides the model objective by the specified value to avoid numerical errors that may result from very large objective coefficients. The default value of 0 decides on the scaling automatically. A value less than zero uses the maximum coefficient to the specified power as the scaling (so

`ObjScale=-0.5`

would scale by the square root of the largest objective coefficient).Range: [

`-1`

, ∞]Default:

`0`

**optimalitytol** *(real)*: Dual feasibility tolerance ↵

Reduced costs must all be larger than

`OptimalityTol`

in the improving direction in order for a model to be declared optimal.Range: [

`1e-9`

,`1e-2`

]Default:

`1e-6`

**perturbvalue** *(real)*: Magnitude of simplex perturbation when required ↵

Range: [

`0`

,`0.01`

]Default:

`0.0002`

**poolgap** *(real)*: Maximum gap for stored solutions ↵

Determines how large a gap to tolerate in stored solutions. When this parameter is set to a non-default value, solutions whose objective values exceed that of the best known solution by more than the specified (relative) gap are discarded. For example, if the MIP solver has found a solution at objective 100, then a setting of

`PoolGap=0.2`

would discard solutions with objective worse than 120 (assuming a minimization objective).Default:

`maxdouble`

**poolsearchmode** *(integer)*: Selects different modes for exploring the MIP search tree ↵

With the default setting (

`PoolSearchMode=0`

), the MIP solver tries to find an optimal solution to the model. It keeps other solutions found along the way, but those are incidental. By setting this parameter to a non-default value, the MIP search will continue after the optimal solution has been found in order to find additional, high-quality solutions. With a setting of 2, it will find the n best solutions, where n is determined by the value of the PoolSolutions parameter. With a setting of 1, it will try to find additional solutions, but with no guarantees about the quality of those solutions. The cost of the solve will increase with increasing values of this parameter.Once optimization is complete, the

PoolObjBoundattribute (printed to the log) can be used to evaluate the quality of the solutions that were found. For example, a value of`PoolObjBound=100`

indicates that there are no other solutions with objective better 100, and thus that any known solutions with objective better than 100 are better than any as-yet undiscovered solutions.Default:

`0`

**poolsolutions** *(integer)*: Number of MIP solutions to store ↵

Determines how many MIP solutions are stored. For the default value of PoolSearchMode, these are just the solutions that are found along the way in the process of exploring the MIP search tree. For other values of PoolSearchMode, this parameter sets a target for how many solutions to find, so larger values will impact performance.

Default:

`10`

**precrush** *(integer)*: Presolve constraint option ↵

Allows presolve to translate constraints on the original model to equivalent constraints on the presolved model. This parameter is turned on when you use BCH with Gurobi.

Default:

`0`

**predeprow** *(integer)*: Controls the presolve dependent row reduction ↵

Controls the presolve dependent row reduction, which eliminates linearly dependent constraints from the constraint matrix. The default setting (-1) applies the reduction to continuous models but not to MIP models. Setting 0 turns the reduction off for all models. Setting 1 turns it on for all models.

Default:

`-1`

**predual** *(integer)*: Controls whether presolve forms the dual of a continuous model ↵

Depending on the structure of the model, solving the dual can reduce overall solution time. The default setting uses a heuristic to decide. Setting 0 forbids presolve from forming the dual, while setting 1 forces it to take the dual. Setting 2 employs a more expensive heuristic that forms both the presolved primal and dual models (on two threads), and heuristically chooses one of them.

Default:

`-1`

**premiqcpform** *(integer)*: Determines the format of the presolved version of an MIQCP model ↵

Option 0 leaves the model in MIQCP form, so the branch-and-cut algorithm will operate on a model with arbitrary quadratic constraints. Option 1 always transforms the model into MISOCP form; quadratic constraints are transformed into second-order cone constraints. Option 2 always transforms the model into disaggregated MISOCP form; quadratic constraints are transformed into rotated cone constraints, where each rotated cone contains two terms and involves only three variables.

Default:

`-1`

value meaning `-1`

Auto `0`

Always leaves the model in MIQCP form `1`

Always transforms the model into MISOCP form `2`

Always transforms the model into disaggregated MISOCP form

**premiqpmethod** *(integer)*: Transformation presolve performs on MIQP models ↵

Chooses the transformation presolve performs on MIQP models.

Default:

`-1`

value meaning `-1`

Auto `0`

Always leaves the model as an MIQP `1`

Attempts to transform the model into an MILP

**prepasses** *(integer)*: Controls the number of passes performed by presolve ↵

Limits the number of passes performed by presolve. The default setting (-1) chooses the number of passes automatically.

Default:

`-1`

**preqlinearize** *(integer)*: Controls linearization of Q matrices in the quadratic constraints or a quadratic objective ↵

Option 1 attempts to linearize quadratic constraints or a quadratic objective, potentially transforming an MIQP or MIQCP into an MILP. Option 0 shuts off the transformation. The default setting (-1) choose automatically. The automatic setting works well, but there are cases where forcing Q linearization can be beneficial.

Default:

`-1`

value meaning `-1`

Auto `0`

Linearization off `1`

Force Linearization on

**presolve** *(integer)*: Controls the presolve level ↵

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**presos1bigm** *(real)*: Threshold for SOS1-to-binary reformulation ↵

Controls the automatic reformulation of SOS1 constraints into binary form. SOS1 constraints are often handled more efficiently using a binary representation. The reformulation often requires big-M values to be introduced as coefficients. This parameter specifies the largest big-M that can be introduced by presolve when performing this reformulation. Larger values increase the chances that an SOS1 constraint will be reformulated, but very large values (e.g., 1e8) can lead to numerical issues.

The default value of -1 chooses a threshold automatically. You should set the parameter to 0 to shut off SOS1 reformulation entirely, or a large value to force reformulation.

Range: [

`-1`

, ∞]Default:

`-1`

**presos2bigm** *(real)*: Threshold for SOS2-to-binary reformulation ↵

Controls the automatic reformulation of SOS2 constraints into binary form. SOS2 constraints are often handled more efficiently using a binary representation. The reformulation often requires big-M values to be introduced as coefficients. This parameter specifies the largest big-M that can be introduced by presolve when performing this reformulation. Larger values increase the chances that an SOS2 constraint will be reformulated, but very large values (e.g., 1e8) can lead to numerical issues.

The default value of 0 disables the reformulation. You can set the parameter to -1 to choose an automatic approach, or a large value to force reformulation.

Range: [

`-1`

, ∞]Default:

`0`

**presparsify** *(boolean)*: Enables the presolve sparsify reduction for MIP models ↵

This reduction can sometimes significantly reduce the number of nonzero values in the presolved model.

Default:

`0`

value meaning `0`

Disable the presolve sparsify reduction `1`

Enable the presolve sparsify reduction

**printoptions** *(boolean)*: List values of all options to GAMS listing file ↵

Default:

`0`

value meaning `0`

Do not list option values to GAMS listing file `1`

List option values to GAMS listing file

**.prior** *(real)*: Branching priorities ↵

GAMS allows to specify priorities for discrete variables only. Gurobi can detect that continuous variables are implied discrete variables and can utilize priorities. Such priorities can be specified through a GAMS/Gurobi solver option file. The syntax for dot options is explained in the Introduction chapter of the Solver Manual. The priorities are only passed on to Gurobi if the model attribute

`priorOpt`

is turned on.Default:

`1`

**psdtol** *(real)*: limit on the amount of diagonal perturbation ↵

Positive semi-definite tolerance (for QP/MIQP). Sets a limit on the amount of diagonal perturbation that the optimizer is allowed to automatically perform on the Q matrix in order to correct minor PSD violations. If a larger perturbation is required, the optimizer will terminate stating the problem is not PSD.

Range: [

`0`

, ∞]Default:

`1e-6`

**pumppasses** *(integer)*: Number of passes of the feasibility pump heuristic ↵

Note that this heuristic is only applied at the end of the MIP root, and only when no other root heuristic found a feasible solution.

Default:

`0`

**qcpdual** *(boolean)*: Determines whether dual variable values are computed for QCP models ↵

Determines whether dual variable values are computed for QCP models. Computing them can add significant time to the optimization, so you should turn this parameter to 0 if you do not need them.

Default:

`1`

value meaning `0`

Do not compute dual for QCP problem `1`

Compute dual for QCP problem

**quad** *(integer)*: Quad precision computation in simplex ↵

Enables or disables quad precision computation in simplex. The -1 default setting allows the algorithm to decide.

Default:

`-1`

**readparams** *(string)*: Read Gurobi parameter file ↵

**rerun** *(integer)*: Resolve without presolve in case of unbounded or infeasible ↵

In case Gurobi reports

Model was proven to be either infeasible or unbounded, this option decides about a resolve without presolve which will determine the exact model status. If the option is set toauto, which is the default, and the model fits into demo limits, the problems is resolved.Default:

`0`

value meaning `-1`

No `0`

Auto `1`

Yes

**rins** *(integer)*: Frequency of the RINS heuristic ↵

Default value (-1) chooses automatically. A value of 0 shuts off RINS. A positive value

napplies RINS at everyn-th node of the MIP search tree.Default:

`-1`

**scaleflag** *(integer)*: Enables or disables model scaling ↵

Controls model scaling. By default, the rows and columns of the model are scaled in order to improve the numerical properties of the constraint matrix. The scaling is removed before the final solution is returned. Scaling typically reduces solution times, but it may lead to larger constraint violations in the original, unscaled model. Turning off scaling

`ScaleFlag=0`

can sometimes produce smaller constraint violations. Choosing a more aggressive scaling option`ScaleFlag=2`

can sometimes improve performance for particularly numerically difficult models.freegamsmodel In order to provide the maximum amount of memory to the solver this option dumps the internal representation of the model instance temporarily to disk and frees memory. This option only works with

`SolveLink=0`

and only for models without quadratic constraints.Default:

`1`

**seed** *(integer)*: Random number seed ↵

Modifies the random number seed. This acts as a small perturbation to the solver, and typically leads to different solution paths.

Default:

`0`

**sensitivity** *(boolean)*: Provide sensitivity information ↵

Default:

`0`

value meaning `0`

Do not provide sensitivity information `1`

Provide sensitivity information

**sifting** *(integer)*: Sifting within dual simplex ↵

Enables or disables sifting within dual simplex. Sifting is often useful for LP models where the number of variables is many times larger than the number of constraints. With a

Moderatesetting, sifting will be applied to LP models and to the root node for MIP models. With anAggressivesetting, sifting will be also applied to the nodes of a MIP. Note that this parameter has no effect if you aren't using dual simplex. Note also that sifting will be skipped in cases where it is obviously a worse choice, even when sifting has been selected.Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Moderate `2`

Agressive

**siftmethod** *(integer)*: LP method used to solve sifting sub-problems ↵

Note that this parameter only has an effect when you are using dual simplex and sifting has been selected (either by the automatic method, or through the Sifting parameter).

Default:

`-1`

value meaning `-1`

Auto `0`

Primal Simplex `1`

Dual Simplex `2`

Barrier

**simplexpricing** *(integer)*: Determines variable pricing strategy ↵

Default:

`-1`

value meaning `-1`

Auto `0`

Partial Pricing `1`

Steepest Edge `2`

Devex `3`

Quick-Start Steepest Edge

**solnpool** *(string)*: Controls export of alternate MIP solutions ↵

The GDX file specified by this option will contain a set call

`index`

that contains the names of GDX files with the individual solutions. For details see example model`dumpsol`

in the GAMS Test Library. The option PoolSolutions, PoolSearchModel, and PoolGap control the search for alternative solutions. Please also refer to the secion Solution Pool.threads Default number of parallel threads allowed for any solution method. Non-positive values are interpreted as the number of cores to leave free so setting threads to 0 uses all available cores while setting threads to -1 leaves one core free for other tasks.

**solutionlimit** *(integer)*: Limits the number of feasible solutions found ↵

Default:

`maxint`

**solvefixed** *(boolean)*: Indicator for solving the fixed problem for a MIP to get a dual solution ↵

Default:

`1`

value meaning `0`

Do not solve the fixed problem `1`

Solve the fixed problem

**strongcgcuts** *(integer)*: Strong-CG cut generation ↵

Controls Strong Chvátal-Gomory (Strong-CG) cut generation. Use 0 to disable these cuts, 1 for moderate cut generation, or 2 for aggressive cut generation. The default -1 value chooses automatically. Overrides the Cuts parameter.

Default:

`-1`

**submipcuts** *(integer)*: Controls the generation of sub-MIP cutting planes ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

**submipnodes** *(integer)*: Limits the number of nodes explored by the heuristics ↵

Limits the number of nodes explored by the heuristics, like RINS. Exploring more nodes can produce better solutions, but it generally takes longer.

Default:

`500`

**symmetry** *(integer)*: Controls MIP symmetry detection ↵

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**threads** *(integer)*: Controls the number of threads to apply to parallel MIP or Barrier ↵

Default:

`GAMS threads`

**timelimit** *(real)*: Limits the total time expended in seconds ↵

Default:

`GAMS reslim`

**tunecriterion** *(integer)*: Tuning criterion ↵

Modifies the tuning criterion for the tuning tool. The primary tuning criterion is always to minimize the runtime required to find a proven optimal solution. However, for MIP models that don't solve to optimality within the specified time limit, a secondary criterion is needed. Set this parameter to 1 to use the optimality gap as the secondary criterion. Choose a value of 2 to use the objective of the best feasible solution found. Choose a value of 3 to use the best objective bound. Choose 0 to ignore the secondary criterion and focus entirely on minimizing the time to find a proven optimal solution. The default value of -1 chooses automatically.

Default:

`-1`

**tunejobs** *(integer)*: Distributed tuning job count ↵

Enables distributed parallel tuning, which can significantly increase the performance of the tuning tool. A value of

ncauses the tuning tool to distribute tuning work amongnparallel jobs. These jobs are distributed among a set of workers. Use the WorkerPool parameter to provide a list of available workers.Note that distributed tuning is most effective when the workers have similar performance. Distributed tuning doesn't attempt to normalize performance by worker, so it can incorrectly attribute a boost in performance to a parameter change when the associated setting is tried on a worker that is significantly faster than the others.

Default:

`0`

**tuneoutput** *(integer)*: Tuning output level ↵

Default:

`2`

value meaning `0`

No output `1`

Summary output only when a new best parameter set is found `2`

Summary output for each parameter set that is tried `3`

Summary output, plus detailed solver output, for each parameter set tried

**tuneresults** *(integer)*: Number of improved parameter sets returned ↵

The tuning tool often finds multiple parameter sets that produce better results than the baseline settings. This parameter controls how many of these sets should be retained when tuning is complete.

Default:

`1`

**tunetimelimit** *(real)*: Time limit for tuning ↵

Limits total tuning runtime (in seconds). The default setting (-1) chooses a time limit automatically.

Default:

`-1`

**tunetrials** *(integer)*: Perform multiple runs on each parameter set to limit the effect of random noise ↵

Performance on a MIP model can sometimes experience significant variations due to random effects. As a result, the tuning tool may return parameter sets that improve on the baseline only due to randomness. This parameter allows you to perform multiple solves for each parameter set, using different Seed values for each, in order to reduce the influence of randomness on the results.

Note: Only affects mixed integer programming (MIP) models

Default:

`2`

**tuning** *(string)*: Parameter Tuning ↵

Invokes the Gurobi parameter tuning tool. The mandatory value following the keyword specifies a GAMS/Gurobi option file. All options found in this option file will be used but not modified during the tuning. A sequence of file names specifying existing problem files may follow the option file name. The files can be in MPS, REW, LP, RLP, and ILP format created by the WriteProb option. Gurobi will tune the parameters either for the problem provided by GAMS (no additional problem files specified) or for the suite of problems listed after the GAMS/Gurobi option file name without considering the problem provided by GAMS. The result of such a run is the updated GAMS/Gurobi option file with a tuned set of parameters. In case the option TuneResults is larger than 1, GAMS/Gurobi will create a sequence of GAMS/Gurobi option files. The solver and model status returned to GAMS will be

`NORMAL COMPLETION`

and`NO SOLUTION`

. Tuning is incompatible with advanced features like FeasOpt of GAMS/Gurobi.

**usebasis** *(integer)*: Use basis from GAMS ↵

If

`UseBasis`

is not specified, GAMS (via option`BRatio`

) decides if the starting basis or a primal/dual solution is given to Gurobi. If`UseBasis`

is explicitly set in an option file then the basis or a primal/dual solution is passed to Gurobi independent of the GAMS option`BRatio`

. Please note, if Gurobi uses a starting basis presolve will be skipped.Default:

`GAMS bratio`

value meaning `0`

No basis `1`

Supply basis if basis is full otherwise provide primal dual solution `2`

Supply basis iff basis is full `3`

Supply primal dual solution

**varbranch** *(integer)*: Controls the branch variable selection strategy ↵

Default:

`-1`

value meaning `-1`

Auto `0`

Pseudo Reduced Cost Branching `1`

Pseudo Shadow Price Branching `2`

Maximum Infeasibility Branching `3`

Strong Branching

**varhint** *(boolean)*: Guide heuristics and branching through variable hints ↵

If you know that a variable is likely to take a particular value in high quality solutions of a MIP model, you can provide this information as a hint. If

`VarHint`

option is active, GAMS/Gurobi will pass variable levels rounded to the nearest integer as hints to Gurobi if their level is within`TryInt`

of an integer. The closer the level is to the rounded integer the higher your level of confidence in this hint. Internally this is recalculated into a Gurobi variable hint priority: \([\frac{1}{\max(10^{-6},|x.l-[x.l]|)}]\)The Gurobi MIP solver will use these variable hints in a number of different ways. Hints will affect the heuristics that Gurobi uses to find feasible solutions, and the branching decisions that Gurobi makes to explore the MIP search tree. In general, high quality hints should produce high quality MIP solutions faster. In contrast, low quality hints will lead to some wasted effort, but shouldn't lead to dramatic performance degradations.

Variables hints and MIP starts are similar in concept, but they behave in very different ways. If you specify a MIP start, the Gurobi MIP solver will try to build a single feasible solution from the provided set of variable values. If you know a solution, you should use a MIP start to provide it to the solver. In contrast, variable hints provide guidance to the MIP solver that affects the entire solution process. If you have a general sense of the likely values for variables, you should provide them through variable hints.

Default:

`0`

**workerpassword** *(string)*: Compute server password Pool of compute servers to use for distributed algorithms ↵

When using a distributed algorithm (the distributed concurrent MIP solver or distributed tuning), this parameter allows you to specify the password for the workers listed in the WorkerPool parameter.

**workerpool** *(string)*: Pool of compute servers to use for distributed algorithms ↵

When using a distributed algorithm (the distributed concurrent solver, distributed MIP, or distributed tuning), this parameter allows you to specify a comma-separated list of workers. You can refer to workers using their names or their IP addresses. You should specify the access password, if there is one, in the WorkerPassword parameter.

To give an example, if you have two workers named server1.mydomain.com and server2.mydomain.com, with IP addresses

192.168.1.100and192.168.1.101, you could set the`WorkerPool`

to"server1.mydomain.com,server2.mydomain.comor192.168.1.100,192.168.1.101.

**workerport** *(integer)*: Non-default port number for distributed workers ↵

When using a distributed algorithm (distributed MIP, distributed concurrent, or distributed tuning), this parameter allows you to specify a non-default port number for the distributed worker machines. All workers should use the same port number. The list of distributed workers should be specified via the WorkerPool parameter.

Default:

`-1`

**writeparams** *(string)*: Write Gurobi parameter file ↵

**writeprob** *(string)*: Save the problem instance ↵

**zerohalfcuts** *(integer)*: Controls zero-half cut generation ↵

See the description of the global Cuts parameter for further information.

Default:

`-1`

value meaning `-1`

Auto `0`

Off `1`

Conservative `2`

Aggressive

**zeroobjnodes** *(integer)*: Number of nodes to explore in the zero objective heuristic ↵

Note that this heuristic is only applied at the end of the MIP root, and only when no other root heuristic finds a feasible solution.

Default:

`0`