Preprocessing
Reads your gurobipy model, separates binary \mathbf{x} from continuous \mathbf{y}, and extracts the matrices.
\mathbf{c},\mathbf{H},\mathbf{e} go to the MAP. \mathbf{d},\mathbf{A},\mathbf{G},\mathbf{b} go to the SUBs.
IEEE QCNC 2025 · Open-source Python package
v202610New: Benders dual decomposition cutsHybrid Quantum‑Classical Multi‑cuts Benders' Decomposition for (mixed‑)integer linear programs.
Give it a Gurobi model. HQC-Bend sends the binary master problem to a quantum or quantum-inspired annealer and the continuous subproblems to classical CPUs, then adds optimality and feasibility cuts until the bounds meet.
import gurobipy as gp
from HQCMCBD import HQCMCBD_algorithm
model = gp.Model("MILP")
# ... variables, constraints, objective ...
solver = HQCMCBD_algorithm(model, mode="default")
solver.run()
Two lines after your model: full hybrid quantum-classical automation.
01 · Motivation
Many planning and operations problems mix yes/no decisions (open a route, start a generator, switch on a chiller) with continuous quantities (flows, power, temperatures). That mix is a (mixed-)integer linear program, or (M)ILP.
(M)ILP is NP-hard: unless P = NP, no algorithm solves every instance in polynomial time.
The classical toolbox includes enumerative methods, branch and bound, and cutting planes. All of them run on CPUs.
02 · Quantum vs classical
Each processor is strong where the other is weak. HQC-Bend gives each one the part of the problem it is suited to.
| Advantages | Disadvantages | |
|---|---|---|
| CPU Central Processing Unit |
|
|
| QPU Quantum Processing Unit |
|
|
Superposition spans a vast space of candidate solutions at once.
The optimization problem is embedded into the quantum system's energy landscape.
The system settles into low-energy states, which are read back as classical solutions.
The master problem is purely binary, which is the form annealers natively solve (QUBO).
The subproblems are continuous linear programs, which classical solvers handle fast and in parallel.
03 · How it works
HQC-Bend decomposes the target model into a binary master problem (MAP) and continuous subproblems (SUB), then iterates between them.
Reads your gurobipy model, separates binary \mathbf{x} from continuous \mathbf{y}, and extracts the matrices.
\mathbf{c},\mathbf{H},\mathbf{e} go to the MAP. \mathbf{d},\mathbf{A},\mathbf{G},\mathbf{b} go to the SUBs.
Solved on a CPU (Gurobi) or a QPU (D-Wave CQM/BQM) or by a local quantum-inspired sampler. It returns one or more binary candidates \mathbf{x}^{*}.
A threshold check on the λ bounds decides whether to stop.
For each candidate, the subproblems run on CPUs 1…N with the normal, L-shaped or Benders dual scheme and return optimality or feasibility cuts to the MAP.
The loop repeats until the gap closes or max_steps is reached.
gurobipy model. Runs as a script or in Jupyter Notebook.04 · Master-problem solvers
The master problem is binary because λ is discretized into bits (see Configure). Each quantum mode encodes the objective and constraints as a QUBO, with each constraint added as a penalty term:
Here P_c is the penalty coefficient of constraint c and g(\cdot) is its encoded penalty.
Hybrid_mode: falseClassical baseline. The MAP is solved exactly with Gurobi, one cut per iteration.
"cqm"D-Wave Leap hybrid CQM solver. Constraints are passed natively instead of as penalties.
"bqm_hybrid"D-Wave Leap hybrid sampler. Classical and quantum modules work together for balanced performance.
"bqm_quantum"Pure quantum annealing on a D-Wave QPU through an embedding composite.
"openjij"Quantum-inspired annealing on your own machine. No cloud token needed.
"bifurcation"Quantum-inspired Ising solver built on PyTorch, run by HQC-Bend on an NVIDIA GPU. GPU install guide
The hybrid modes run on D-Wave's Hybrid Solver Service, which pairs a Classical Heuristic module (CH) with a Quantum Module (QM) in several parallel threads. Together they return one or more high-quality candidate solutions. HQC-Bend can turn each candidate into its own cut (multi-cuts).
Scheme after Osaba, Villar-Rodríguez, Gomez-Tejedor and Oregi, “Hybrid quantum solvers in production: how to succeed in the NISQ era?”, IDEAL 2024, pp. 423–434.
05 · Cut-adding schemes
Given a binary candidate \mathbf{x}^{*} from the MAP, the subproblem produces a dual solution \mathbf{w}^{*}, which becomes one of two cuts:
Benders dual decomposition (Rahmaniani et al., Operations Research, 2020) gives the subproblem binary copies \mathbf{z} of the master variables and prices the copy constraint \mathbf{z} = \mathbf{x} into the objective with multipliers \boldsymbol{\pi}.
F(\boldsymbol{\beta}) is the same problem with a penalized slack \mathbf{s} on every row and objective \mathbf{1}^{\intercal}\mathbf{s} - \boldsymbol{\beta}^{\intercal}\mathbf{z}. With \boldsymbol{\pi} fixed to the LP multipliers the cut keeps the classical slope and gets a higher right-hand side (strengthened cut); optimizing \boldsymbol{\pi} gives a Lagrangian cut.
At a binary master point these cuts equal the classical ones, so BDD runs at the LP root before the first master solve and the main loop then adds L-shaped cuts. The subproblem MILPs also return feasible solutions; the best one is saved as an incumbent in data_output/bdd_info.json.
A quantum sampler returns a whole distribution of low-energy binary states, not just one. With Mcut_flag: true, HQC-Bend takes the best Cutnums candidates, solves their subproblems in parallel on CPUs, and adds one cut per candidate in a single iteration. More cuts per round tighten the bounds on λ faster.
Each cut is a plane that bounds λ from below. Rounds continue until the upper and lower bounds of λ are within threshold.gap.
06 · Configuration
A JSON file controls the solver backend, the cut scheme, the precision of λ and the stopping rule. mode="manual" reads config.json and mode="default" reads config_default.json. Users can change the mathematical method even with little background in the field.
Save it as config.json next to HQCMCBD.py and run with mode="manual".
| Keyword | Meaning | Values |
|---|---|---|
lambda_var | Connection variable λ between the MAP and the SUBs, written as \lambda = \lambda_{+}^{\mathbb{Z}} + \lambda_{+}^{\mathbb{Q}\setminus\mathbb{Z}} - \lambda_{-}^{\mathbb{Z}} | object |
nonneg_bits_length | Bits for the non-negative integer part \lambda_{+}^{\mathbb{Z}} | positive integer |
decimal_bits_length | Bits for the positive fractional part \lambda_{+}^{\mathbb{Q}\setminus\mathbb{Z}} | positive integer |
negative_bits_length | Bits for the negative integer part \lambda_{-}^{\mathbb{Z}} | positive integer |
submethod | Method for solving the subproblems | normal, l_shape, bdd |
bdd.root_iterations | Maximum LP iterations of the BDD root phase; 0 behaves like l_shape | non-negative integer |
bdd.lagrangian_iterations | Maximum multiplier updates per Lagrangian cut; 0 stops after strengthened cuts | non-negative integer |
bdd.mip_gap | Gurobi MIPGap for the BDD subproblems | non-negative number |
bdd.time_limit | Gurobi time limit in seconds for each BDD subproblem | positive number or null |
debug_mode | Export LP files of the master problem and subproblems | true, false |
Hybrid_mode | Solve the master problem with a quantum or quantum-inspired backend (Q+C) instead of Gurobi (C+C) | true, false |
dwave.mode | How the MAP is encoded for the quantum solver | cqm, bqm_hybrid, bqm_quantum, openjij, bifurcation |
dwave.DWave_token | D-Wave Leap API token. Placeholder values fall back to the DWAVE_API_TOKEN environment variable | string |
dwave.Mcut_flag | Add multiple cuts per iteration (otherwise one) | true, false |
dwave.Cutnums | Number of cuts per iteration when Mcut_flag is true | positive integer |
dwave.num_of_read | Number of samples to read from the quantum solver | positive integer |
threshold.type | Which gap the stopping rule checks: absolute |\bar\lambda - \underline\lambda| or relative 100\cdot|\bar\lambda - \underline\lambda| / |\bar\lambda| (in percent) | absolute, relative |
threshold.gap | The run stops once the chosen gap drops below this value ε | positive number |
max_steps | The algorithm stops after this many iterations | positive integer |
07 · Quick start
Requires Python 3.8+ and Gurobi 9.1.2+ with a valid license. HQCMCBD.py imports every backend when it loads, so install all of them even if you plan to use one mode.
git clone https://github.com/djzts/HQCMCBD-API.git
cd HQCMCBD-API
pip install gurobipy numpy dimod dwave-system openjij torch simulated-bifurcationFor the D-Wave modes (cqm, bqm_hybrid, bqm_quantum), set DWAVE_API_TOKEN in your environment rather than committing a token to the config file.
"bifurcation")The bifurcation backend calls simulated_bifurcation.minimize(..., device="cuda"), so it needs an NVIDIA GPU whose driver supports CUDA 11.8. The GPU_acced_Q installation guide covers the setup step by step: Python 3.10 (a conda environment is recommended), PyTorch 2.6.0 built for CUDA 11.8, and simulated-bifurcation 1.2.0. In short, run these after the install command above so the GPU build of PyTorch is not replaced:
pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu118
pip install simulated-bifurcation==1.2.0
python -c "import torch, simulated_bifurcation as sb; print(torch.__version__, torch.cuda.is_available())"The last command should print 2.6.0+cu118 True. PyTorch's cu118 wheels include the CUDA runtime, so no separate CUDA Toolkit is needed. If it prints False, see the guide's troubleshooting section.
from HQCMCBD import HQCMCBD_algorithmimport warnings
warnings.filterwarnings("ignore")
%run HQCMCBD_notebook.ipynbAny gurobipy model with binary variables and non-negative continuous variables works. This is the example problem from the package (Example.ipynb).
import gurobipy as gp
from gurobipy import GRB
import numpy as np
A = np.array([[0, 0], [0, 0], [0, 0], [0, 0],
[-1, -1], [-1, 0], [-1, 0], [0, -1], [0, -1]])
G = np.array([[1, 0, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 0, 1],
[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])
b = np.array([1, 1, 1, 1, -1, 0, 0, 0, 0])
c = np.hstack(np.array([-15.0, -10.0]))
h = np.hstack(np.array([8, 9, 5, 6]))
# Create a new Gurobi model
model = gp.Model("MILP")
# Add variables
x = model.addMVar(shape=len(c), vtype=GRB.BINARY, name="x")
y = model.addMVar(shape=len(h), vtype=GRB.CONTINUOUS, lb=0, name="y")
z = model.addVar(vtype=GRB.CONTINUOUS, lb=0, name="z")
p = model.addVar(vtype=GRB.BINARY, name="p")
# Objective and constraints
model.setObjective(c @ x + h @ y, GRB.MAXIMIZE)
model.addConstr(A @ x + G @ y <= b, name="constraints")
model.addConstr(z == 1, name="constraints_eq")
model.addConstr(p == 1, name="constraints_eq2")
model.optimize()Maximization models are converted to minimization internally and reported back in the original sign convention.
solver = HQCMCBD_algorithm(model, mode="manual")
solver.run()solver = HQCMCBD_algorithm(model, mode="default")
solver.run()Each round prints the objective value, the λ bounds, and the relative and absolute gaps. The run stops when the gap meets the threshold.
Benders decomposition Round - 2
The 2-th Config file of quantum sampling is created successfully at .\data_output\Gurobi_info-round-2.json.
create optimality cut
Round 2:
Current Objective value is 12.0;
lambda_upper is 20.0;
lambda_lower is 11.0;
Relative gap is 81.818%.
Absolute gap is 9.0
Benders decomposition Round - 3
create optimality cut
Round 3:
Current Objective value is 6.0;
lambda_upper is 19.0;
lambda_lower is 17.0;
Relative gap is 11.765%.
Absolute gap is 2.0
Benders decomposition Round - 4
create optimality cut
Round 4:
Current Objective value is 5.0;
lambda_upper is 17.0;
lambda_lower is 17.0;
Relative gap is 0.0%.
Absolute gap is 0.0
optimal found, it takes 4 Rounds.data_output/Objective values, λ bounds, solver metadata and MAP solutions for every round.LP_output/Gurobi LP exports of the MAP and subproblems when debug_mode is on.LP_output_dwave/Artifacts from the quantum and quantum-inspired solvers.08 · Results
Both plots track the lower and upper bounds of the connection variable λ and the objective value at each iteration.
HQC-Bend is a Python package that solves complex (M)ILP problems with the HQC-Bend algorithm. It uses quantum computing for the optimization tasks it suits and classical solvers for the rest, giving an efficient and robust way to handle (M)ILP problems.
09 · Application
The companion repository djzts/HQCMBD contains a data center model built for HQC-Bend. It is a natural fit: on/off decisions are binary and go to the quantum master problem, while power flows and temperatures are continuous and go to the CPU subproblems.
Minimize the cost of electricity drawn from the grid:
Grid demand is HVAC load plus server load plus battery charging, minus solar production. The schedule must respect battery limits, zone thermal dynamics with heat exchange between neighboring zones, ventilation requirements and chiller and cooling-tower capacity.
10 · Research using HQC-Bend
The same idea (a binary master problem solved on quantum hardware, with classical solvers handling the continuous subproblems) has been applied in peer-reviewed work on satellite and space networks, federated learning and energy systems.
IEEE Transactions on Power Systems, vol. 40, no. 5, pp. 3967–3978, 2025
Co-schedules hydrogen and power distribution systems, including the routes and loading of truck-mounted mobile hydrogen storage. The master problem runs as a QUBO on a quantum annealer and the subproblems on a classical CPU.
IEEE Transactions on Mobile Computing, 2024
Minimizes service delay for IoT devices served by LEO satellites, high-altitude platforms and ground base stations. A Lyapunov-based online controller splits the stochastic problem into per-slot problems that are solved with quantum assistance.
IEEE Transactions on Mobile Computing, vol. 24, no. 2, pp. 830–844, 2025 (online 2024)
Jointly optimizes user association, virtual network function placement and flow routing. The resulting MILP is solved with hybrid quantum-classical Benders’ decomposition, with the master problem converted to a QUBO.
IEEE Transactions on Network Science and Engineering, vol. 11, no. 6, pp. 6038–6051, 2024
Schedules several federated learning models at once, choosing participants and learning rates. The joint problem is an NP-hard MINLP, which hybrid quantum-classical Benders’ decomposition solves.
IEEE Transactions on Network Science and Engineering, vol. 11, no. 6, pp. 5163–5174, 2024
Maximizes throughput by jointly optimizing content delivery, cache placement and transmit power. The large-scale MINLP is solved with a hybrid quantum-classical generalized Benders’ decomposition.
32nd International Conference on Computer Communications and Networks (ICCCN), IEEE, pp. 1–10, 2023
The first application of the method: multi-model federated learning scheduling, split into a binary master problem and small continuous subproblems that combine quantum and classical computing.
Using HQC-Bend in your research? Let us know and we will add your paper here.
11 · Citation
If you use HQC-Bend in your work, please cite the QCNC 2025 paper:
@inproceedings{zhao2025hqc,
title={HQC-Bend: A Python Package of Hybrid Quantum-Classical Multi-cuts Benders' Decomposition Algorithm},
author={Zhao, Zhongqi and Li, Mingze and Fan, Lei and Han, Zhu},
booktitle={2025 International Conference on Quantum Communications, Networking, and Computing (QCNC)},
pages={591--597},
year={2025},
organization={IEEE},
url={https://github.com/djzts/HQCMCBD-API}
}Zhongqi Zhao · zzhao27@uh.edu
Mingze Li · mli44@central.uh.edu