Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

QUBO and Ising Models (Python)

Maintained by the JuliaQUBO organization
SECQUOIA  ·  PSR Energy

Open In Colab

Setup

Google Colab

Click the badge above to open this notebook in Colab. The notebook installs or activates dependencies in the setup cells below.

Local installation

Run the following from the repository root before opening this notebook locally:

python -m pip install dimod dwave-neal matplotlib networkx numpy pandas pyomo scipy

GLPK is used for the integer-programming comparison cells.

GLPK (required for ILP sections):

Learning objectives

By the end of this notebook you will be able to:

  1. Describe QUBO and Ising model forms and the role of linear, quadratic, and offset terms.

  2. Convert constrained binary optimization problems into QUBO models using penalty terms.

  3. Build Binary Quadratic Models with dimod and solve them with simulated annealing.

  4. Validate sampled solutions and connect QUBO penalties to graph-coloring feasibility.

Prerequisites

Mathematical background: Binary variables, matrix notation, quadratic objectives, and basic graph terminology.
Prior notebooks: Notebook 1 (MathProg) or equivalent experience with binary integer programming.
Accounts required: None; all examples use local Python packages.
Python version: Python 3.9+ with the D-Wave Ocean packages used by this repository.

Quadratic Unconstrained Binary Optimization

This notebook explains the basics of QUBO modeling. We use D-Wave’s dimod package to build QUBOs and neal to solve them with simulated annealing. We also use SymPy for the symbolic computation behind the Gröbner-basis examples and NetworkX to represent graph problems.

QUBO problem statement

We define a QUBO as the following optimization problem:

min⁡x∈{0,1}n∑(ij)∈E(G)Qijxixj+∑i∈V(G)Qiixi+cQ=min⁡x∈{0,1}nx⊤Qx+cQ\min_{x \in \{0,1 \}^n} \sum_{(ij) \in E(G)} Q_{ij}x_i x_j + \sum_{i \in V(G)}Q_{ii}x_i + c_Q = \min_{x \in \{0,1 \}^n} x^\top Q x + c_Q

where we optimize over binary variables x∈{0,1}nx \in \{ 0,1 \}^n, on a constrained graph G(V,E)G(V,E) defined by an adjacency matrix QQ. We also include an arbitrary offset cQc_Q.

QUBO example

Suppose we want to solve the following problem via QUBO $$ \min_{\mathbf{x}} 2𝑥_0+4𝑥_1+4𝑥_2+4𝑥_3+4𝑥_4+4𝑥_5+5𝑥_6+4𝑥_7+5𝑥_8+6𝑥_9+5𝑥_{10} \ s.t. \begin{bmatrix} 1 & 0 & 0 & 1 & 1 & 1 & 0 & 1 & 1 & 1 & 1\ 0 & 1 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 1 & 1\ 0 & 0 & 1 & 0 & 1 & 0 & 1 & 1 & 1 & 1 & 1 \end{bmatrix}\mathbf{x}=

[111]\begin{bmatrix} 1\\ 1\\ 1 \end{bmatrix}

\mathbf{x} \in {0,1 }^{11} $$

Notebook Cell

First we would write this problem as an unconstrained one by penalizing the linear constraints as quadratics in the objective. Let’s first define the problem parameters

In order to define the Q\mathbf{Q} matrix, we first write the problem

min⁡xc′xs.t.Ax=b x∈{0,1}11\begin{array}{rl} \displaystyle% \min_{\mathbf{x}} &\mathbf{c}' \mathbf{x} \\ \textrm{s.t.} & \mathbf{A}\mathbf{x} = \mathbf{b} \\ ~ & \mathbf{x} \in \{0,1 \}^{11} \end{array}

as follows:

min⁡xc′x+ρ(Ax−b)′(Ax−b)s.t.x∈{0,1}11\begin{array}{rl} \displaystyle% \min_{\mathbf{x}} & \mathbf{c}' \mathbf{x} + \rho (\mathbf{A}\mathbf{x}-\mathbf{b})' (\mathbf{A}\mathbf{x}-\mathbf{b}) \\ \textrm{s.t.} & \mathbf{x} \in \{0,1 \}^{11} \end{array}

Exploiting the fact that x2=xx^2=x for x∈{0,1}x \in \{0,1\}, we can make the linear terms appear in the diagonal of the Q\mathbf{Q} matrix.

ρ(Ax−b)′(Ax−b)=ρ(x′(A′A)x−2(A′b)x+b′b)\rho(\mathbf{A}\mathbf{x}-\mathbf{b})'(\mathbf{A}\mathbf{x}-\mathbf{b}) = \rho( \mathbf{x}'(\mathbf{A}'\mathbf{A}) \mathbf{x} - 2(\mathbf{A}'\mathbf{b}) \mathbf{x} + \mathbf{b}'\mathbf{b} )

Penalty parameter rationale

The penalty term must be large enough that any infeasible assignment is worse than the objective improvement it might gain by violating the constraint. For a binary constraint A x = b, the residual A x - b is integer-valued; the smallest nonzero violation has squared penalty at least 1. A conservative sufficient bound is rho = sum(abs(c)) + epsilon, because changing binary variables can improve the linear objective by at most sum(abs(c_i)).

Worked example: if sum(abs(c_i)) = 6 and rho = 5.9, an infeasible assignment with violation 1 can gain 6 objective units while paying only 5.9 penalty units, so it can look 0.1 units better than a feasible assignment. Choosing rho = 6 + epsilon closes that gap for this bounded binary model.

This is a sufficient bound for this model family, not a universal rule. Constraints with non-binary variables, non-integer residuals, or a larger objective range need a problem-specific penalty analysis. See Glover, Kochenberger, and Du (2019), “A Tutorial on Formulating and Using QUBO Models.”

[[ -46    0    0   48   48   48    0   48   48   48   48]
 [   0  -44    0   48    0   48   48    0   48   48   48]
 [   0    0  -44    0   48    0   48   48   48   48   48]
 [  48   48    0  -92   48   96   48   48   96   96   96]
 [  48    0   48   48  -92   48   48   96   96   96   96]
 [  48   48    0   96   48  -92   48   48   96   96   96]
 [   0   48   48   48   48   48  -91   48   96   96   96]
 [  48    0   48   48   96   48   48  -92   96   96   96]
 [  48   48   48   96   96   96   96   96 -139  144  144]
 [  48   48   48   96   96   96   96   96  144 -138  144]
 [  48   48   48   96   96   96   96   96  144  144 -139]]
144

We can visualize the graph that defines this instance using the Q matrix as the adjacency matrix of a graph.

Image produced in Jupyter

Let’s define a QUBO model and then solve it using D-Wave’s code for complete enumeration and simulated annealing (eventually with quantum annealing too!).

BinaryQuadraticModel({0: -46.0, 1: -44.0, 2: -44.0, 3: -92.0, 4: -92.0, 5: -92.0, 6: -91.0, 7: -92.0, 8: -139.0, 9: -138.0, 10: -139.0}, {(3, 0): 96.0, (3, 1): 96.0, (4, 0): 96.0, (4, 2): 96.0, (4, 3): 96.0, (5, 0): 96.0, (5, 1): 96.0, (5, 3): 192.0, (5, 4): 96.0, (6, 1): 96.0, (6, 2): 96.0, (6, 3): 96.0, (6, 4): 96.0, (6, 5): 96.0, (7, 0): 96.0, (7, 2): 96.0, (7, 3): 96.0, (7, 4): 192.0, (7, 5): 96.0, (7, 6): 96.0, (8, 0): 96.0, (8, 1): 96.0, (8, 2): 96.0, (8, 3): 192.0, (8, 4): 192.0, (8, 5): 192.0, (8, 6): 192.0, (8, 7): 192.0, (9, 0): 96.0, (9, 1): 96.0, (9, 2): 96.0, (9, 3): 192.0, (9, 4): 192.0, (9, 5): 192.0, (9, 6): 192.0, (9, 7): 192.0, (9, 8): 288.0, (10, 0): 96.0, (10, 1): 96.0, (10, 2): 96.0, (10, 3): 192.0, (10, 4): 192.0, (10, 5): 192.0, (10, 6): 192.0, (10, 7): 192.0, (10, 8): 288.0, (10, 9): 288.0}, 144.0, 'BINARY')

Since the problem is relatively small (11 variables, 211=20482^{11}=2048 combinations), we can afford to enumerate all the solutions.

Image produced in Jupyter
minimum energy: 5.0
Image produced in Jupyter
minimum energy: 5.0

Let’s now solve this QUBO via traditional Integer Programming.

