# The seven example workflows

> A walkthrough of the seven published Qsolve example workflows: what each solves, its inputs, outputs and parameters, and what to learn from reading its code.

Source: https://qsolve.omlabs.co/docs/build/examples
Updated: 2026-11-12

The `examples` repository holds seven complete, self-contained workflows. Copy the closest one and change it. Start with `max-cut`, then `generic-qubo`.

| Workflow | Family | Solves | Envelope |
|---|---|---|---|
| `max-cut` | `qubo_optimization` | Split a weighted graph into two groups | 24 nodes |
| `generic-qubo` | `qubo_optimization` | Minimise any QUBO, optionally with exactly k ones | 24 variables |
| `portfolio-optimization` | `qubo_optimization` | Pick k assets, trading return against risk | 24 assets |
| `molecular-ground-state` | `electronic_structure` | Ground-state energy of a closed-shell molecule or ion | 12 qubits |
| `interaction-energy` | `electronic_structure` | A signed sum of system energies: binding, solvation, reaction | 6 systems of 12 qubits |
| `electrolyte-solvent-screen` | `electronic_structure` | Rank battery-electrolyte solvents by Li+ binding | 8 solvents |
| `quantum-kernel-classifier` | `quantum_ml` | Binary classification with a quantum-kernel SVM | 8 features, 60 training points |

Every folder holds `README.md`, `qsolve.yaml`, `src/workflow.py` with the algorithm in small modules beside it, `benchmarks/cases.yaml` and `tests/`. Run any of them with `qsolve test <folder>` or `qsolve run <folder> -i <folder>/examples/<file>.json`. The chemistry workflows need PySCF (Linux, macOS or WSL).

## max-cut

Splits a weighted graph into two groups so the edges between the groups weigh as much as possible.

- **Input:** `nodes`, a list of names, and `edges` as `[u, v]` or `[u, v, weight]`. Duplicate edges and self-loops are rejected in `__init__`.
- **Output:** the two groups, the cut weight and the total edge weight.
- **Parameters:** `layers`, `shots`, `train_shots`, `optimizer_iters`, `train_on` (`sim` or `backend`).
- **Methods:** QAOA (quantum); exhaustive search, switching to annealing above 22 variables (reference); simulated annealing (classical).
- **Cases:** six, including a complete graph where low-depth QAOA struggles and a `fake:fez@1.6` case with `min_fidelity: 0.97`.

An edge of weight w is cut when `x_i + x_j - 2 x_i x_j = 1`, so the workflow builds a QUBO and minimises it; `evaluate` returns the negative cut weight and `answer` turns it back. Angles are trained noise-free on a statevector, and only the final circuit goes to the target.

Learn from it: `estimate()` built from a plan of circuits and shots, so the quote matches the run; the quantum method capping itself at two layers on noise-model and hardware targets; one `ctx.report_mitigation` call declaring readout correction.

## generic-qubo

Minimises `x'Qx + offset` over binary variables for any square matrix, with an optional "exactly k ones" constraint.

- **Input:** `Q` (up to 24 by 24), optional `labels`, `offset` and `cardinality`.
- **Output:** the assignment, the variables set to 1 and the objective value.
- **Parameters:** the same five as `max-cut`.
- **Cases:** six, with and without the cardinality constraint, up to 18 variables.

With `cardinality`, the circuit starts in the uniform superposition of every state with k ones (a Dicke state) and mixes with an XY ring, so every sample is valid and no penalty term is needed.

Learn from it: optional schema fields, with `x-ui: {"advanced": true}` on `offset`, and a constraint handled in the circuit.

## portfolio-optimization

Chooses exactly k assets from up to 24, trading expected return against risk: `risk_aversion * x'Cx - mu'x` with exactly k ones.

- **Input:** `assets`, `num_to_select`, `risk_aversion` and either `expected_returns` with `covariance`, or `returns_history`. The bundled real-data example holds statistics of 12 US industry portfolios from 2015 to 2024.
- **Output:** selected assets, equal weights, expected return, risk and whether the constraint holds.
- **Parameters:** `layers`, `shots`, `train_shots`, `optimizer_iters`, `constraint_mode` (`mixer` or `penalty`), `penalty_scale`, `init` (`dicke` or `product`), `train_on`.
- **Cases:** nine, including real data, penalty mode and a noise-model case on 5 assets.

Learn from it: a top-level `anyOf` in the input schema for two ways to describe one problem; `x-ui.format: percent` in the output schema; enum parameters that switch the method (`mixer` keeps every sample valid, `penalty` post-selects); and tolerances that grow honestly with problem size, `max_gap: 0.0` at 10 assets and 0.10 at 14.

## molecular-ground-state

Ground-state energy of a closed-shell molecule or ion with VQE in a chosen active space, reported beside the exact active-space energy, Hartree-Fock, MP2 and full-space CCSD(T).

- **Input:** a built-in `name` (H2, LiH, HF, N2, CO, BeH2, H2O, NH3, CH4, Li+, Na+), or `xyz` text or `atoms`; `charge`; `basis`; and an optional `active_space` of up to 6 orbitals.
- **Output:** the energy in Hartree, kcal/mol, kJ/mol and eV with its error bar, the error against the exact reference, the share of correlation energy recovered, and whether chemical accuracy (1.6 mHa) is met.
- **Parameters:** `ansatz` (`uccsd` or `hea`), `shots`, `optimizer_iters`.
- **Methods:** VQE (quantum); exact active-space solution, CASCI (reference); Hartree-Fock, MP2 and CCSD(T) (classical).
- **Metric:** `relative_error` with `tolerance_abs: 0.0016`.
- **Cases:** five, including a custom NH3 geometry and a noise-model case with `min_fidelity: 0.99`.

The trial state is trained noise-free, then the energy is measured in groups of commuting Pauli terms, one circuit per group, in one batch. On noise-model and hardware targets the workflow uses a compact circuit, mitigates the counts with readout correction, electron-count post-selection and zero-noise extrapolation, and reports them with `report_mitigation`.

Learn from it: `Outcome(solution=None, ...)` for measured and library energies, labelled reported; `MethodUnavailable` when CCSD(T) was not computed; a tolerance in the objective's own units; one batched `ctx.sampler.run` for many measurement circuits.

## interaction-energy

A binding, solvation, adsorption or reaction energy as a signed sum of system energies, each from VQE.

- **Input:** `systems`, named species each given as a built-in `name` or `xyz` with a `charge`; `basis`; an `active_space`; and optional `terms`, a coefficient per system. Without `terms` the first system counts `+1` and the others `-1`, a binding energy.
- **Output:** the combined energy with error bars, per-system energies and the Hartree-Fock, exact and CCSD(T) references.
- **Parameters:** `ansatz`, `shots`, `optimizer_iters`.
- **Cases:** four, including Li+ binding to water and to ammonia, and the energy cost of stretching H2.

Error bars of the combined energy add in quadrature, so a small interaction energy needs more shots than a total energy.

Learn from it: one workflow serving many chemistries through its input; mitigation reported once per measured circuit, with a `steps` ladder only when a single system is computed.

## electrolyte-solvent-screen

Ranks candidate battery-electrolyte solvents by how strongly each binds a Li+ ion, with each binding energy computed by VQE and checked against exact and MP2 references.

- **Input:** `solvents` from seven built-in molecules (EC, FEC, DMC, DME, THF, ACN, water), up to four `custom_solvents` with your own geometries of the molecule and its Li+ complex, `basis` and `active_space`.
- **Output:** a ranking with each binding energy split into mean-field and correlation parts, the strongest and weakest binder, whether the VQE ranking matches the exact one, and any neighbouring pair whose order is inside the error bars.
- **Parameters:** `shots`, `optimizer_iters`, `ansatz`.
- **Resources:** a 7200 second limit and 4096 MB, because it builds seven-system problems at 6-31G*.
- **Cases:** four, with tolerances of about three times the shot noise of the combined objective.

Learn from it: curated data shipped inside the repository (`src/geometries.json`), since runs have no network; an active space centred on the binding site and chosen identically in the complex and the free solvent, so no fake binding energy appears; results that say "unresolved" instead of ranking inside the noise.

## quantum-kernel-classifier

Binary classification with a quantum-kernel support vector machine, tuned by cross-validation and compared on a held-out test set against a tuned RBF-SVM, logistic regression, a random forest and gradient boosting.

- **Input:** a built-in `dataset` (`breast_cancer`, or synthetic moons, circles, xor and blobs), your own `data` table, or explicit `train` and `test` tables; `test_fraction`.
- **Output:** test accuracy with a 95% Wilson interval, the best classical accuracy, a paired McNemar test against the RBF-SVM, the confusion matrix, predictions and a check of the measured kernel against the exact one.
- **Parameters:** `reps`, `bandwidth` (both 0 for automatic tuning), `shots`, `kernel_mode` (`sampled` or `exact`).
- **Metric:** `error_rate`. The objective is the test error rate.
- **Cases:** five, with test sets of 200 or more points.

Every kernel entry is one circuit, and all circuits of a Gram matrix go through `ctx.sampler` in one call. Each method's solution is its list of predictions and `evaluate` scores them against the true labels, so no method can claim a better error rate than its predictions earn.

Learn from it: the `error_rate` metric, which needs `n_test` in the quantum outcome's `details`; mitigation by readout correction and a depolarizing rescale fitted on mirror circuits, reported for one representative circuit, with whole-matrix quality in the answer's `kernel_check`; `kernel_mode: exact`, which still sends eight spot-check circuits because the quantum method must use the backend.

See [Your first workflow](/docs/build/your-first-workflow) and [Writing the workflow](/docs/build/writing-the-workflow).
