# Solution File Formats#

## SOL format#

A Gurobi solution (SOL) file is used to output a solution vector. It can
be written (using `GRBwrite`

, for example) whenever a solution
is available.

The file consists of variable-value pairs, each on its own line. The file contains one line for each variable in the model. The following is a simple example:

```
# Solution file
x 1.0
y 0.5
z 0.2
```

## JSON solution format#

JSON (or JavaScript Object Notation) is a lightweight, text-based, language-independent data interchange format. It was derived from JavaScript, but many modern programming languages include code to generate and parse JSON-format data.

Gurobi JSON solution format is meant to be a simple and standard way to capture and share optimization results. It conforms to the RFC-8259 standard. JSON solutions can be written to a file or captured in a string.

The JSON solution captures the values of various Gurobi attributes associated with the solution to the model. Some are related to the model overall, some to individual variables, and some to individual constraints. The exact contents of a JSON solution string will depend on a few factors:

The type of model being solved (linear, quadratic, mixed-integer, multi-objective, etc.). Some solution information is simply not available for certain problem types (e.g., dual variable values for MIP models).

The set of tagged elements in the model. By default the JSON solution will contain only model attributes and variable data. Users can tag variables (using the VTag attribute), linear constraints (using the CTag attribute), and quadratic constraints (using the QCTag attribute) to request data on a more selective basis. If any such attribute is used, only tagged elements will have solution information in the JSON solution.

The JSONSolDetail parameter, which controls how much detail is included in the JSON solution.

Parameter settings such as InfUnbdInfo or QCPDual, which cause the optimization process to generate more solution information.

JSON solutions aren’t generally meant to be interpreted directly by humans. Instead, you typically feed them into a JSON parser, which provides tools for extracting the desired information from the string. JSON is a widely-used format, and nearly all modern program languages have libraries available for helping to parse JSON strings and files. And if you are determined to examine the string directly, JSON parsers typically also include pretty-printing utilities that make it easier to do so.

### Basic Structure#

A JSON solution string consists of a collection of named components. In its simplest form, it might look like the following:

```
{ "SolutionInfo": { "Status": 3,
"Runtime": 3.4289908409118652e-01,
"BoundVio": 0,
"ConstrVio": 0,
"IterCount": 0,
"BarIterCount": 0}}
```

A JSON parser makes it relatively easy to extract the various components
from this string. In Python, for example, you would be able to retrieve
the optimization status by accessing
`result['SolutionInfo']['Status']`

after parsing.

Before discussing the specific information that is available in this format, let us first say a word about how data is represented. The type of each data item follows from the attribute type. For example, Status is an integer attribute, so the corresponding value is stored as an integer. Runtime is a double attribute, which is represented as a string, and that string always captures the exact, double-precision (IEEE754) value of the attribute.

### Named Components#

A JSON solution will always have at least one named object:
`SolutionInfo`

. It may contain up to three optional named arrays:
`Vars, Constrs, QConstrs`

. A JSON solution string may look like:

```
{ "SolutionInfo": {...},
"Vars": [...],
"Constrs": [...],
"QConstrs": [...]}
```

The exact contents of the three optional sections will depend on what
model components have been tagged and on what solution information is
available. If no element is tagged, for example, then the `Vars`

array
will be present and contain names and solution values for all variables
with non-zero solution values. For a MIP model, the `Constrs`

array
will not be present, since MIP solutions don’t contain any constraint
information.

### SolutionInfo Object#

The `SolutionInfo`

object contains high-level information about the
solution that was computed for this model. Some entries will always be
present, while others depend on the problem type or the results of the
optimization. This component may include the following model attributes:

- Status (always present)
The optimization status (optimal, infeasible, hit the time limit, etc.).

- Runtime (always present)
Runtime for the optimization (in seconds).

- ObjVal
The solution objective value.

- ObjBound
The best known bound on the objective value.

- ObjBoundC
The best known bound on the objective value (before using integrality information to strengthen the bound).

- MIPGap
The optimality gap.

- IntVio
The maximum integrality violation.

- BoundVio
The maximum bound violation.

- ConstrVio
The maximum constraint violation.

- ObjNVal (multi-objective only)
An array of objective values, one for each objective.

- ScenNObjVal (multi-scenario only)
An array of objective values, one for each scenario.

- ScenNObjBound (multi-scenario only)
An array of objective bounds, one for each scenario.

- IterCount
Number of simplex iterations.

- BarIterCount
Number of barrier iterations.

- NodeCount
Number of branch-and-cut nodes explored for MIP models.

- FarkasProof
Part of the infeasibility certificate for infeasible models. Note that you have to set the InfUnbdInfo parameter before the optimization call for this information to be available.

- SolCount
Number of stored solutions (only for MIP models).

- PoolObjBound
Bound on the objective of undiscovered MIP solutions.

- PoolObjVal
Only for MIP models with at least one solution. For single-objective models, this is an array containing the objective value for each stored solution (starting with the incumbent). For multi-objective models, this is an array containing SolCount arrays of values, each array contains the objective value for each multi-objective for the particular solution.

Here’s an example of a `SolutionInfo`

object for a MIP model:

```
{ "SolutionInfo": { "Status": 2,
"Runtime": 5.8451418876647949e+00,
"ObjVal": 3089,
"ObjBound": 3089,
"ObjBoundC": 3089,
"MIPGap": 0,
"IntVio": 0,
"BoundVio": 0,
"ConstrVio": 0,
"IterCount": 32,
"BarIterCount": 0,
"NodeCount": 1,
"SolCount": 1,
"PoolObjBound": 3089,
"PoolObjVal": [ 3089]}}
```

### Vars Array#

The `Vars`

component is an array (possibly empty) of objects
containing information about variables. If no explicit tags (VTag, CTag,
or QCTag) have been set at all, all variables with a non-zero objective
value will be included, along with their names. Otherwise only variables
wih a set VTag will be included, and this tag will be part of the
object. Some data will always be present, while other data will depend
on the problem type or the results of the optimization. This component
may include the following variable attributes:

- VarName
The variable’s name in the model. Present only if no tags have been set.

- VTag
Array containing the variable tag. Note that this is stored as an array, but the array will currently only ever contain a single string.

- X (always present)
Value for the variable corresponding to the VarName or VTag in the current solution. Note objects with a zero variable value will be omitted from the Vars array unless JSONSolDetail is greater than zero.

- Xn
Values for all stored solutions including the incumbent solution (only for MIP).

- ScenNX
For multiple scenarios, values for all scenario solutions.

- RC
For continuous models with dual information, the reduced cost for the variable.

- VBasis
For continuous models whose solution is basic, the basis status for the variable.

- UnbdRay
For unbounded models with InfUnbdInfo enabled, the unbounded ray component associated with the variable.

The following attributes are only included if
JSONSolDetail is greater than 0: `RC`

, `UnbdRay`

,
`VBasis`

, `Xn`

.

These objects may look like:

```
{ "VTag": ["VTag7"], "X": 1}
{ "VTag": ["VTag12"], "X": 3.6444895037909271e-02, "RC": 0}
{ "VTag": ["VTag2747"],
"X": 0,
"Xn": [ 0, 1, 1, 1, 0, 1, 1, 0, 0, 0]}
```

### Constrs Array#

The `Constrs`

component is an array (possibly empty) of objects
containing information about tagged linear constraints. Some entries
will always be present, while others depend on the problem type or the
results of the optimization. This component may include the following
constraint attributes:

- CTag (always present)
Array containing the linear constraint tag. Note that this is stored as an array, but the array will currently only ever contain a single string.

- Slack (always present)
Value for the slack variable in the current solution.

- Pi
For continuous models with dual information, the dual value for the corresponding constraint.

- FarkasDual
For infeasible models with InfUnbdInfo enabled, the Farkas dual component associated with the constraint. This component will always be empty for MIP models.

The following attributes are only included if
JSONSolDetail is greater than 0: `CBasis`

,
`FarkasDual`

, `Pi`

, `Slack`

.

These objects may look like:

```
{ "CTag": ["CTag72"],
"Slack": -1.3877787807814457e-17,
"Pi": -5.6530866311690423e-02}
```

### QConstrs Array#

The `QConstrs`

component is an array (possibly empty) of objects
containing information about tagged quadratic constraints. Some entries
will always be present, while others depend on the problem type or the
results of the optimization. This component may include the following
quadratic constraint attributes:

- QCTag (always present)
Array containing the quadratic constraint tag. Note that this is stored as an array, but the array will currently only ever contain a single string.

- QCSlack (always present)
Value for the slack variable in the current solution.

- QCPi
For continuous models with dual information, the dual value for the corresponding constraint. This component will always be empty for MIP models.

The following attributes are only included if
JSONSolDetail is greater than 0: `QCPi`

, `QCSlack`

.

### JSON Solution Examples#

For a continuous model, the JSON solution string may look like

```
{ "SolutionInfo": {
"Status": 2,
"Runtime": 9.9294495582580566e-01,
"ObjVal": 5.2045497375374854e-07,
"BoundVio": 0,
"ConstrVio": 1.002e-07,
"IterCount": 0,
"BarIterCount": 3},
"Vars": [
{"VTag": ["VTag7"], "X": -3.0187172916263982e-09, "RC": 0},
{"VTag": ["VTag1340"], "X": -3.0696132844593768e-09, "RC": 0},
{"VTag": ["VTag2673"], "X": -4.8134359014615295e-09, "RC": 0},
{"VTag": ["VTag4006"], "X": -7.1652420015125937e-02, "RC": 0},
{"VTag": ["VTag5339"], "X": -1.5815441619302997e-02, "RC": 0},
{"VTag": ["VTag6672"], "X": 1.4945278866946186e-02, "RC": 0}],
"Constrs": [
{"CTag": ["CTag7"], "Slack": 4.85722506e-17, "Pi": 2.3140310696e-06},
{"CTag": ["CTag673"], "Slack": 0, "Pi": -1.4475853138350041e-06},
{"CTag": ["CTag1339"], "Slack": -2.7758914e-17, "Pi": -3.7443785e-06},
{"CTag": ["CTag2005"], "Slack": 4.3420177e-18, "Pi": -1.0277524e-06},
{"CTag": ["CTag2671"], "Slack": -1.3895245e-17, "Pi": 8.0012944e-07},
{"CTag": ["CTag3337"], "Slack": 6.39465e-16, "Pi": -5.3368958e-06}]}
```

For a multi-objective LP, the JSON solution string may look like

```
{ "SolutionInfo": {
"Status": 2,
"Runtime": 2.2838807106018066e-01,
"ObjNVal": [ 10, 339],
"IterCount": 112,
"BarIterCount": 0,
"NodeCount": 0},
"Vars": [
{"VTag": ["VTag7"], "X": 0},
{"VTag": ["VTag569"], "X": 0},
{"VTag": ["VTag1131"], "X": 0},
{"VTag": ["VTag1693"], "X": 0},
{"VTag": ["VTag2255"], "X": 0},
{"VTag": ["VTag2817"], "X": 0},
{"VTag": ["VTag3379"], "X": 0},
{"VTag": ["VTag3941"], "X": 0},
{"VTag": ["VTag4503"], "X": 0},
{"VTag": ["VTag5065"], "X": 1},
{"VTag": ["VTag5627"], "X": 1},
{"VTag": ["VTag6189"], "X": 1}]}
```

For a regular MIP problem, the JSON solution string may look like

```
{ "SolutionInfo": {
"Status": 2,
"Runtime": 2.4669170379638672e-03,
"ObjVal": 3124,
"ObjBound": 3124,
"ObjBoundC": 3124,
"MIPGap": 0,
"IntVio": 1.958742e-08,
"BoundVio": 0,
"ConstrVio": 1.002e-07,
"IterCount": 465,
"BarIterCount": 0,
"NodeCount": 1,
"SolCount": 4,
"PoolObjBound": 3124,
"PoolObjVal": [ 3124, 3124, 3124, 3124]},
"Vars": [
{"VTag": ["VTag7"], "X": 1, "Xn": [ 1, 1, 1, 1]},
{"VTag": ["VTag466"], "X": 0, "Xn": [ 0, 1, 1, 0]},
{"VTag": ["VTag925"], "X": 0, "Xn": [ 0, 0, 0, 0]},
{"VTag": ["VTag1384"], "X": 0, "Xn": [ 0, 0, 1, 1]},
{"VTag": ["VTag1843"], "X": 0, "Xn": [ 0, 1, 0, 0]},
{"VTag": ["VTag2302"], "X": 0, "Xn": [ 0, 1, 1, 0]}]}
```

For a multi-objective MIP, the JSON solution string may look like

```
{ "SolutionInfo": {
"Status": 2,
"Runtime": 3.5403838157653809e+00,
"ObjNVal": [ 2763, 704],
"IterCount": 595,
"BarIterCount": 0,
"NodeCount": 1,
"SolCount": 6,
"PoolObjVal": [ [ 2763, 704 ], [ 2763, 705 ],
[ 2763, 716 ], [ 2763, 718 ],
[ 2763, 769 ], [ 2763, 1060 ]]},
"Vars": [
{"VTag": ["VTag7"], "X": 1, "Xn": [ 1, 1, 1, 1, 1, 1]},
{"VTag": ["VTag466"], "X": 0, "Xn": [ 0, 1, 0, 0, 0, 0]},
{"VTag": ["VTag925"], "X": 0, "Xn": [ 0, 0, 0, 0, 1, 1]},
{"VTag": ["VTag1384"], "X": 0, "Xn": [ 0, 0, 0, 0, 0, 0]},
{"VTag": ["VTag1843"], "X": 0, "Xn": [ 0, 0, 1, 1, 0, 0]},
{"VTag": ["VTag2302"], "X": 0, "Xn": [ 0, 1, 0, 0, 0, 0]}]}
```

For a multi-scenario model, the JSON solution string may look like

```
{ "SolutionInfo": {
"Status": 2,
"Runtime": 3.5403838157653809e+00,
"ObjVal": 2763,
"ObjBound": 2763,
"ObjBoundC": 1324,
"IntVio": 0,
"BoundVio": 0,
"ConstrVio": 0,
"ScenNObjVal": [2763, 3413, 1e+100],
"ScenNObjBound": [2763, 3413, 1e+100],
"IterCount": 595,
"BarIterCount": 0,
"NodeCount": 1,
"SolCount": 3,
"PoolObjBound": 2763,
"PoolObjVal": [ 2763, 2763, 2763]},
"Vars": [
{"VTag": ["VTag7"], "X": 1, "ScenNX": [1, 0, 1e+101], "Xn": [ 1, 0, 1]},
{"VTag": ["VTag466"], "X": 0, "ScenNX": [1, 1, 1e+101], "Xn": [ 1, 1, 1]},
{"VTag": ["VTag925"], "X": 0, "ScenNX": [0, 0, 1e+101], "Xn": [ 0, 0, 0]},
{"VTag": ["VTag1384"], "X": 0, "ScenNX": [2, 1, 1e+101], "Xn": [ 2, 1, 0]},
{"VTag": ["VTag1843"], "X": 0, "ScenNX": [0, 2, 1e+101], "Xn": [ 0, 2, 1]},
{"VTag": ["VTag2302"], "X": 0, "ScenNX": [0, 1, 1e+101], "Xn": [ 0, 1, 0]}]}
```

If the scenario objective value ScenNObjVal is infinite
(`GRB_INFINITY = 1e+100`

for minimization, `-GRB_INFINITY = -1e+100`

for maximization), then no feasible solution has been found for this
scenario. The corresponding ScenNX value for each variable
will be `GRB_UNDEFINED = 1e+101`

. Moreover, if the
ScenNObjBound value for the scenario is also infinite, it
means that the scenario has been proven to be infeasible.

## MST format#

A MIP start (MST) file is used to specify an initial solution for a
mixed integer programming model. The file lists values to assign to the
variables in the model. If a MIP start has been imported into a MIP
model before optimization begins (using `GRBread`

, for example),
the Gurobi optimizer will attempt to build a feasible solution from the
specified start values. A good initial solution often speeds the
solution of the MIP model, since it provides an early bound on the
optimal value, and also since the specified solution can be used to seed
the local search heuristics employed by the MIP solver.

A MIP start file consists of variable-value pairs, each on its own line. Any line that begins with the hash sign (#) is a comment line and is ignored. The following is a simple example:

```
# MIP start
x1 1
x2 0
x3 1
```

Importing a MIP start into a model is equivalent to setting the Start attribute for each listed variable to the associated value. If the same variable appears more than once in a start file, the last assignment is used. Importing multiple start files is equivalent to reading the concatenation of the imported files.

Note that start files don’t need to specify values for all variables. When variable values are left unspecified, the Gurobi solver will try to extend the specified values into a feasible solution for the full model.

It is important to mention that when saving an MST file, Gurobi will not save the values of continuous variables. If you want to save a complete description of the best solution found, we recommend to save it as a solution file (SOL format). This will guarantee that you will save the values for each variable present in your model.

## BAS format#

An LP basis (BAS) file is used to specify an initial basis for a
continuous model. The file provides basis status information for each
variable and constraint in the model. If written by Gurobi, to reduce
the size of the file, it only includes the difference to the slack
basis. In a slack basis for each row the corresponding slack variable is
basic while all other problem variables are at their lower bound. If a
basis has been imported into a continuous model before optimization
begins (using `GRBread`

, for example), and if a simplex
optimizer has been selected (through the Method
parameter), the Gurobi simplex optimizer begins from the specified
basis.

A BAS file begins with a `NAME`

line, and ends with an `ENDATA`

statement. No information is retrieved from these lines, but they are
required by the format. Between these two lines are basis status lines,
each consisting of two or three fields and starting with a white space
character. If the first field is `LL`

, `UL`

, or `BS`

, the variable
named (slack variables are not allowed) in the second field is non-basic
at its lower bound, non-basic at its upper bound, or basic,
respectively. Any additional fields are ignored. If the first field is
`XL`

or `XU`

, the variable named in the second field is basic, while
the row named in the third field states that the corresponding slack
variable is non-basic at its lower or upper bound, respectively.

The following is a simple example:

```
NAME example.bas
XL x1 c1
XU x2 c2
UL x3
LL x4
ENDATA
```

Importing a basis into a model is equivalent to setting the VBasis and CBasis attributes for each listed variable and constraint to the specified basis status.

A near-optimal basis can speed the solution of a difficult LP model. However, specifying a start basis that is not extremely close to an optimal solution will often slow down the solution process. Exercise caution when providing start bases.