Model 'QUBO example as an IP, 47-779/785 QuIPML'

  Variables:
    x : Size=11, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          0 :     0 :  None :     1 : False :  True : Binary
          1 :     0 :  None :     1 : False :  True : Binary
          2 :     0 :  None :     1 : False :  True : Binary
          3 :     0 :  None :     1 : False :  True : Binary
          4 :     0 :  None :     1 : False :  True : Binary
          5 :     0 :  None :     1 : False :  True : Binary
          6 :     0 :  None :     1 : False :  True : Binary
          7 :     0 :  None :     1 : False :  True : Binary
          8 :     0 :  None :     1 : False :  True : Binary
          9 :     0 :  None :     1 : False :  True : Binary
         10 :     0 :  None :     1 : False :  True : Binary
    y : Size=121, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}*{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key      : Lower : Value : Upper : Fixed : Stale : Domain
          (0, 0) :     0 :  None :     1 : False :  True : Binary
          (0, 1) :     0 :  None :     1 : False :  True : Binary
          (0, 2) :     0 :  None :     1 : False :  True : Binary
          (0, 3) :     0 :  None :     1 : False :  True : Binary
          (0, 4) :     0 :  None :     1 : False :  True : Binary
          (0, 5) :     0 :  None :     1 : False :  True : Binary
          (0, 6) :     0 :  None :     1 : False :  True : Binary
          (0, 7) :     0 :  None :     1 : False :  True : Binary
          (0, 8) :     0 :  None :     1 : False :  True : Binary
          (0, 9) :     0 :  None :     1 : False :  True : Binary
         (0, 10) :     0 :  None :     1 : False :  True : Binary
          (1, 0) :     0 :  None :     1 : False :  True : Binary
          (1, 1) :     0 :  None :     1 : False :  True : Binary
          (1, 2) :     0 :  None :     1 : False :  True : Binary
          (1, 3) :     0 :  None :     1 : False :  True : Binary
          (1, 4) :     0 :  None :     1 : False :  True : Binary
          (1, 5) :     0 :  None :     1 : False :  True : Binary
          (1, 6) :     0 :  None :     1 : False :  True : Binary
          (1, 7) :     0 :  None :     1 : False :  True : Binary
          (1, 8) :     0 :  None :     1 : False :  True : Binary
          (1, 9) :     0 :  None :     1 : False :  True : Binary
         (1, 10) :     0 :  None :     1 : False :  True : Binary
          (2, 0) :     0 :  None :     1 : False :  True : Binary
          (2, 1) :     0 :  None :     1 : False :  True : Binary
          (2, 2) :     0 :  None :     1 : False :  True : Binary
          (2, 3) :     0 :  None :     1 : False :  True : Binary
          (2, 4) :     0 :  None :     1 : False :  True : Binary
          (2, 5) :     0 :  None :     1 : False :  True : Binary
          (2, 6) :     0 :  None :     1 : False :  True : Binary
          (2, 7) :     0 :  None :     1 : False :  True : Binary
          (2, 8) :     0 :  None :     1 : False :  True : Binary
          (2, 9) :     0 :  None :     1 : False :  True : Binary
         (2, 10) :     0 :  None :     1 : False :  True : Binary
          (3, 0) :     0 :  None :     1 : False :  True : Binary
          (3, 1) :     0 :  None :     1 : False :  True : Binary
          (3, 2) :     0 :  None :     1 : False :  True : Binary
          (3, 3) :     0 :  None :     1 : False :  True : Binary
          (3, 4) :     0 :  None :     1 : False :  True : Binary
          (3, 5) :     0 :  None :     1 : False :  True : Binary
          (3, 6) :     0 :  None :     1 : False :  True : Binary
          (3, 7) :     0 :  None :     1 : False :  True : Binary
          (3, 8) :     0 :  None :     1 : False :  True : Binary
          (3, 9) :     0 :  None :     1 : False :  True : Binary
         (3, 10) :     0 :  None :     1 : False :  True : Binary
          (4, 0) :     0 :  None :     1 : False :  True : Binary
          (4, 1) :     0 :  None :     1 : False :  True : Binary
          (4, 2) :     0 :  None :     1 : False :  True : Binary
          (4, 3) :     0 :  None :     1 : False :  True : Binary
          (4, 4) :     0 :  None :     1 : False :  True : Binary
          (4, 5) :     0 :  None :     1 : False :  True : Binary
          (4, 6) :     0 :  None :     1 : False :  True : Binary
          (4, 7) :     0 :  None :     1 : False :  True : Binary
          (4, 8) :     0 :  None :     1 : False :  True : Binary
          (4, 9) :     0 :  None :     1 : False :  True : Binary
         (4, 10) :     0 :  None :     1 : False :  True : Binary
          (5, 0) :     0 :  None :     1 : False :  True : Binary
          (5, 1) :     0 :  None :     1 : False :  True : Binary
          (5, 2) :     0 :  None :     1 : False :  True : Binary
          (5, 3) :     0 :  None :     1 : False :  True : Binary
          (5, 4) :     0 :  None :     1 : False :  True : Binary
          (5, 5) :     0 :  None :     1 : False :  True : Binary
          (5, 6) :     0 :  None :     1 : False :  True : Binary
          (5, 7) :     0 :  None :     1 : False :  True : Binary
          (5, 8) :     0 :  None :     1 : False :  True : Binary
          (5, 9) :     0 :  None :     1 : False :  True : Binary
         (5, 10) :     0 :  None :     1 : False :  True : Binary
          (6, 0) :     0 :  None :     1 : False :  True : Binary
          (6, 1) :     0 :  None :     1 : False :  True : Binary
          (6, 2) :     0 :  None :     1 : False :  True : Binary
          (6, 3) :     0 :  None :     1 : False :  True : Binary
          (6, 4) :     0 :  None :     1 : False :  True : Binary
          (6, 5) :     0 :  None :     1 : False :  True : Binary
          (6, 6) :     0 :  None :     1 : False :  True : Binary
          (6, 7) :     0 :  None :     1 : False :  True : Binary
          (6, 8) :     0 :  None :     1 : False :  True : Binary
          (6, 9) :     0 :  None :     1 : False :  True : Binary
         (6, 10) :     0 :  None :     1 : False :  True : Binary
          (7, 0) :     0 :  None :     1 : False :  True : Binary
          (7, 1) :     0 :  None :     1 : False :  True : Binary
          (7, 2) :     0 :  None :     1 : False :  True : Binary
          (7, 3) :     0 :  None :     1 : False :  True : Binary
          (7, 4) :     0 :  None :     1 : False :  True : Binary
          (7, 5) :     0 :  None :     1 : False :  True : Binary
          (7, 6) :     0 :  None :     1 : False :  True : Binary
          (7, 7) :     0 :  None :     1 : False :  True : Binary
          (7, 8) :     0 :  None :     1 : False :  True : Binary
          (7, 9) :     0 :  None :     1 : False :  True : Binary
         (7, 10) :     0 :  None :     1 : False :  True : Binary
          (8, 0) :     0 :  None :     1 : False :  True : Binary
          (8, 1) :     0 :  None :     1 : False :  True : Binary
          (8, 2) :     0 :  None :     1 : False :  True : Binary
          (8, 3) :     0 :  None :     1 : False :  True : Binary
          (8, 4) :     0 :  None :     1 : False :  True : Binary
          (8, 5) :     0 :  None :     1 : False :  True : Binary
          (8, 6) :     0 :  None :     1 : False :  True : Binary
          (8, 7) :     0 :  None :     1 : False :  True : Binary
          (8, 8) :     0 :  None :     1 : False :  True : Binary
          (8, 9) :     0 :  None :     1 : False :  True : Binary
         (8, 10) :     0 :  None :     1 : False :  True : Binary
          (9, 0) :     0 :  None :     1 : False :  True : Binary
          (9, 1) :     0 :  None :     1 : False :  True : Binary
          (9, 2) :     0 :  None :     1 : False :  True : Binary
          (9, 3) :     0 :  None :     1 : False :  True : Binary
          (9, 4) :     0 :  None :     1 : False :  True : Binary
          (9, 5) :     0 :  None :     1 : False :  True : Binary
          (9, 6) :     0 :  None :     1 : False :  True : Binary
          (9, 7) :     0 :  None :     1 : False :  True : Binary
          (9, 8) :     0 :  None :     1 : False :  True : Binary
          (9, 9) :     0 :  None :     1 : False :  True : Binary
         (9, 10) :     0 :  None :     1 : False :  True : Binary
         (10, 0) :     0 :  None :     1 : False :  True : Binary
         (10, 1) :     0 :  None :     1 : False :  True : Binary
         (10, 2) :     0 :  None :     1 : False :  True : Binary
         (10, 3) :     0 :  None :     1 : False :  True : Binary
         (10, 4) :     0 :  None :     1 : False :  True : Binary
         (10, 5) :     0 :  None :     1 : False :  True : Binary
         (10, 6) :     0 :  None :     1 : False :  True : Binary
         (10, 7) :     0 :  None :     1 : False :  True : Binary
         (10, 8) :     0 :  None :     1 : False :  True : Binary
         (10, 9) :     0 :  None :     1 : False :  True : Binary
        (10, 10) :     0 :  None :     1 : False :  True : Binary

  Objectives:
    objective : Size=1, Index=None, Active=True
ERROR: evaluating object as numeric value: y[3,0]
        (object: <class 'pyomo.core.base.var.VarData'>)
    No value for uninitialized VarData object y[3,0]
ERROR: evaluating object as numeric value: objective
        (object: <class 'pyomo.core.base.objective.ScalarObjective'>)
    No value for uninitialized VarData object y[3,0]
        Key : Active : Value
        None :   None :  None

  Constraints:
    c1 : Size=47
        Key : Lower : Body : Upper
          1 :  None : None :   0.0
          2 :  None : None :   0.0
          3 :  None : None :   0.0
          4 :  None : None :   0.0
          5 :  None : None :   0.0
          6 :  None : None :   0.0
          7 :  None : None :   0.0
          8 :  None : None :   0.0
          9 :  None : None :   0.0
         10 :  None : None :   0.0
         11 :  None : None :   0.0
         12 :  None : None :   0.0
         13 :  None : None :   0.0
         14 :  None : None :   0.0
         15 :  None : None :   0.0
         16 :  None : None :   0.0
         17 :  None : None :   0.0
         18 :  None : None :   0.0
         19 :  None : None :   0.0
         20 :  None : None :   0.0
         21 :  None : None :   0.0
         22 :  None : None :   0.0
         23 :  None : None :   0.0
         24 :  None : None :   0.0
         25 :  None : None :   0.0
         26 :  None : None :   0.0
         27 :  None : None :   0.0
         28 :  None : None :   0.0
         29 :  None : None :   0.0
         30 :  None : None :   0.0
         31 :  None : None :   0.0
         32 :  None : None :   0.0
         33 :  None : None :   0.0
         34 :  None : None :   0.0
         35 :  None : None :   0.0
         36 :  None : None :   0.0
         37 :  None : None :   0.0
         38 :  None : None :   0.0
         39 :  None : None :   0.0
         40 :  None : None :   0.0
         41 :  None : None :   0.0
         42 :  None : None :   0.0
         43 :  None : None :   0.0
         44 :  None : None :   0.0
         45 :  None : None :   0.0
         46 :  None : None :   0.0
         47 :  None : None :   0.0
    c2 : Size=47
        Key : Lower : Body : Upper
          1 :  None : None :   0.0
          2 :  None : None :   0.0
          3 :  None : None :   0.0
          4 :  None : None :   0.0
          5 :  None : None :   0.0
          6 :  None : None :   0.0
          7 :  None : None :   0.0
          8 :  None : None :   0.0
          9 :  None : None :   0.0
         10 :  None : None :   0.0
         11 :  None : None :   0.0
         12 :  None : None :   0.0
         13 :  None : None :   0.0
         14 :  None : None :   0.0
         15 :  None : None :   0.0
         16 :  None : None :   0.0
         17 :  None : None :   0.0
         18 :  None : None :   0.0
         19 :  None : None :   0.0
         20 :  None : None :   0.0
         21 :  None : None :   0.0
         22 :  None : None :   0.0
         23 :  None : None :   0.0
         24 :  None : None :   0.0
         25 :  None : None :   0.0
         26 :  None : None :   0.0
         27 :  None : None :   0.0
         28 :  None : None :   0.0
         29 :  None : None :   0.0
         30 :  None : None :   0.0
         31 :  None : None :   0.0
         32 :  None : None :   0.0
         33 :  None : None :   0.0
         34 :  None : None :   0.0
         35 :  None : None :   0.0
         36 :  None : None :   0.0
         37 :  None : None :   0.0
         38 :  None : None :   0.0
         39 :  None : None :   0.0
         40 :  None : None :   0.0
         41 :  None : None :   0.0
         42 :  None : None :   0.0
         43 :  None : None :   0.0
         44 :  None : None :   0.0
         45 :  None : None :   0.0
         46 :  None : None :   0.0
         47 :  None : None :   0.0
    c3 : Size=47
        Key : Lower : Body : Upper
          1 :  None : None :   0.0
          2 :  None : None :   0.0
          3 :  None : None :   0.0
          4 :  None : None :   0.0
          5 :  None : None :   0.0
          6 :  None : None :   0.0
          7 :  None : None :   0.0
          8 :  None : None :   0.0
          9 :  None : None :   0.0
         10 :  None : None :   0.0
         11 :  None : None :   0.0
         12 :  None : None :   0.0
         13 :  None : None :   0.0
         14 :  None : None :   0.0
         15 :  None : None :   0.0
         16 :  None : None :   0.0
         17 :  None : None :   0.0
         18 :  None : None :   0.0
         19 :  None : None :   0.0
         20 :  None : None :   0.0
         21 :  None : None :   0.0
         22 :  None : None :   0.0
         23 :  None : None :   0.0
         24 :  None : None :   0.0
         25 :  None : None :   0.0
         26 :  None : None :   0.0
         27 :  None : None :   0.0
         28 :  None : None :   0.0
         29 :  None : None :   0.0
         30 :  None : None :   0.0
         31 :  None : None :   0.0
         32 :  None : None :   0.0
         33 :  None : None :   0.0
         34 :  None : None :   0.0
         35 :  None : None :   0.0
         36 :  None : None :   0.0
         37 :  None : None :   0.0
         38 :  None : None :   0.0
         39 :  None : None :   0.0
         40 :  None : None :   0.0
         41 :  None : None :   0.0
         42 :  None : None :   0.0
         43 :  None : None :   0.0
         44 :  None : None :   0.0
         45 :  None : None :   0.0
         46 :  None : None :   0.0
         47 :  None : None :   0.0

Let’s install the MIP solver GLPK

Notebook Cell
Model 'QUBO example as an IP, 47-779/785 QuIPML'

  Variables:
    x : Size=11, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          0 :     0 :   0.0 :     1 : False : False : Binary
          1 :     0 :   0.0 :     1 : False : False : Binary
          2 :     0 :   0.0 :     1 : False : False : Binary
          3 :     0 :   0.0 :     1 : False : False : Binary
          4 :     0 :   0.0 :     1 : False : False : Binary
          5 :     0 :   0.0 :     1 : False : False : Binary
          6 :     0 :   0.0 :     1 : False : False : Binary
          7 :     0 :   0.0 :     1 : False : False : Binary
          8 :     0 :   0.0 :     1 : False : False : Binary
          9 :     0 :   0.0 :     1 : False : False : Binary
         10 :     0 :   1.0 :     1 : False : False : Binary
    y : Size=121, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}*{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key      : Lower : Value : Upper : Fixed : Stale : Domain
          (0, 0) :     0 :  None :     1 : False :  True : Binary
          (0, 1) :     0 :  None :     1 : False :  True : Binary
          (0, 2) :     0 :  None :     1 : False :  True : Binary
          (0, 3) :     0 :  None :     1 : False :  True : Binary
          (0, 4) :     0 :  None :     1 : False :  True : Binary
          (0, 5) :     0 :  None :     1 : False :  True : Binary
          (0, 6) :     0 :  None :     1 : False :  True : Binary
          (0, 7) :     0 :  None :     1 : False :  True : Binary
          (0, 8) :     0 :  None :     1 : False :  True : Binary
          (0, 9) :     0 :  None :     1 : False :  True : Binary
         (0, 10) :     0 :  None :     1 : False :  True : Binary
          (1, 0) :     0 :  None :     1 : False :  True : Binary
          (1, 1) :     0 :  None :     1 : False :  True : Binary
          (1, 2) :     0 :  None :     1 : False :  True : Binary
          (1, 3) :     0 :  None :     1 : False :  True : Binary
          (1, 4) :     0 :  None :     1 : False :  True : Binary
          (1, 5) :     0 :  None :     1 : False :  True : Binary
          (1, 6) :     0 :  None :     1 : False :  True : Binary
          (1, 7) :     0 :  None :     1 : False :  True : Binary
          (1, 8) :     0 :  None :     1 : False :  True : Binary
          (1, 9) :     0 :  None :     1 : False :  True : Binary
         (1, 10) :     0 :  None :     1 : False :  True : Binary
          (2, 0) :     0 :  None :     1 : False :  True : Binary
          (2, 1) :     0 :  None :     1 : False :  True : Binary
          (2, 2) :     0 :  None :     1 : False :  True : Binary
          (2, 3) :     0 :  None :     1 : False :  True : Binary
          (2, 4) :     0 :  None :     1 : False :  True : Binary
          (2, 5) :     0 :  None :     1 : False :  True : Binary
          (2, 6) :     0 :  None :     1 : False :  True : Binary
          (2, 7) :     0 :  None :     1 : False :  True : Binary
          (2, 8) :     0 :  None :     1 : False :  True : Binary
          (2, 9) :     0 :  None :     1 : False :  True : Binary
         (2, 10) :     0 :  None :     1 : False :  True : Binary
          (3, 0) :     0 :   0.0 :     1 : False : False : Binary
          (3, 1) :     0 :   0.0 :     1 : False : False : Binary
          (3, 2) :     0 :  None :     1 : False :  True : Binary
          (3, 3) :     0 :  None :     1 : False :  True : Binary
          (3, 4) :     0 :  None :     1 : False :  True : Binary
          (3, 5) :     0 :  None :     1 : False :  True : Binary
          (3, 6) :     0 :  None :     1 : False :  True : Binary
          (3, 7) :     0 :  None :     1 : False :  True : Binary
          (3, 8) :     0 :  None :     1 : False :  True : Binary
          (3, 9) :     0 :  None :     1 : False :  True : Binary
         (3, 10) :     0 :  None :     1 : False :  True : Binary
          (4, 0) :     0 :   0.0 :     1 : False : False : Binary
          (4, 1) :     0 :  None :     1 : False :  True : Binary
          (4, 2) :     0 :   0.0 :     1 : False : False : Binary
          (4, 3) :     0 :   0.0 :     1 : False : False : Binary
          (4, 4) :     0 :  None :     1 : False :  True : Binary
          (4, 5) :     0 :  None :     1 : False :  True : Binary
          (4, 6) :     0 :  None :     1 : False :  True : Binary
          (4, 7) :     0 :  None :     1 : False :  True : Binary
          (4, 8) :     0 :  None :     1 : False :  True : Binary
          (4, 9) :     0 :  None :     1 : False :  True : Binary
         (4, 10) :     0 :  None :     1 : False :  True : Binary
          (5, 0) :     0 :   0.0 :     1 : False : False : Binary
          (5, 1) :     0 :   0.0 :     1 : False : False : Binary
          (5, 2) :     0 :  None :     1 : False :  True : Binary
          (5, 3) :     0 :   0.0 :     1 : False : False : Binary
          (5, 4) :     0 :   0.0 :     1 : False : False : Binary
          (5, 5) :     0 :  None :     1 : False :  True : Binary
          (5, 6) :     0 :  None :     1 : False :  True : Binary
          (5, 7) :     0 :  None :     1 : False :  True : Binary
          (5, 8) :     0 :  None :     1 : False :  True : Binary
          (5, 9) :     0 :  None :     1 : False :  True : Binary
         (5, 10) :     0 :  None :     1 : False :  True : Binary
          (6, 0) :     0 :  None :     1 : False :  True : Binary
          (6, 1) :     0 :   0.0 :     1 : False : False : Binary
          (6, 2) :     0 :   0.0 :     1 : False : False : Binary
          (6, 3) :     0 :   0.0 :     1 : False : False : Binary
          (6, 4) :     0 :   0.0 :     1 : False : False : Binary
          (6, 5) :     0 :   0.0 :     1 : False : False : Binary
          (6, 6) :     0 :  None :     1 : False :  True : Binary
          (6, 7) :     0 :  None :     1 : False :  True : Binary
          (6, 8) :     0 :  None :     1 : False :  True : Binary
          (6, 9) :     0 :  None :     1 : False :  True : Binary
         (6, 10) :     0 :  None :     1 : False :  True : Binary
          (7, 0) :     0 :   0.0 :     1 : False : False : Binary
          (7, 1) :     0 :  None :     1 : False :  True : Binary
          (7, 2) :     0 :   0.0 :     1 : False : False : Binary
          (7, 3) :     0 :   0.0 :     1 : False : False : Binary
          (7, 4) :     0 :   0.0 :     1 : False : False : Binary
          (7, 5) :     0 :   0.0 :     1 : False : False : Binary
          (7, 6) :     0 :   0.0 :     1 : False : False : Binary
          (7, 7) :     0 :  None :     1 : False :  True : Binary
          (7, 8) :     0 :  None :     1 : False :  True : Binary
          (7, 9) :     0 :  None :     1 : False :  True : Binary
         (7, 10) :     0 :  None :     1 : False :  True : Binary
          (8, 0) :     0 :   0.0 :     1 : False : False : Binary
          (8, 1) :     0 :   0.0 :     1 : False : False : Binary
          (8, 2) :     0 :   0.0 :     1 : False : False : Binary
          (8, 3) :     0 :   0.0 :     1 : False : False : Binary
          (8, 4) :     0 :   0.0 :     1 : False : False : Binary
          (8, 5) :     0 :   0.0 :     1 : False : False : Binary
          (8, 6) :     0 :   0.0 :     1 : False : False : Binary
          (8, 7) :     0 :   0.0 :     1 : False : False : Binary
          (8, 8) :     0 :  None :     1 : False :  True : Binary
          (8, 9) :     0 :  None :     1 : False :  True : Binary
         (8, 10) :     0 :  None :     1 : False :  True : Binary
          (9, 0) :     0 :   0.0 :     1 : False : False : Binary
          (9, 1) :     0 :   0.0 :     1 : False : False : Binary
          (9, 2) :     0 :   0.0 :     1 : False : False : Binary
          (9, 3) :     0 :   0.0 :     1 : False : False : Binary
          (9, 4) :     0 :   0.0 :     1 : False : False : Binary
          (9, 5) :     0 :   0.0 :     1 : False : False : Binary
          (9, 6) :     0 :   0.0 :     1 : False : False : Binary
          (9, 7) :     0 :   0.0 :     1 : False : False : Binary
          (9, 8) :     0 :   0.0 :     1 : False : False : Binary
          (9, 9) :     0 :  None :     1 : False :  True : Binary
         (9, 10) :     0 :  None :     1 : False :  True : Binary
         (10, 0) :     0 :   0.0 :     1 : False : False : Binary
         (10, 1) :     0 :   0.0 :     1 : False : False : Binary
         (10, 2) :     0 :   0.0 :     1 : False : False : Binary
         (10, 3) :     0 :   0.0 :     1 : False : False : Binary
         (10, 4) :     0 :   0.0 :     1 : False : False : Binary
         (10, 5) :     0 :   0.0 :     1 : False : False : Binary
         (10, 6) :     0 :   0.0 :     1 : False : False : Binary
         (10, 7) :     0 :   0.0 :     1 : False : False : Binary
         (10, 8) :     0 :   0.0 :     1 : False : False : Binary
         (10, 9) :     0 :   0.0 :     1 : False : False : Binary
        (10, 10) :     0 :  None :     1 : False :  True : Binary

  Objectives:
    objective : Size=1, Index=None, Active=True
        Key  : Active : Value
        None :   True :   5.0

  Constraints:
    c1 : Size=47
        Key : Lower : Body : Upper
          1 :  None : -1.0 :   0.0
          2 :  None : -1.0 :   0.0
          3 :  None : -1.0 :   0.0
          4 :  None : -1.0 :   0.0
          5 :  None : -1.0 :   0.0
          6 :  None : -1.0 :   0.0
          7 :  None : -1.0 :   0.0
          8 :  None : -1.0 :   0.0
          9 :  None : -1.0 :   0.0
         10 :  None : -1.0 :   0.0
         11 :  None : -1.0 :   0.0
         12 :  None : -1.0 :   0.0
         13 :  None : -1.0 :   0.0
         14 :  None : -1.0 :   0.0
         15 :  None : -1.0 :   0.0
         16 :  None : -1.0 :   0.0
         17 :  None : -1.0 :   0.0
         18 :  None : -1.0 :   0.0
         19 :  None : -1.0 :   0.0
         20 :  None : -1.0 :   0.0
         21 :  None : -1.0 :   0.0
         22 :  None : -1.0 :   0.0
         23 :  None : -1.0 :   0.0
         24 :  None : -1.0 :   0.0
         25 :  None : -1.0 :   0.0
         26 :  None : -1.0 :   0.0
         27 :  None : -1.0 :   0.0
         28 :  None : -1.0 :   0.0
         29 :  None : -1.0 :   0.0
         30 :  None : -1.0 :   0.0
         31 :  None : -1.0 :   0.0
         32 :  None : -1.0 :   0.0
         33 :  None : -1.0 :   0.0
         34 :  None : -1.0 :   0.0
         35 :  None : -1.0 :   0.0
         36 :  None : -1.0 :   0.0
         37 :  None : -1.0 :   0.0
         38 :  None :  0.0 :   0.0
         39 :  None :  0.0 :   0.0
         40 :  None :  0.0 :   0.0
         41 :  None :  0.0 :   0.0
         42 :  None :  0.0 :   0.0
         43 :  None :  0.0 :   0.0
         44 :  None :  0.0 :   0.0
         45 :  None :  0.0 :   0.0
         46 :  None :  0.0 :   0.0
         47 :  None :  0.0 :   0.0
    c2 : Size=47
        Key : Lower : Body : Upper
          1 :  None :  0.0 :   0.0
          2 :  None :  0.0 :   0.0
          3 :  None :  0.0 :   0.0
          4 :  None :  0.0 :   0.0
          5 :  None :  0.0 :   0.0
          6 :  None :  0.0 :   0.0
          7 :  None :  0.0 :   0.0
          8 :  None :  0.0 :   0.0
          9 :  None :  0.0 :   0.0
         10 :  None :  0.0 :   0.0
         11 :  None :  0.0 :   0.0
         12 :  None :  0.0 :   0.0
         13 :  None :  0.0 :   0.0
         14 :  None :  0.0 :   0.0
         15 :  None :  0.0 :   0.0
         16 :  None :  0.0 :   0.0
         17 :  None :  0.0 :   0.0
         18 :  None :  0.0 :   0.0
         19 :  None :  0.0 :   0.0
         20 :  None :  0.0 :   0.0
         21 :  None :  0.0 :   0.0
         22 :  None :  0.0 :   0.0
         23 :  None :  0.0 :   0.0
         24 :  None :  0.0 :   0.0
         25 :  None :  0.0 :   0.0
         26 :  None :  0.0 :   0.0
         27 :  None :  0.0 :   0.0
         28 :  None :  0.0 :   0.0
         29 :  None :  0.0 :   0.0
         30 :  None :  0.0 :   0.0
         31 :  None :  0.0 :   0.0
         32 :  None :  0.0 :   0.0
         33 :  None :  0.0 :   0.0
         34 :  None :  0.0 :   0.0
         35 :  None :  0.0 :   0.0
         36 :  None :  0.0 :   0.0
         37 :  None :  0.0 :   0.0
         38 :  None : -1.0 :   0.0
         39 :  None : -1.0 :   0.0
         40 :  None : -1.0 :   0.0
         41 :  None : -1.0 :   0.0
         42 :  None : -1.0 :   0.0
         43 :  None : -1.0 :   0.0
         44 :  None : -1.0 :   0.0
         45 :  None : -1.0 :   0.0
         46 :  None : -1.0 :   0.0
         47 :  None : -1.0 :   0.0
    c3 : Size=47
        Key : Lower : Body : Upper
          1 :  None :  0.0 :   0.0
          2 :  None :  0.0 :   0.0
          3 :  None :  0.0 :   0.0
          4 :  None :  0.0 :   0.0
          5 :  None :  0.0 :   0.0
          6 :  None :  0.0 :   0.0
          7 :  None :  0.0 :   0.0
          8 :  None :  0.0 :   0.0
          9 :  None :  0.0 :   0.0
         10 :  None :  0.0 :   0.0
         11 :  None :  0.0 :   0.0
         12 :  None :  0.0 :   0.0
         13 :  None :  0.0 :   0.0
         14 :  None :  0.0 :   0.0
         15 :  None :  0.0 :   0.0
         16 :  None :  0.0 :   0.0
         17 :  None :  0.0 :   0.0
         18 :  None :  0.0 :   0.0
         19 :  None :  0.0 :   0.0
         20 :  None :  0.0 :   0.0
         21 :  None :  0.0 :   0.0
         22 :  None :  0.0 :   0.0
         23 :  None :  0.0 :   0.0
         24 :  None :  0.0 :   0.0
         25 :  None :  0.0 :   0.0
         26 :  None :  0.0 :   0.0
         27 :  None :  0.0 :   0.0
         28 :  None :  0.0 :   0.0
         29 :  None :  0.0 :   0.0
         30 :  None :  0.0 :   0.0
         31 :  None :  0.0 :   0.0
         32 :  None :  0.0 :   0.0
         33 :  None :  0.0 :   0.0
         34 :  None :  0.0 :   0.0
         35 :  None :  0.0 :   0.0
         36 :  None :  0.0 :   0.0
         37 :  None :  0.0 :   0.0
         38 :  None :  0.0 :   0.0
         39 :  None :  0.0 :   0.0
         40 :  None :  0.0 :   0.0
         41 :  None :  0.0 :   0.0
         42 :  None :  0.0 :   0.0
         43 :  None :  0.0 :   0.0
         44 :  None :  0.0 :   0.0
         45 :  None :  0.0 :   0.0
         46 :  None :  0.0 :   0.0
         47 :  None :  0.0 :   0.0

We observe that the optimal solution of this problem is x8=1,0x_{8} = 1, 0 otherwise, leading to an objective of 5. Notice that this problem has a degenerate optimal solution given that x10=1,0x_{10} = 1, 0 otherwise also leads to the same solution.

Ising model

This section introduces the Ising model. We use D-Wave’s dimod and neal packages to define Ising models and solve them with simulated annealing. For integer-programming comparisons, we use Pyomo, an open-source modeling framework with access to linear and nonlinear solvers. The examples use the open-source GLPK solver for mixed-integer linear programming.

Ising problem statement

We pose the Ising problem as the following optimization problem:

min⁡σ∈{−1,+1}nH(σ)=min⁡σ∈{−1,+1}n∑(ij)∈E(G)Jijσiσj+∑i∈V(G)hiσi+cI\min_{\sigma \in \{ -1,+1 \}^n} H(\sigma) =\min_{\sigma \in \{ -1,+1 \}^n} \sum_{(ij) \in E(G)} J_{ij}\sigma_i\sigma_j + \sum_{i \in V(G)}h_i\sigma_i + c_I

where we optimize over spins σ∈{−1,+1}n\sigma \in \{ -1,+1 \}^n, on a constrained graph G(V,E)G(V,E), where the quadratic coefficients are JijJ_{ij} and the linear coefficients are hih_i. We also include an arbitrary offset of the Ising model cIc_I.

Ising example

Suppose we have an Ising model defined from

h=[145.0122.0122.0266.0266.0266.0242.5266.0386.5387.0386.5],J=[0002424240242424240002402424242424240000240242424242400002448242448484800000242448484848000000242448484800000002448484800000000484848000000000727200000000007200000000000] and β=1319.5h = \begin{bmatrix} 145.0 \\ 122.0 \\ 122.0 \\ 266.0 \\ 266.0 \\ 266.0 \\ 242.5 \\ 266.0 \\ 386.5 \\ 387.0 \\ 386.5 \end{bmatrix}, J = \begin{bmatrix} 0 & 0 & 0 & 24 & 24 & 24 & 0 & 24 & 24 & 24 & 24\\ 0 & 0 & 0 & 24 & 0 & 24 & 24 & 24 & 24 & 24 & 24\\ 0 & 0 & 0 & 0 & 24 & 0 & 24 & 24 & 24 & 24 & 24\\ 0 & 0 & 0 & 0 & 24 & 48 & 24 & 24 & 48 & 48 & 48\\ 0 & 0 & 0 & 0 & 0 & 24 & 24 & 48 & 48 & 48 & 48\\ 0 & 0 & 0 & 0 & 0 & 0 & 24 & 24 & 48 & 48 & 48\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 24 & 48 & 48 & 48\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 48 & 48 & 48\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 72 & 72\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 72\\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ \end{bmatrix} \text{ and } \beta = 1319.5

Let’s solve this problem

Since the problem is relatively small (11 variables, 211=20482^{11}=2048 combinations), we can afford to enumerate all the solutions.

Image produced in Jupyter
minimum energy: 5.0
Image produced in Jupyter
minimum energy: 5.0

Let’s now solve this Ising Model via traditional Integer Programming.

Model 'Ising example as an IP, 47-779/785 QuIPML'

  Variables:
    x : Size=11, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          0 :     0 :  None :     1 : False :  True : Binary
          1 :     0 :  None :     1 : False :  True : Binary
          2 :     0 :  None :     1 : False :  True : Binary
          3 :     0 :  None :     1 : False :  True : Binary
          4 :     0 :  None :     1 : False :  True : Binary
          5 :     0 :  None :     1 : False :  True : Binary
          6 :     0 :  None :     1 : False :  True : Binary
          7 :     0 :  None :     1 : False :  True : Binary
          8 :     0 :  None :     1 : False :  True : Binary
          9 :     0 :  None :     1 : False :  True : Binary
         10 :     0 :  None :     1 : False :  True : Binary
    y : Size=121, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}*{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key      : Lower : Value : Upper : Fixed : Stale : Domain
          (0, 0) :     0 :  None :     1 : False :  True : Binary
          (0, 1) :     0 :  None :     1 : False :  True : Binary
          (0, 2) :     0 :  None :     1 : False :  True : Binary
          (0, 3) :     0 :  None :     1 : False :  True : Binary
          (0, 4) :     0 :  None :     1 : False :  True : Binary
          (0, 5) :     0 :  None :     1 : False :  True : Binary
          (0, 6) :     0 :  None :     1 : False :  True : Binary
          (0, 7) :     0 :  None :     1 : False :  True : Binary
          (0, 8) :     0 :  None :     1 : False :  True : Binary
          (0, 9) :     0 :  None :     1 : False :  True : Binary
         (0, 10) :     0 :  None :     1 : False :  True : Binary
          (1, 0) :     0 :  None :     1 : False :  True : Binary
          (1, 1) :     0 :  None :     1 : False :  True : Binary
          (1, 2) :     0 :  None :     1 : False :  True : Binary
          (1, 3) :     0 :  None :     1 : False :  True : Binary
          (1, 4) :     0 :  None :     1 : False :  True : Binary
          (1, 5) :     0 :  None :     1 : False :  True : Binary
          (1, 6) :     0 :  None :     1 : False :  True : Binary
          (1, 7) :     0 :  None :     1 : False :  True : Binary
          (1, 8) :     0 :  None :     1 : False :  True : Binary
          (1, 9) :     0 :  None :     1 : False :  True : Binary
         (1, 10) :     0 :  None :     1 : False :  True : Binary
          (2, 0) :     0 :  None :     1 : False :  True : Binary
          (2, 1) :     0 :  None :     1 : False :  True : Binary
          (2, 2) :     0 :  None :     1 : False :  True : Binary
          (2, 3) :     0 :  None :     1 : False :  True : Binary
          (2, 4) :     0 :  None :     1 : False :  True : Binary
          (2, 5) :     0 :  None :     1 : False :  True : Binary
          (2, 6) :     0 :  None :     1 : False :  True : Binary
          (2, 7) :     0 :  None :     1 : False :  True : Binary
          (2, 8) :     0 :  None :     1 : False :  True : Binary
          (2, 9) :     0 :  None :     1 : False :  True : Binary
         (2, 10) :     0 :  None :     1 : False :  True : Binary
          (3, 0) :     0 :  None :     1 : False :  True : Binary
          (3, 1) :     0 :  None :     1 : False :  True : Binary
          (3, 2) :     0 :  None :     1 : False :  True : Binary
          (3, 3) :     0 :  None :     1 : False :  True : Binary
          (3, 4) :     0 :  None :     1 : False :  True : Binary
          (3, 5) :     0 :  None :     1 : False :  True : Binary
          (3, 6) :     0 :  None :     1 : False :  True : Binary
          (3, 7) :     0 :  None :     1 : False :  True : Binary
          (3, 8) :     0 :  None :     1 : False :  True : Binary
          (3, 9) :     0 :  None :     1 : False :  True : Binary
         (3, 10) :     0 :  None :     1 : False :  True : Binary
          (4, 0) :     0 :  None :     1 : False :  True : Binary
          (4, 1) :     0 :  None :     1 : False :  True : Binary
          (4, 2) :     0 :  None :     1 : False :  True : Binary
          (4, 3) :     0 :  None :     1 : False :  True : Binary
          (4, 4) :     0 :  None :     1 : False :  True : Binary
          (4, 5) :     0 :  None :     1 : False :  True : Binary
          (4, 6) :     0 :  None :     1 : False :  True : Binary
          (4, 7) :     0 :  None :     1 : False :  True : Binary
          (4, 8) :     0 :  None :     1 : False :  True : Binary
          (4, 9) :     0 :  None :     1 : False :  True : Binary
         (4, 10) :     0 :  None :     1 : False :  True : Binary
          (5, 0) :     0 :  None :     1 : False :  True : Binary
          (5, 1) :     0 :  None :     1 : False :  True : Binary
          (5, 2) :     0 :  None :     1 : False :  True : Binary
          (5, 3) :     0 :  None :     1 : False :  True : Binary
          (5, 4) :     0 :  None :     1 : False :  True : Binary
          (5, 5) :     0 :  None :     1 : False :  True : Binary
          (5, 6) :     0 :  None :     1 : False :  True : Binary
          (5, 7) :     0 :  None :     1 : False :  True : Binary
          (5, 8) :     0 :  None :     1 : False :  True : Binary
          (5, 9) :     0 :  None :     1 : False :  True : Binary
         (5, 10) :     0 :  None :     1 : False :  True : Binary
          (6, 0) :     0 :  None :     1 : False :  True : Binary
          (6, 1) :     0 :  None :     1 : False :  True : Binary
          (6, 2) :     0 :  None :     1 : False :  True : Binary
          (6, 3) :     0 :  None :     1 : False :  True : Binary
          (6, 4) :     0 :  None :     1 : False :  True : Binary
          (6, 5) :     0 :  None :     1 : False :  True : Binary
          (6, 6) :     0 :  None :     1 : False :  True : Binary
          (6, 7) :     0 :  None :     1 : False :  True : Binary
          (6, 8) :     0 :  None :     1 : False :  True : Binary
          (6, 9) :     0 :  None :     1 : False :  True : Binary
         (6, 10) :     0 :  None :     1 : False :  True : Binary
          (7, 0) :     0 :  None :     1 : False :  True : Binary
          (7, 1) :     0 :  None :     1 : False :  True : Binary
          (7, 2) :     0 :  None :     1 : False :  True : Binary
          (7, 3) :     0 :  None :     1 : False :  True : Binary
          (7, 4) :     0 :  None :     1 : False :  True : Binary
          (7, 5) :     0 :  None :     1 : False :  True : Binary
          (7, 6) :     0 :  None :     1 : False :  True : Binary
          (7, 7) :     0 :  None :     1 : False :  True : Binary
          (7, 8) :     0 :  None :     1 : False :  True : Binary
          (7, 9) :     0 :  None :     1 : False :  True : Binary
         (7, 10) :     0 :  None :     1 : False :  True : Binary
          (8, 0) :     0 :  None :     1 : False :  True : Binary
          (8, 1) :     0 :  None :     1 : False :  True : Binary
          (8, 2) :     0 :  None :     1 : False :  True : Binary
          (8, 3) :     0 :  None :     1 : False :  True : Binary
          (8, 4) :     0 :  None :     1 : False :  True : Binary
          (8, 5) :     0 :  None :     1 : False :  True : Binary
          (8, 6) :     0 :  None :     1 : False :  True : Binary
          (8, 7) :     0 :  None :     1 : False :  True : Binary
          (8, 8) :     0 :  None :     1 : False :  True : Binary
          (8, 9) :     0 :  None :     1 : False :  True : Binary
         (8, 10) :     0 :  None :     1 : False :  True : Binary
          (9, 0) :     0 :  None :     1 : False :  True : Binary
          (9, 1) :     0 :  None :     1 : False :  True : Binary
          (9, 2) :     0 :  None :     1 : False :  True : Binary
          (9, 3) :     0 :  None :     1 : False :  True : Binary
          (9, 4) :     0 :  None :     1 : False :  True : Binary
          (9, 5) :     0 :  None :     1 : False :  True : Binary
          (9, 6) :     0 :  None :     1 : False :  True : Binary
          (9, 7) :     0 :  None :     1 : False :  True : Binary
          (9, 8) :     0 :  None :     1 : False :  True : Binary
          (9, 9) :     0 :  None :     1 : False :  True : Binary
         (9, 10) :     0 :  None :     1 : False :  True : Binary
         (10, 0) :     0 :  None :     1 : False :  True : Binary
         (10, 1) :     0 :  None :     1 : False :  True : Binary
         (10, 2) :     0 :  None :     1 : False :  True : Binary
         (10, 3) :     0 :  None :     1 : False :  True : Binary
         (10, 4) :     0 :  None :     1 : False :  True : Binary
         (10, 5) :     0 :  None :     1 : False :  True : Binary
         (10, 6) :     0 :  None :     1 : False :  True : Binary
         (10, 7) :     0 :  None :     1 : False :  True : Binary
         (10, 8) :     0 :  None :     1 : False :  True : Binary
         (10, 9) :     0 :  None :     1 : False :  True : Binary
        (10, 10) :     0 :  None :     1 : False :  True : Binary

  Objectives:
    objective : Size=1, Index=None, Active=True
ERROR: evaluating object as numeric value: y[3,0]
        (object: <class 'pyomo.core.base.var.VarData'>)
    No value for uninitialized VarData object y[3,0]
ERROR: evaluating object as numeric value: objective
        (object: <class 'pyomo.core.base.objective.ScalarObjective'>)
    No value for uninitialized VarData object y[3,0]
        Key : Active : Value
        None :   None :  None

  Constraints:
    c1 : Size=47
        Key : Lower : Body : Upper
          1 :  None : None :   0.0
          2 :  None : None :   0.0
          3 :  None : None :   0.0
          4 :  None : None :   0.0
          5 :  None : None :   0.0
          6 :  None : None :   0.0
          7 :  None : None :   0.0
          8 :  None : None :   0.0
          9 :  None : None :   0.0
         10 :  None : None :   0.0
         11 :  None : None :   0.0
         12 :  None : None :   0.0
         13 :  None : None :   0.0
         14 :  None : None :   0.0
         15 :  None : None :   0.0
         16 :  None : None :   0.0
         17 :  None : None :   0.0
         18 :  None : None :   0.0
         19 :  None : None :   0.0
         20 :  None : None :   0.0
         21 :  None : None :   0.0
         22 :  None : None :   0.0
         23 :  None : None :   0.0
         24 :  None : None :   0.0
         25 :  None : None :   0.0
         26 :  None : None :   0.0
         27 :  None : None :   0.0
         28 :  None : None :   0.0
         29 :  None : None :   0.0
         30 :  None : None :   0.0
         31 :  None : None :   0.0
         32 :  None : None :   0.0
         33 :  None : None :   0.0
         34 :  None : None :   0.0
         35 :  None : None :   0.0
         36 :  None : None :   0.0
         37 :  None : None :   0.0
         38 :  None : None :   0.0
         39 :  None : None :   0.0
         40 :  None : None :   0.0
         41 :  None : None :   0.0
         42 :  None : None :   0.0
         43 :  None : None :   0.0
         44 :  None : None :   0.0
         45 :  None : None :   0.0
         46 :  None : None :   0.0
         47 :  None : None :   0.0
    c2 : Size=47
        Key : Lower : Body : Upper
          1 :  None : None :   0.0
          2 :  None : None :   0.0
          3 :  None : None :   0.0
          4 :  None : None :   0.0
          5 :  None : None :   0.0
          6 :  None : None :   0.0
          7 :  None : None :   0.0
          8 :  None : None :   0.0
          9 :  None : None :   0.0
         10 :  None : None :   0.0
         11 :  None : None :   0.0
         12 :  None : None :   0.0
         13 :  None : None :   0.0
         14 :  None : None :   0.0
         15 :  None : None :   0.0
         16 :  None : None :   0.0
         17 :  None : None :   0.0
         18 :  None : None :   0.0
         19 :  None : None :   0.0
         20 :  None : None :   0.0
         21 :  None : None :   0.0
         22 :  None : None :   0.0
         23 :  None : None :   0.0
         24 :  None : None :   0.0
         25 :  None : None :   0.0
         26 :  None : None :   0.0
         27 :  None : None :   0.0
         28 :  None : None :   0.0
         29 :  None : None :   0.0
         30 :  None : None :   0.0
         31 :  None : None :   0.0
         32 :  None : None :   0.0
         33 :  None : None :   0.0
         34 :  None : None :   0.0
         35 :  None : None :   0.0
         36 :  None : None :   0.0
         37 :  None : None :   0.0
         38 :  None : None :   0.0
         39 :  None : None :   0.0
         40 :  None : None :   0.0
         41 :  None : None :   0.0
         42 :  None : None :   0.0
         43 :  None : None :   0.0
         44 :  None : None :   0.0
         45 :  None : None :   0.0
         46 :  None : None :   0.0
         47 :  None : None :   0.0
    c3 : Size=47
        Key : Lower : Body : Upper
          1 :  None : None :   0.0
          2 :  None : None :   0.0
          3 :  None : None :   0.0
          4 :  None : None :   0.0
          5 :  None : None :   0.0
          6 :  None : None :   0.0
          7 :  None : None :   0.0
          8 :  None : None :   0.0
          9 :  None : None :   0.0
         10 :  None : None :   0.0
         11 :  None : None :   0.0
         12 :  None : None :   0.0
         13 :  None : None :   0.0
         14 :  None : None :   0.0
         15 :  None : None :   0.0
         16 :  None : None :   0.0
         17 :  None : None :   0.0
         18 :  None : None :   0.0
         19 :  None : None :   0.0
         20 :  None : None :   0.0
         21 :  None : None :   0.0
         22 :  None : None :   0.0
         23 :  None : None :   0.0
         24 :  None : None :   0.0
         25 :  None : None :   0.0
         26 :  None : None :   0.0
         27 :  None : None :   0.0
         28 :  None : None :   0.0
         29 :  None : None :   0.0
         30 :  None : None :   0.0
         31 :  None : None :   0.0
         32 :  None : None :   0.0
         33 :  None : None :   0.0
         34 :  None : None :   0.0
         35 :  None : None :   0.0
         36 :  None : None :   0.0
         37 :  None : None :   0.0
         38 :  None : None :   0.0
         39 :  None : None :   0.0
         40 :  None : None :   0.0
         41 :  None : None :   0.0
         42 :  None : None :   0.0
         43 :  None : None :   0.0
         44 :  None : None :   0.0
         45 :  None : None :   0.0
         46 :  None : None :   0.0
         47 :  None : None :   0.0
Model 'Ising example as an IP, 47-779/785 QuIPML'

  Variables:
    x : Size=11, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          0 :     0 :   0.0 :     1 : False : False : Binary
          1 :     0 :   0.0 :     1 : False : False : Binary
          2 :     0 :   0.0 :     1 : False : False : Binary
          3 :     0 :   0.0 :     1 : False : False : Binary
          4 :     0 :   0.0 :     1 : False : False : Binary
          5 :     0 :   0.0 :     1 : False : False : Binary
          6 :     0 :   0.0 :     1 : False : False : Binary
          7 :     0 :   0.0 :     1 : False : False : Binary
          8 :     0 :   0.0 :     1 : False : False : Binary
          9 :     0 :   0.0 :     1 : False : False : Binary
         10 :     0 :   1.0 :     1 : False : False : Binary
    y : Size=121, Index={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}*{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        Key      : Lower : Value : Upper : Fixed : Stale : Domain
          (0, 0) :     0 :  None :     1 : False :  True : Binary
          (0, 1) :     0 :  None :     1 : False :  True : Binary
          (0, 2) :     0 :  None :     1 : False :  True : Binary
          (0, 3) :     0 :  None :     1 : False :  True : Binary
          (0, 4) :     0 :  None :     1 : False :  True : Binary
          (0, 5) :     0 :  None :     1 : False :  True : Binary
          (0, 6) :     0 :  None :     1 : False :  True : Binary
          (0, 7) :     0 :  None :     1 : False :  True : Binary
          (0, 8) :     0 :  None :     1 : False :  True : Binary
          (0, 9) :     0 :  None :     1 : False :  True : Binary
         (0, 10) :     0 :  None :     1 : False :  True : Binary
          (1, 0) :     0 :  None :     1 : False :  True : Binary
          (1, 1) :     0 :  None :     1 : False :  True : Binary
          (1, 2) :     0 :  None :     1 : False :  True : Binary
          (1, 3) :     0 :   0.0 :     1 : False : False : Binary
          (1, 4) :     0 :  None :     1 : False :  True : Binary
          (1, 5) :     0 :   0.0 :     1 : False : False : Binary
          (1, 6) :     0 :  None :     1 : False :  True : Binary
          (1, 7) :     0 :  None :     1 : False :  True : Binary
          (1, 8) :     0 :   0.0 :     1 : False : False : Binary
          (1, 9) :     0 :   0.0 :     1 : False : False : Binary
         (1, 10) :     0 :   0.0 :     1 : False : False : Binary
          (2, 0) :     0 :  None :     1 : False :  True : Binary
          (2, 1) :     0 :  None :     1 : False :  True : Binary
          (2, 2) :     0 :  None :     1 : False :  True : Binary
          (2, 3) :     0 :  None :     1 : False :  True : Binary
          (2, 4) :     0 :   0.0 :     1 : False : False : Binary
          (2, 5) :     0 :  None :     1 : False :  True : Binary
          (2, 6) :     0 :   0.0 :     1 : False : False : Binary
          (2, 7) :     0 :   0.0 :     1 : False : False : Binary
          (2, 8) :     0 :   0.0 :     1 : False : False : Binary
          (2, 9) :     0 :   0.0 :     1 : False : False : Binary
         (2, 10) :     0 :   0.0 :     1 : False : False : Binary
          (3, 0) :     0 :   0.0 :     1 : False : False : Binary
          (3, 1) :     0 :  None :     1 : False :  True : Binary
          (3, 2) :     0 :  None :     1 : False :  True : Binary
          (3, 3) :     0 :  None :     1 : False :  True : Binary
          (3, 4) :     0 :  None :     1 : False :  True : Binary
          (3, 5) :     0 :  None :     1 : False :  True : Binary
          (3, 6) :     0 :  None :     1 : False :  True : Binary
          (3, 7) :     0 :  None :     1 : False :  True : Binary
          (3, 8) :     0 :  None :     1 : False :  True : Binary
          (3, 9) :     0 :  None :     1 : False :  True : Binary
         (3, 10) :     0 :  None :     1 : False :  True : Binary
          (4, 0) :     0 :   0.0 :     1 : False : False : Binary
          (4, 1) :     0 :  None :     1 : False :  True : Binary
          (4, 2) :     0 :  None :     1 : False :  True : Binary
          (4, 3) :     0 :   0.0 :     1 : False : False : Binary
          (4, 4) :     0 :  None :     1 : False :  True : Binary
          (4, 5) :     0 :  None :     1 : False :  True : Binary
          (4, 6) :     0 :  None :     1 : False :  True : Binary
          (4, 7) :     0 :  None :     1 : False :  True : Binary
          (4, 8) :     0 :  None :     1 : False :  True : Binary
          (4, 9) :     0 :  None :     1 : False :  True : Binary
         (4, 10) :     0 :  None :     1 : False :  True : Binary
          (5, 0) :     0 :   0.0 :     1 : False : False : Binary
          (5, 1) :     0 :  None :     1 : False :  True : Binary
          (5, 2) :     0 :  None :     1 : False :  True : Binary
          (5, 3) :     0 :   0.0 :     1 : False : False : Binary
          (5, 4) :     0 :   0.0 :     1 : False : False : Binary
          (5, 5) :     0 :  None :     1 : False :  True : Binary
          (5, 6) :     0 :  None :     1 : False :  True : Binary
          (5, 7) :     0 :  None :     1 : False :  True : Binary
          (5, 8) :     0 :  None :     1 : False :  True : Binary
          (5, 9) :     0 :  None :     1 : False :  True : Binary
         (5, 10) :     0 :  None :     1 : False :  True : Binary
          (6, 0) :     0 :  None :     1 : False :  True : Binary
          (6, 1) :     0 :   0.0 :     1 : False : False : Binary
          (6, 2) :     0 :  None :     1 : False :  True : Binary
          (6, 3) :     0 :   0.0 :     1 : False : False : Binary
          (6, 4) :     0 :   0.0 :     1 : False : False : Binary
          (6, 5) :     0 :   0.0 :     1 : False : False : Binary
          (6, 6) :     0 :  None :     1 : False :  True : Binary
          (6, 7) :     0 :   0.0 :     1 : False : False : Binary
          (6, 8) :     0 :   0.0 :     1 : False : False : Binary
          (6, 9) :     0 :   0.0 :     1 : False : False : Binary
         (6, 10) :     0 :   0.0 :     1 : False : False : Binary
          (7, 0) :     0 :   0.0 :     1 : False : False : Binary
          (7, 1) :     0 :  None :     1 : False :  True : Binary
          (7, 2) :     0 :  None :     1 : False :  True : Binary
          (7, 3) :     0 :   0.0 :     1 : False : False : Binary
          (7, 4) :     0 :   0.0 :     1 : False : False : Binary
          (7, 5) :     0 :   0.0 :     1 : False : False : Binary
          (7, 6) :     0 :  None :     1 : False :  True : Binary
          (7, 7) :     0 :  None :     1 : False :  True : Binary
          (7, 8) :     0 :  None :     1 : False :  True : Binary
          (7, 9) :     0 :  None :     1 : False :  True : Binary
         (7, 10) :     0 :  None :     1 : False :  True : Binary
          (8, 0) :     0 :   0.0 :     1 : False : False : Binary
          (8, 1) :     0 :  None :     1 : False :  True : Binary
          (8, 2) :     0 :  None :     1 : False :  True : Binary
          (8, 3) :     0 :   0.0 :     1 : False : False : Binary
          (8, 4) :     0 :   0.0 :     1 : False : False : Binary
          (8, 5) :     0 :   0.0 :     1 : False : False : Binary
          (8, 6) :     0 :  None :     1 : False :  True : Binary
          (8, 7) :     0 :   0.0 :     1 : False : False : Binary
          (8, 8) :     0 :  None :     1 : False :  True : Binary
          (8, 9) :     0 :  None :     1 : False :  True : Binary
         (8, 10) :     0 :  None :     1 : False :  True : Binary
          (9, 0) :     0 :   0.0 :     1 : False : False : Binary
          (9, 1) :     0 :  None :     1 : False :  True : Binary
          (9, 2) :     0 :  None :     1 : False :  True : Binary
          (9, 3) :     0 :   0.0 :     1 : False : False : Binary
          (9, 4) :     0 :   0.0 :     1 : False : False : Binary
          (9, 5) :     0 :   0.0 :     1 : False : False : Binary
          (9, 6) :     0 :  None :     1 : False :  True : Binary
          (9, 7) :     0 :   0.0 :     1 : False : False : Binary
          (9, 8) :     0 :   0.0 :     1 : False : False : Binary
          (9, 9) :     0 :  None :     1 : False :  True : Binary
         (9, 10) :     0 :  None :     1 : False :  True : Binary
         (10, 0) :     0 :   0.0 :     1 : False : False : Binary
         (10, 1) :     0 :  None :     1 : False :  True : Binary
         (10, 2) :     0 :  None :     1 : False :  True : Binary
         (10, 3) :     0 :   0.0 :     1 : False : False : Binary
         (10, 4) :     0 :   0.0 :     1 : False : False : Binary
         (10, 5) :     0 :   0.0 :     1 : False : False : Binary
         (10, 6) :     0 :  None :     1 : False :  True : Binary
         (10, 7) :     0 :   0.0 :     1 : False : False : Binary
         (10, 8) :     0 :   0.0 :     1 : False : False : Binary
         (10, 9) :     0 :   0.0 :     1 : False : False : Binary
        (10, 10) :     0 :  None :     1 : False :  True : Binary

  Objectives:
    objective : Size=1, Index=None, Active=True
        Key  : Active : Value
        None :   True :   5.0

  Constraints:
    c1 : Size=47
        Key : Lower : Body : Upper
          1 :  None : -1.0 :   0.0
          2 :  None : -1.0 :   0.0
          3 :  None : -1.0 :   0.0
          4 :  None : -1.0 :   0.0
          5 :  None : -1.0 :   0.0
          6 :  None : -1.0 :   0.0
          7 :  None : -1.0 :   0.0
          8 :  None : -1.0 :   0.0
          9 :  None : -1.0 :   0.0
         10 :  None : -1.0 :   0.0
         11 :  None : -1.0 :   0.0
         12 :  None : -1.0 :   0.0
         13 :  None : -1.0 :   0.0
         14 :  None : -1.0 :   0.0
         15 :  None : -1.0 :   0.0
         16 :  None : -1.0 :   0.0
         17 :  None : -1.0 :   0.0
         18 :  None : -1.0 :   0.0
         19 :  None : -1.0 :   0.0
         20 :  None : -1.0 :   0.0
         21 :  None : -1.0 :   0.0
         22 :  None :  0.0 :   0.0
         23 :  None :  0.0 :   0.0
         24 :  None :  0.0 :   0.0
         25 :  None :  0.0 :   0.0
         26 :  None :  0.0 :   0.0
         27 :  None :  0.0 :   0.0
         28 :  None :  0.0 :   0.0
         29 :  None : -1.0 :   0.0
         30 :  None : -1.0 :   0.0
         31 :  None : -1.0 :   0.0
         32 :  None : -1.0 :   0.0
         33 :  None :  0.0 :   0.0
         34 :  None : -1.0 :   0.0
         35 :  None : -1.0 :   0.0
         36 :  None : -1.0 :   0.0
         37 :  None : -1.0 :   0.0
         38 :  None : -1.0 :   0.0
         39 :  None : -1.0 :   0.0
         40 :  None :  0.0 :   0.0
         41 :  None : -1.0 :   0.0
         42 :  None : -1.0 :   0.0
         43 :  None : -1.0 :   0.0
         44 :  None : -1.0 :   0.0
         45 :  None : -1.0 :   0.0
         46 :  None :  0.0 :   0.0
         47 :  None : -1.0 :   0.0
    c2 : Size=47
        Key : Lower : Body : Upper
          1 :  None :  0.0 :   0.0
          2 :  None :  0.0 :   0.0
          3 :  None :  0.0 :   0.0
          4 :  None :  0.0 :   0.0
          5 :  None :  0.0 :   0.0
          6 :  None :  0.0 :   0.0
          7 :  None :  0.0 :   0.0
          8 :  None :  0.0 :   0.0
          9 :  None :  0.0 :   0.0
         10 :  None :  0.0 :   0.0
         11 :  None :  0.0 :   0.0
         12 :  None :  0.0 :   0.0
         13 :  None :  0.0 :   0.0
         14 :  None :  0.0 :   0.0
         15 :  None :  0.0 :   0.0
         16 :  None :  0.0 :   0.0
         17 :  None :  0.0 :   0.0
         18 :  None :  0.0 :   0.0
         19 :  None :  0.0 :   0.0
         20 :  None :  0.0 :   0.0
         21 :  None :  0.0 :   0.0
         22 :  None : -1.0 :   0.0
         23 :  None : -1.0 :   0.0
         24 :  None : -1.0 :   0.0
         25 :  None : -1.0 :   0.0
         26 :  None : -1.0 :   0.0
         27 :  None : -1.0 :   0.0
         28 :  None : -1.0 :   0.0
         29 :  None :  0.0 :   0.0
         30 :  None :  0.0 :   0.0
         31 :  None :  0.0 :   0.0
         32 :  None :  0.0 :   0.0
         33 :  None :  0.0 :   0.0
         34 :  None :  0.0 :   0.0
         35 :  None :  0.0 :   0.0
         36 :  None :  0.0 :   0.0
         37 :  None :  0.0 :   0.0
         38 :  None :  0.0 :   0.0
         39 :  None :  0.0 :   0.0
         40 :  None :  0.0 :   0.0
         41 :  None :  0.0 :   0.0
         42 :  None :  0.0 :   0.0
         43 :  None :  0.0 :   0.0
         44 :  None :  0.0 :   0.0
         45 :  None :  0.0 :   0.0
         46 :  None :  0.0 :   0.0
         47 :  None :  0.0 :   0.0
    c3 : Size=47
        Key : Lower : Body : Upper
          1 :  None :  0.0 :   0.0
          2 :  None :  0.0 :   0.0
          3 :  None :  0.0 :   0.0
          4 :  None :  0.0 :   0.0
          5 :  None :  0.0 :   0.0
          6 :  None :  0.0 :   0.0
          7 :  None :  0.0 :   0.0
          8 :  None :  0.0 :   0.0
          9 :  None :  0.0 :   0.0
         10 :  None :  0.0 :   0.0
         11 :  None :  0.0 :   0.0
         12 :  None :  0.0 :   0.0
         13 :  None :  0.0 :   0.0
         14 :  None :  0.0 :   0.0
         15 :  None :  0.0 :   0.0
         16 :  None :  0.0 :   0.0
         17 :  None :  0.0 :   0.0
         18 :  None :  0.0 :   0.0
         19 :  None :  0.0 :   0.0
         20 :  None :  0.0 :   0.0
         21 :  None :  0.0 :   0.0
         22 :  None :  0.0 :   0.0
         23 :  None :  0.0 :   0.0
         24 :  None :  0.0 :   0.0
         25 :  None :  0.0 :   0.0
         26 :  None :  0.0 :   0.0
         27 :  None :  0.0 :   0.0
         28 :  None :  0.0 :   0.0
         29 :  None :  0.0 :   0.0
         30 :  None :  0.0 :   0.0
         31 :  None :  0.0 :   0.0
         32 :  None :  0.0 :   0.0
         33 :  None : -1.0 :   0.0
         34 :  None :  0.0 :   0.0
         35 :  None :  0.0 :   0.0
         36 :  None :  0.0 :   0.0
         37 :  None :  0.0 :   0.0
         38 :  None :  0.0 :   0.0
         39 :  None :  0.0 :   0.0
         40 :  None : -1.0 :   0.0
         41 :  None :  0.0 :   0.0
         42 :  None :  0.0 :   0.0
         43 :  None :  0.0 :   0.0
         44 :  None :  0.0 :   0.0
         45 :  None :  0.0 :   0.0
         46 :  None : -1.0 :   0.0
         47 :  None :  0.0 :   0.0

We observe that the optimal solution of this problem is x10=1,0x_{10} = 1, 0 otherwise, leading to an objective of 5. Notice that this problem has a degenerate optimal solution given that x8=1,0x_8 = 1, 0 otherwise also leads to the same solution.

From QUBO to Ising

QUBO and Ising models describe the same binary search space with different variable conventions. The QUBO form uses variables in {0, 1}, while the Ising form uses spins in {-1, +1}. Moving between them changes the linear terms, quadratic terms, and offset, but not the underlying set of assignments. This equivalence lets us compare exact integer-programming solves with simulated annealing on the same problem.

We can also solve this problem using Simulated Annealing

Image produced in Jupyter
minimum energy: 5.0
Image produced in Jupyter
minimum energy: 5.0
{'beta_range': [np.float64(0.00041111932417553103), np.float64(0.1458971970580513)], 'beta_schedule_type': 'geometric', 'timing': {'preprocessing_ns': 1258757, 'sampling_ns': 174347111, 'postprocessing_ns': 293102}}

From penalty models to graph coloring

The previous examples used penalties to enforce algebraic constraints. Graph coloring uses the same idea with one-hot variables: each vertex must choose exactly one color, and adjacent vertices may not share a color. Violating either rule adds a penalty to the QUBO objective, so low-energy samples correspond to valid colorings when the penalties are large enough.

Let’s solve the graph coloring problem using QUBO.

Vertex kk-coloring of graphs

Given a graph G(V,E)G(V, E), where VV is the set of vertices and EE is the set of edges of GG, and a positive integer kk, we ask if it is possible to assign a color to every vertex from VV, such that adjacent vertices have different colors assigned.

G(V,E)G(V, E) has 12 vertices and 23 edges. We ask if the graph is 3–colorable. Let’s first encode VV and EE using Python data structures:

Note: This tutorial is heavily inspired in D-Wave’s Map coloring of Canada found here.

Image produced in Jupyter

Defining the Binary Quadratic Model (QUBO) directly from the graph coloring penalties we have:

Image produced in Jupyter
minimum energy: 0.0
Image produced in Jupyter
minimum energy: 0.0

With this direct penalty model, every feasible 3-coloring has energy 0. Any sample with positive energy violates at least one exactly-one-color or adjacent-color constraint.

{'x1,0': np.int8(0), 'x1,1': np.int8(1), 'x1,2': np.int8(0), 'x10,0': np.int8(0), 'x10,1': np.int8(1), 'x10,2': np.int8(0), 'x11,0': np.int8(1), 'x11,1': np.int8(0), 'x11,2': np.int8(0), 'x12,0': np.int8(0), 'x12,1': np.int8(0), 'x12,2': np.int8(1), 'x2,0': np.int8(1), 'x2,1': np.int8(0), 'x2,2': np.int8(0), 'x3,0': np.int8(0), 'x3,1': np.int8(0), 'x3,2': np.int8(1), 'x4,0': np.int8(0), 'x4,1': np.int8(0), 'x4,2': np.int8(1), 'x5,0': np.int8(0), 'x5,1': np.int8(1), 'x5,2': np.int8(0), 'x6,0': np.int8(1), 'x6,1': np.int8(0), 'x6,2': np.int8(0), 'x7,0': np.int8(0), 'x7,1': np.int8(0), 'x7,2': np.int8(1), 'x8,0': np.int8(0), 'x8,1': np.int8(1), 'x8,2': np.int8(0), 'x9,0': np.int8(1), 'x9,1': np.int8(0), 'x9,2': np.int8(0)}
Image produced in Jupyter

Practice checkpoints

Use these checkpoints during the workshop to test the main ideas before moving on.

Notebook Cell
best_assignment = (1, 0, 0); energy = 0.0; feasible = true
Notebook Cell
rho = 0.25; best_assignment = (0, 0, 0); energy = 0.5; feasible = false
Notebook Cell
one_hot_groups = x_1_red,x_1_green,x_1_blue | x_2_red,x_2_green,x_2_blue | x_3_red,x_3_green,x_3_blue; edge_conflicts = x_1_red-x_2_red | x_1_green-x_2_green | x_1_blue-x_2_blue | x_2_red-x_3_red | x_2_green-x_3_green | x_2_blue-x_3_blue

The next lecture develops classical augmentation methods. We return to this QUBO for quantum annealing and an optional QAOA comparison in Lecture 4: D-Wave and quantum methods.

Summary

In this notebook we:

  • Defined QUBO and Ising objectives and identified how coefficients encode binary optimization problems.

  • Reformulated constrained binary problems with penalty terms so they can be sampled as unconstrained BQMs.

  • Used dimod and simulated annealing to sample candidate solutions and inspect their energies.

  • Modeled graph coloring directly as a BQM and validated feasible color assignments without a CSP helper package.

Learning objectives met: You practiced reading QUBO/Ising forms, building BQMs, applying penalty reformulations, and checking sampled solutions against the original constraints.

Next steps: Proceed to Notebook 3: GAMA to compare QUBO-style sampling with Graver-basis augmentation for structured integer programs.

Further reading:

Acknowledgments

This notebook was developed by: