Skip to main content

CVXPY x GUROBI

This small library provides an alternative way to solve CVXPY problems with Gurobi.

Usage

The library provides a solver that will translate a CVXPY Problem into a gurobipy.Model, and optimize using Gurobi:

import cvxpy as cp
import cvxpy_gurobi

problem = cp.Problem(cp.Maximize(cp.Variable(name="x", nonpos=True)))
cvxpy_gurobi.solve(problem)
assert problem.value == 0

The solver can also be registered with CVXPY and used as any other solver:

import cvxpy as cp
from cvxpy_gurobi import GUROBI_TRANSLATION, solver

cvxpy_gurobi.register_solver()
# ^ this is the same as:
cp.Problem.register_solve_method(GUROBI_TRANSLATION, solver())

problem.solve(method=GUROBI_TRANSLATION)

This solver is a simple wrapper for the most common use case:

from cvxpy_gurobi import build_model, backfill_problem

model = build_model(problem)
model.optimize()
backfill_problem(problem, model)
assert model.optVal == problem.value

The build_model function provided by this library translates the cvxpy.Problem instance into an equivalent gurobipy.Model, and backfill_problem sets the optimal values on the original problem.

[!NOTE] Both functions must be used together as they rely on naming conventions to map variables and constraints between CVXPY and Gurobi.

The output of the build_model function is a standard gurobipy.Model instance, which can be further customized prior to solving. This approach enables you to manage how the model will be optimized.

Installation

pip install cvxpy-gurobi

CVXPY has an interface to Gurobi, why is this needed?

When using CVXPY's interface to Gurobi, the problems fed to Gurobi have been pre-compiled by CVXPY, meaning the model is not exactly the same as the one you have written. This is great for solvers with low-level APIs, such as SCS or OSQP, but gurobipy allows you to express your models at a higher-level.

Providing the raw model to Gurobi can be a better idea in general to let the Gurobi solver use its own heuristics. The chosen algorithm can be different depending on the way it is modelled, potentially leading to better performance.

In addition, CVXPY does not give access to the model before solving it. CVXPY must therefore make some choices for you, such as setting QCPDual to 1 on all non-MIP models. Having access to the model can help if you want to handle the call to .optimize() in a non-standard way, e.g. by sending it to an async loop.

Another feature is the ability to use the latest features of Gurobi, such as non-linear expressions, which are not yet supported by the Gurobi interface in CVXPY.

Example

Consider this QP problem:

import cvxpy as cp

x = cp.Variable(name="x")
problem = cp.Problem(cp.Minimize((x-1) ** 2))

The problem will be sent to Gurobi as (in LP format):

Minimize
 [ 2 C0 ^2 ] / 2
Subject To
 R0: - C0 + C1 = 1
Bounds
 C0 free
 C1 free
End

Using this package, it will instead send:

Minimize
  - 2 x + Constant + [ 2 x ^2 ] / 2
Subject To
Bounds
 x free
 Constant = 1
End

Note that:

  • the variable's name matches the user-defined problem;
  • no extra (free) variables;
  • no extra constraints.

Why not use gurobipy directly?

CVXPY has 2 main features: a modelling API and interfaces to many solvers. The modelling API has a great design, whereas gurobipy feels like a thin layer over the C API. The interfaces to other solvers can be useful to not have to rewrite the problem when switching solvers.

Supported versions

All supported versions of Python, CVXPY and gurobipy should work. However, due to licensing restrictions, old versions of gurobipy cannot be tested in CI. If you run into a bug, please open an issue in this repo specifying the versions used.

Contributing

Hatch is used for development. It will handle all virtual environment management.

To lint the code, run:

ruff check

To format the code, run:

ruff format

For testing, run:

hatch run latest:tests

This will test the latest version of dependencies. You can also run hatch run oldest:tests to test the minimum required dependency versions.

Make sure any change is tested through a snapshot test. To add a new test case, build a simple CVXPY problem in tests/test_problems.py in the appropriate category, then run:

hatch run update-snapshots

You can then check the output in the tests/snapshots folder is as expected.

Metadata

Release files for cvxpy-gurobi 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cvxpy-gurobi 1.2.0
File Size Uploaded
cvxpy_gurobi-1.2.0.tar.gz 45.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cvxpy-gurobi 1.2.0
File Interpreter ABI Platform
cvxpy_gurobi-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 62.2 kB

Release files / cvxpy_gurobi-1.2.0.tar.gz

Download URL cvxpy_gurobi-1.2.0.tar.gz
Size 45.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a6f229f34f159ca605853af2b820d9258b6b87c05ada234f43e7c81297bceb8c
BLAKE2b-256 checksum
How to use checksums
0e868408b320d67ccafc1ac3d2303dfa0fcc858bf25d1c900684217d7e1c6d9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 23, 2025.

Transparency log

Release files / cvxpy_gurobi-1.2.0-py3-none-any.whl

Download URL cvxpy_gurobi-1.2.0-py3-none-any.whl
Size 16.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5406ed550dd244ef274749616e4c6903c67b1b5e9227e40b2ccace5edbf11511
BLAKE2b-256 checksum
How to use checksums
d930d7f073f5ac31b780d6c9d4999c307d3204e763e783a52845091fb6495a7a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 23, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page