Git Product home page Git Product logo

qubovert's Introduction

qubovert

The one-stop package for formulating, simulating, and solving problems in boolean and spin form.

master branch

GitHub Actions CI Documentation Status Code Coverage Code Quality

dev branch

GitHub Actions CI Documentation Status Code Coverage

pypi distribution

pypi dist pypi dist downloads

Please see the Repository and Docs. For examples/tutorials, see the notebooks.

For the stable release (same version as the master branch):

pip install qubovert

Or to install from source:

git clone https://github.com/jtiosue/qubovert.git
cd qubovert
pip install -e .

Then you can use it in Python versions 3.6 and above with

import qubovert as qv

Note that to install from source on Windows you will need Microsoft Visual C++ Build Tools 14 installed.

Here we show an example of formulating a pseudo-boolean objective function. We can also make spin objective functions (Hamiltonians) in a very similar manner. See the notebooks for examples.

from qubovert import boolean_var

N = 10

# create the variables
x = {i: boolean_var('x(%d)' % i) for i in range(N)}

# minimize \sum_{i=0}^{N-2} (1-2x_{i}) x_{i+1}
model = 0
for i in range(N-1):
    model += (1 - 2 * x[i]) * x[i+1]

# subject to the constraint that x_1 equals the XOR of x_3 and x_5
# enforce with a penalty factor of 3
model.add_constraint_eq_XOR(x[1], x[3], x[5], lam=3)

# subject to the constraints that the sum of all variables is less than 4
# enforce with a penalty factor of 5
model.add_constraint_lt_zero(sum(x.values()) - 4, lam=5)

Next we will show multiple ways to solve the model.

Before using the bruteforce solver, always check that model.num_binary_variables is relatively small!

model_solution = model.solve_bruteforce()
print("Variable assignment:", model_solution)
print("Model value:", model.value(model_solution))
print("Constraints satisfied?", model.is_solution_valid(model_solution))

Please see the definition of PUBO in the next section. We will anneal the PUBO.

from qubovert.sim import anneal_pubo

res = anneal_pubo(model, num_anneals=10)
model_solution = res.best.state

print("Variable assignment:", model_solution)
print("Model value:", res.best.value)
print("Constraints satisfied?", model.is_solution_valid(model_solution))

D-Wave's simulated annealer cannot anneal PUBOs as we did above. Instead the model must be reduced to a QUBO. See the next section for definitions of QUBO and PUBO.

from neal import SimulatedAnnealingSampler

# Get the QUBO form of the model
qubo = model.to_qubo()

# D-Wave accept QUBOs in a different format than qubovert's format
# to get the qubo in this form, use the .Q property
dwave_qubo = qubo.Q

# solve with D-Wave
res = SimulatedAnnealingSampler().sample_qubo(dwave_qubo, num_reads=10)
qubo_solution = res.first.sample

# convert the qubo solution back to the solution to the model
model_solution = model.convert_solution(qubo_solution)

print("Variable assignment:", model_solution)
print("Model value:", model.value(model_solution))
print("Constraints satisfied?", model.is_solution_valid(model_solution))

qubovert defines, among many others, the following objects.

  • QUBO: Quadratic Unconstrained Boolean Optimization (qubovert.QUBO)
  • QUSO: Quadratic Unconstrained Spin Optimization (qubovert.QUSO)
  • PUBO: Polynomial Unconstrained Boolean Optimization (qubovert.PUBO)
  • PUSO: Polynomial Unconstrained Spin Optimization (qubovert.PUSO)
  • PCBO: Polynomial Constrained Boolean Optimization (qubovert.PCBO)
  • PCSO: Polynomial Constrained Spin Optimization (qubovert.PCSO)

Each of the objects has many methods and arbitary arithmetic defined; see the docstrings of each object and the notebooks for more info. A boolean optimization model is one whose variables can be assigned to be either 0 or 1, while a spin optimization model is one whose variables can be assigned to be either 1 or -1. The qubovert.boolean_var(name) function will create a PCBO representing the boolean variable with name name. Similarly, the qubovert.spin_var(name) function will create a PCSO representing the spin variable with name name.

There are many utilities in the utils library that can be helpful. Some examples of utility functions are listed here.

  • qubovert.utils.solve_pubo_bruteforce, solve a PUBO by iterating through all possible solutions.
  • qubovert.utils.solve_puso_bruteforce, solve a PUSO by iterating through all possible solutions.
  • qubovert.utils.pubo_to_puso, convert a PUBO to a PUSO.
  • qubovert.utils.puso_to_pubo, convert a PUSO to a PUBO.
  • qubovert.utils.pubo_value, determine the value that a PUBO takes with a particular solution mapping.
  • qubovert.utils.puso_value, determine the value that a PUSO takes with a particular solution mapping.
  • qubovert.utils.approximate_pubo_extrema, approximate the minimum and maximum values that a PUBO can take; the true extrema will lie within these bounds.
  • qubovert.utils.approximate_puso_extrema, approximate the minimum and maximum values that a PUSO can take; the true extrema will lie within these bounds.
  • qubovert.utils.subgraph, create the subgraph of a model that only contains certain given variables.
  • qubovert.utils.subvalue, create the submodel of a model with certain values of the model replaced with values.
  • qubovert.utils.normalize, normalize a model such that its coefficients have a maximum absolute magnitude.

See qubovert.utils.__all__ for more. Please note that all conversions between boolean and spin map {0, 1} to/from {1, -1} in that order! This is the convention that qubovert uses everywhere.

The PCBO and PCSO objects have constraint methods; for example, the .add_constraint_le_zero method will enforce that an expression is less than or equal to zero by adding a penalty to the model whenever it does not. The PCBO object also has constraint methods for satisfiability expressions; for example, the .add_constraint_OR will enforce that the OR of the given boolean expression evaluates to True by adding a penalty to the model whenever it does not. See the docstrings and notebooks for more info.

For more utilities on satisfiability expressions, qubovert also has a sat library; see qubovert.sat.__all__. Consider the following 3-SAT example. We have variables x0, x1, x2, x3, labeled by 0, 1, 2, 3. We can create an expression C that evaluates to 1 whenever the 3-SAT conditions are satisfied.

from qubovert.sat import AND, NOT, OR

C = AND(OR(0, 1, 2), OR(NOT(0), 2, NOT(3)), OR(NOT(1), NOT(2), 3))

# C = 1 for a satisfying assignment, C = 0 otherwise
# So minimizing -C will solve it.
P = -C
solution = P.solve_bruteforce()

See the notebooks for many fully worked out examples. Here we will just show some basic and brief examples.

The basic building block of a binary optimization model is a Python dictionary. The keys of the dictionary are tuples of variable names, and the values are their corresponding coefficients. For example, in the below code block, model1, model2, and model3 are equivalent.

from qubovert import boolean_var, PUBO

x0, x1, x2 = boolean_var('x0'), boolean_var('x1'), boolean_var('x2')

model1 = -1 + x0 + 2 * x0 * x1 - 3 * x0 * x2 + x0 * x1 * x2
model2 = {(): -1, ('x0',): 1, ('x0', 'x1'): 2, ('x0', 'x2'): -3, ('x0', 'x1', 'x2'): 1}
model3 = PUBO(model2)

Similarly, in the below code block, model1, model2, and model3 are equivalent.

from qubovert import spin_var, PUSO

z0, z1, z2 = spin_var('z0'), spin_var('z1'), spin_var('z2')

model1 = -1 + z0 + 2 * z0 * z1 - 3 * z0 * z2 + z0 * z1 * z2
model2 = {(): -1, ('z0',): 1, ('z0', 'z1'): 2, ('z0', 'z2'): -3, ('z0', 'z1', 'z2'): 1}
model3 = PUSO(model2)

Let's take the same model from above (ie define model = model1.copy()). Suppose we want to find the ground state of the model subject to the constraints that the sum of the variables is negative and that the product of z0 and z1 is 1. We have to enforce these constraints with a penalty called lam. For now, let's set it as a Symbol that we can adjust later.

from sympy import Symbol

lam = Symbol('lam')
model.add_constraint_lt_zero(z0 + z1 + z2, lam=lam)
model.add_constraint_eq_zero(z0 * z1 - 1, lam=lam)

Note that constraint methods can also be strung together if you want. So we could have written this as

model.add_constraint_lt_zero(
    z0 + z1 + z2, lam=lam
).add_constraint_eq_zero(
    z0 * z1 - 1, lam=lam
)

The first thing you notice if you print(model.variables) is that there are now new variables in the model called '__a0' and '__a1'. These are auxillary or ancilla variables that are needed to enforce the constraints. The next thing to notice if you print(model.degree) is that the model is a polynomial of degree 3. Many solvers (for example D-Wave's solvers) only solve degree 2 models. To get a QUBO or QUSO (which are degree two modes) from model, simply call the .to_qubo or .to_quso methods, which will reduce the degree to 2 by introducing more variables.

qubo = model.to_qubo()
quso = model.to_quso()

Next let's solve the QUBO and/or QUSO formulations. First we have to substitute a value in for our placeholder symbol lam that is used to enforce the constraints. We'll just use lam=3 for now.

qubo = qubo.subs({lam: 3})
quso = quso.subs({lam: 3})

Here we will use D-Wave's simulated annealer.

from neal import SimulatedAnnealingSampler

# D-Wave represents QUBOs a little differently than qubovert does.
# to get D-Wave's form, use the .Q property
dwave_qubo = qubo.Q

# D-Wave represents QUSOs a little differently than qubovert does.
# to get D-Wave's form, use the .h property the linear terms and the
# .J property for the quadratic terms
dwave_linear, dwave_quadratic = quso.h, quso.J

# call dwave
qubo_res = SimulatedAnnealingSampler().sample_qubo(dwave_qubo)
quso_res = SimulatedAnnealingSampler().sample_ising(dwave_linear, dwave_quadratic)

qubo_solution = qubo_res.first.sample
quso_solution = quso_res.first.sample

Now we have to convert the solution in terms of the QUBO/QUSO variables back to a solution in terms of the original variables. We can then check if the proposed solution satisfies all of the constraints!

converted_qubo_solution = model.convert_solution(qubo_solution)
print(model.is_solution_valid(converted_qubo_solution))

converted_quso_solution = model.convert_solution(quso_solution)
print(model.is_solution_valid(converted_quso_solution))

One of the goals of qubovert is to become a large collection of problems mapped to QUBO and QUSO forms in order to aid the recent increase in study of these problems due to quantum optimization algorithms. Use Python's help function! I have very descriptive doc strings on all the functions and classes. Please see the notebooks for a few more examples as well.

See the following Set Cover example.

from qubovert.problems import SetCover
from any_module import qubo_solver
# or you can use my bruteforce solver...
# from qubovert.utils import solve_qubo_bruteforce as qubo_solver

U = {"a", "b", "c", "d"}
V = [{"a", "b"}, {"a", "c"}, {"c", "d"}]

problem = SetCover(U, V)
Q = problem.to_qubo()

obj, sol = qubo_solver(Q)

solution = problem.convert_solution(sol)

print(solution)
# {0, 2}
print(problem.is_solution_valid(solution))
# will print True, since V[0] + V[2] covers all of U
print(obj == len(solution))
# will print True

To use the QUSO formulation instead:

from qubovert.problems import SetCover
from any_module import quso_solver
# or you can use my bruteforce solver...
# from qubovert.utils import solve_quso_bruteforce as quso_solver

U = {"a", "b", "c", "d"}
V = [{"a", "b"}, {"a", "c"}, {"c", "d"}]

problem = SetCover(U, V)
L = problem.to_quso()

obj, sol = quso_solver(L)

solution = problem.convert_solution(sol)

print(solution)
# {0, 2}
print(problem.is_solution_valid(solution))
# will print True, since V[0] + V[2] covers all of U
print(obj == len(solution))
# will print True

To see problem specifics, run

help(qubovert.problems.SetCover)
help(qubovert.problems.VertexCover)
# etc

https://raw.githubusercontent.com/jtiosue/qubovert/master/assets/qvfire.png

qubovert's People

Contributors

jtiosue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

qubovert's Issues

PUBO to QUBO: The ancillary parameter

If I try to transform a PUBO
x(0) x(1) x(2)

to QUBO, it will give me
6 x(3) + 2 x(0) x(1) - 4 x(0) x(3) - 4 x(1) x(3) + x(2) x(3)

QUESTION 1 = BUT should not the QUBO formula instead be:
-( 6 x(3) + 2 x(0) x(1) - 4 x(0) x(3) - 4 x(1) x(3) ) + x(2) x(3)
and obviously x(3) = x(0) x(1)

QUESTION 2 =
In this case I am assuming that the ancillary*** x(3) was based on
x(3) = x(0) x(1)

the new cost function is this
x(2) x(3)

and the constraint to make QUBO work is
6 x(3) + 2 x(0) x(1) - 4 x(0) x(3) - 4 x(1) x(3)

Is there a way to get the ancillary*** formula?

Process 3SAT problems in CNF form

Hello

Is there any interface where a 3SAT problem in a DIMACS CNF file format can be read from a file and automatically be parsed in PCBO().add_constraint ?

for example, can a CNF formula (x0 or x1 or ~x2)(x1 or x2 or x3) be represented as [0,1,-2][1,2,3] ?

TypeError: loop of ufunc does not support argument 0 of type Float which has no callable log10 method

Error obtained in the line:
res = qv.sim.anneal_qubo(Q, num_anneals=1000)

parameter Q that is being passed is:

{(0, 0): -6,
(0, 54): 12,
(0, 57): 12,
(0, 60): 12,
(1, 1): -6,
(1, 55): 12,
(1, 58): 12,
(1, 61): 12,
(2, 2): -6,
(2, 56): 12,
(2, 59): 12,
(2, 62): 12,
(3, 3): -73,
(3, 4): 48,
(3, 5): 12,
(3, 6): 24,
(3, 7): 12,
(3, 8): 24,
(3, 27): 12,
(3, 45): 12,
(3, 46): 24,
(3, 47): 48,
(3, 54): -24,
(4, 4): -122,
(4, 5): 24,
(4, 6): 48,
(4, 7): 24,
(4, 8): 48,
(4, 27): 24,
(4, 45): 24,
(4, 46): 48,
(4, 47): 96,
(4, 54): -48,
(5, 5): -73,
(5, 6): 48,
(5, 7): 12,
(5, 8): 24,
(5, 28): 12,
(5, 45): 12,
(5, 46): 24,
(5, 47): 48,
(5, 55): -24,
(6, 6): -122,
(6, 7): 24,
(6, 8): 48,
(6, 28): 24,
(6, 45): 24,
(6, 46): 48,
(6, 47): 96,
(6, 55): -48,
(7, 7): -73,
(7, 8): 48,
(7, 29): 12,
(7, 45): 12,
(7, 46): 24,
(7, 47): 48,
(7, 56): -24,
(8, 8): -122,
(8, 29): 24,
(8, 45): 24,
(8, 46): 48,
(8, 47): 96,
(8, 56): -48,
(9, 9): -73,
(9, 10): 48,
(9, 11): 96,
(9, 12): 12,
(9, 13): 24,
(9, 14): 48,
(9, 15): 12,
(9, 16): 24,
(9, 17): 48,
(9, 30): 12,
(9, 31): 24,
(9, 48): 12,
(9, 49): 24,
(9, 50): 48,
(9, 57): -48,
(10, 10): -122,
(10, 11): 192,
(10, 12): 24,
(10, 13): 48,
(10, 14): 96,
(10, 15): 24,
(10, 16): 48,
(10, 17): 96,
(10, 30): 24,
(10, 31): 48,
(10, 48): 24,
(10, 49): 48,
(10, 50): 96,
(10, 57): -96,
(11, 11): -148,
(11, 12): 48,
(11, 13): 96,
(11, 14): 192,
(11, 15): 48,
(11, 16): 96,
(11, 17): 192,
(11, 30): 48,
(11, 31): 96,
(11, 48): 48,
(11, 49): 96,
(11, 50): 192,
(11, 57): -192,
(12, 12): -73,
(12, 13): 48,
(12, 14): 96,
(12, 15): 12,
(12, 16): 24,
(12, 17): 48,
(12, 32): 12,
(12, 33): 24,
(12, 48): 12,
(12, 49): 24,
(12, 50): 48,
(12, 58): -48,
(13, 13): -122,
(13, 14): 192,
(13, 15): 24,
(13, 16): 48,
(13, 17): 96,
(13, 32): 24,
(13, 33): 48,
(13, 48): 24,
(13, 49): 48,
(13, 50): 96,
(13, 58): -96,
(14, 14): -148,
(14, 15): 48,
(14, 16): 96,
(14, 17): 192,
(14, 32): 48,
(14, 33): 96,
(14, 48): 48,
(14, 49): 96,
(14, 50): 192,
(14, 58): -192,
(15, 15): -73,
(15, 16): 48,
(15, 17): 96,
(15, 34): 12,
(15, 35): 24,
(15, 48): 12,
(15, 49): 24,
(15, 50): 48,
(15, 59): -48,
(16, 16): -122,
(16, 17): 192,
(16, 34): 24,
(16, 35): 48,
(16, 48): 24,
(16, 49): 48,
(16, 50): 96,
(16, 59): -96,
(17, 17): -148,
(17, 34): 48,
(17, 35): 96,
(17, 48): 48,
(17, 49): 96,
(17, 50): 192,
(17, 59): -192,
(18, 18): -73,
(18, 19): 48,
(18, 20): 96,
(18, 21): 12,
(18, 22): 24,
(18, 23): 48,
(18, 24): 12,
(18, 25): 24,
(18, 26): 48,
(18, 36): 12,
(18, 37): 24,
(18, 38): 48,
(18, 51): 12,
(18, 52): 24,
(18, 53): 48,
(18, 60): -60,
(19, 19): -122,
(19, 20): 192,
(19, 21): 24,
(19, 22): 48,
(19, 23): 96,
(19, 24): 24,
(19, 25): 48,
(19, 26): 96,
(19, 36): 24,
(19, 37): 48,
(19, 38): 96,
(19, 51): 24,
(19, 52): 48,
(19, 53): 96,
(19, 60): -120,
(20, 20): -148,
(20, 21): 48,
(20, 22): 96,
(20, 23): 192,
(20, 24): 48,
(20, 25): 96,
(20, 26): 192,
(20, 36): 48,
(20, 37): 96,
(20, 38): 192,
(20, 51): 48,
(20, 52): 96,
(20, 53): 192,
(20, 60): -240,
(21, 21): -73,
(21, 22): 48,
(21, 23): 96,
(21, 24): 12,
(21, 25): 24,
(21, 26): 48,
(21, 39): 12,
(21, 40): 24,
(21, 41): 48,
(21, 51): 12,
(21, 52): 24,
(21, 53): 48,
(21, 61): -60,
(22, 22): -122,
(22, 23): 192,
(22, 24): 24,
(22, 25): 48,
(22, 26): 96,
(22, 39): 24,
(22, 40): 48,
(22, 41): 96,
(22, 51): 24,
(22, 52): 48,
(22, 53): 96,
(22, 61): -120,
(23, 23): -148,
(23, 24): 48,
(23, 25): 96,
(23, 26): 192,
(23, 39): 48,
(23, 40): 96,
(23, 41): 192,
(23, 51): 48,
(23, 52): 96,
(23, 53): 192,
(23, 61): -240,
(24, 24): -73,
(24, 25): 48,
(24, 26): 96,
(24, 42): 12,
(24, 43): 24,
(24, 44): 48,
(24, 51): 12,
(24, 52): 24,
(24, 53): 48,
(24, 62): -60,
(25, 25): -122,
(25, 26): 192,
(25, 42): 24,
(25, 43): 48,
(25, 44): 96,
(25, 51): 24,
(25, 52): 48,
(25, 53): 96,
(25, 62): -120,
(26, 26): -148,
(26, 42): 48,
(26, 43): 96,
(26, 44): 192,
(26, 51): 48,
(26, 52): 96,
(26, 53): 192,
(26, 62): -240,
(27, 27): 6,
(27, 54): -24,
(28, 28): 6,
(28, 55): -24,
(29, 29): 6,
(29, 56): -24,
(30, 30): 6,
(30, 31): 24,
(30, 57): -48,
(31, 31): 24,
(31, 57): -96,
(32, 32): 6,
(32, 33): 24,
(32, 58): -48,
(33, 33): 24,
(33, 58): -96,
(34, 34): 6,
(34, 35): 24,
(34, 59): -48,
(35, 35): 24,
(35, 59): -96,
(36, 36): 6,
(36, 37): 24,
(36, 38): 48,
(36, 60): -60,
(37, 37): 24,
(37, 38): 96,
(37, 60): -120,
(38, 38): 96,
(38, 60): -240,
(39, 39): 6,
(39, 40): 24,
(39, 41): 48,
(39, 61): -60,
(40, 40): 24,
(40, 41): 96,
(40, 61): -120,
(41, 41): 96,
(41, 61): -240,
(42, 42): 6,
(42, 43): 24,
(42, 44): 48,
(42, 62): -60,
(43, 43): 24,
(43, 44): 96,
(43, 62): -120,
(44, 44): 96,
(44, 62): -240,
(45, 45): -78,
(45, 46): 24,
(45, 47): 48,
(46, 46): -144,
(46, 47): 96,
(47, 47): -240,
(48, 48): -78,
(48, 49): 24,
(48, 50): 48,
(49, 49): -144,
(49, 50): 96,
(50, 50): -240,
(51, 51): -78,
(51, 52): 24,
(51, 53): 48,
(52, 52): -144,
(52, 53): 96,
(53, 53): -240,
(54, 54): 18,
(54, 57): 12,
(54, 60): 12,
(55, 55): 18,
(55, 58): 12,
(55, 61): 12,
(56, 56): 18,
(56, 59): 12,
(56, 62): 12,
(57, 57): 90,
(57, 60): 12,
(58, 58): 90,
(58, 61): 12,
(59, 59): 90,
(59, 62): 12,
(60, 60): 144,
(61, 61): 144,
(62, 62): 144}

Any help here is appreciated.

Suspected bug in subgraph()

I think I've found a bug in subgraph(). Here's a minimal reproducer:

from qubovert.utils import subgraph
import numpy as np

G = {(2,): 1, (2, 3): -1}
connections={3: 1}
qubo = subgraph(G, [2], connections)
print(qubo)

The output I get is:

{(2,): 1.0}

Whereas the output I expect is:

{}

I suspect the issue is at the end of subgraph(), where we have:

        if value:
            D[key] = value

which I think should be changed to something like this:

        if value:
            D[key] = value
        else:
            try:
                del D[key]
            except KeyError:
                pass

To deal with the situation in which substituting the values from connections causes value to be zero. I've assumed here that it is possible that key is not in D, since I see that just above there is D.get(key, 0) which was designed to work in that scenario. But if that's impossible then we could get rid of the try/except.

`.normalize()` fails for an empty QUBO

In [38]: qv.QUBO({}).normalize()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-38-18b132978996> in <module>
----> 1 qv.QUBO({}).normalize()

~.../python3.8/site-packages/qubovert/utils/_dict_arithmetic.py in normalize(self, value)
    781 
    782         """
--> 783         mult = value / max(abs(v) for v in self.values())
    784         for k in self:
    785             self[k] *= mult

ValueError: max() arg is an empty sequence

@jtiosue I'm happy to make a pull request so that this case would simply return the empty QUBO (or PCBO or whatever) back unchanged.

Dealing with "force fields"

I'm working on a PUBO encoding for polymer lattice models and I need a way to include interactions between nearest-neighbour monomers. The Hamiltonian to be minimised takes the form

$$ H_{targer} = \sum_E \sum_{i=1}^D \sum_{j=1}^D (1-e^E) q_i^{E-} q_j^{E+} \epsilon_{ij} $$

Where $e^E=1$ if the E-th edge is active, in which case I don't count the interaction (because the monomers are bounded). $q_i^{E-}, q_j^{E+}$ indicate which monomers sit at the sides of the edge. $D$ is the number of monomer species. $\epsilon_{ij}$ is the interaction coefficient between a monomer of type i and type j.
In the HP model, $\epsilon = \begin{pmatrix} -1&0 \ 0&0 \end{pmatrix}$.
Now, I'm trying to translate this formula into code, but I'm having trouble accounting for the interaction coefficients.
I came up with the following
H_t = sum(sum(sum((1-e[E])*qi[pm[E][0]+i]*qi[pm[E][1]+j]*epsilon[D*i+j] for j in range(D)) for i in range(D)) for E in range(edges))

The problem is that by using this, the $\epsilon_{ij}$ coefficients become part of my state and I don't want that.
Thanks for the help

Missing attribute after using multiprocessing Queue

When using multiprocessing's Queue class to share PCBO instances between processes, the attribute _degree is missing after extraction. A minimal example:

import multiprocessing as mp
from qubovert import PCBO

def produce(queue):
    pcbo = PCBO({(0,1): -5})
    queue.put(pcbo)

def consume(queue):
    pcbo = queue.get() # AttributeError occurs here
    print(pcbo)

if __name__ == '__main__':
    queue = mp.Queue()

    process1 = mp.Process(target=produce, args=(queue,))
    process2 = mp.Process(target=consume, args=(queue,))

    process1.start()
    process2.start()

    process1.join()
    process2.join()

Executing this produces the following error:

Process Process-2:
Traceback (most recent call last):
  File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
  File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "test.py", line 9, in consume
    pcbo = queue.get()
  File "/usr/lib/python3.8/multiprocessing/queues.py", line 116, in get
    return _ForkingPickler.loads(res)
  File "/home/muecke/.local/lib/python3.8/site-packages/qubovert/utils/_bo_parentclass.py", line 219, in __setitem__
    super().__setitem__(key, value)
  File "/home/muecke/.local/lib/python3.8/site-packages/qubovert/utils/_pubomatrix.py", line 384, in __setitem__
    self._degree = max(self._degree, len(k))
AttributeError: 'PCBO' object has no attribute '_degree'

OS: Linux (Manjaro, kernel 5.7.9-1-MANJARO)
Python version 3.8.3, qubovert version 1.2.3

Thanks in advance!

Extending DictArithmetic to include vector non_zero_min??

Hiya,

I have a constrained binary optimization which involved site selection based on a distance matrix.

  • my space is
    • X = vector of binary decision variables
    • site in solution?
  • and my objective is of the form
    • model = sum(non_zero_min(dist_matrix @ X[i] , axis=1) )
    • sum of travel to each nearest site in solution
  • with constraint
    • model.add_constraint_eq _zero(sum(x.values()) - num_selected_sites ,lam=10)
    • limited number of sites

The space is very large so Gurobi and other exact solvers fail on the hardware we have available. So, heuristics are the only way forward.

I could extend the DictArithmetic class to include "non_zero_min" but would this work. Or, is there and easier way forward that I'm not seeing.

thanks

qubovert doesn't install with python 3.10 on macOS 13.2.1

$ python3.10 -m venv qubovert-venv
$ source qubovert-venv/bin/activate
(qubovert-venv)$ python3.10 -c "import platform; print(platform.mac_ver())"
('13.2.1', ('', '', ''), 'x86_64')
(qubovert-venv)$ python3.10 -m pip install qubovert
Here is the generated output: Collecting qubovert Using cached qubovert-1.2.5.tar.gz (97 kB) Preparing metadata (setup.py) ... done Collecting numpy Using cached numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl (19.8 MB) Installing collected packages: numpy, qubovert WARNING: The scripts f2py, f2py3 and f2py3.10 are installed in '/Library/Frameworks/Python.framework/Versions/3.10/bin' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. DEPRECATION: qubovert is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559 Running setup.py install for qubovert ... error error: subprocess-exited-with-error

× Running setup.py install for qubovert did not run successfully.
│ exit code: 1
╰─> [235 lines of output]
running install
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_py
creating build
creating build/lib.macosx-10.9-universal2-cpython-310
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_pcso.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_pcbo.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_version.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_qubo.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_quso.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_pubo.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
copying qubovert/_puso.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems
copying qubovert/problems/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems
copying qubovert/problems/_problem_parentclass.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems
copying qubovert/problems/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_normalize.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_qubomatrix.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_pusomatrix.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_ordering_key.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_info.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_approximate_extrema.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_conversions.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_warn.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_qusomatrix.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_pubomatrix.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_solve_bruteforce.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_binary_helpers.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_values.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_subgraph.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_dict_arithmetic.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
copying qubovert/utils/_bo_parentclass.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/utils
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/sat
copying qubovert/sat/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sat
copying qubovert/sat/_satisfiability.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sat
copying qubovert/sat/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sat
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
copying qubovert/sim/_anneal_temperature_range.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
copying qubovert/sim/_anneal.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
copying qubovert/sim/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
copying qubovert/sim/_anneal_results.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
copying qubovert/sim/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np
copying qubovert/problems/np/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np
copying qubovert/problems/np/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/benchmarking
copying qubovert/problems/benchmarking/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/benchmarking
copying qubovert/problems/benchmarking/_alternating_sectors_chain.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/benchmarking
copying qubovert/problems/benchmarking/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/benchmarking
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/cycles
copying qubovert/problems/np/cycles/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/cycles
copying qubovert/problems/np/cycles/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/cycles
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/tree
copying qubovert/problems/np/tree/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/tree
copying qubovert/problems/np/tree/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/tree
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/bilp
copying qubovert/problems/np/bilp/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/bilp
copying qubovert/problems/np/bilp/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/bilp
copying qubovert/problems/np/bilp/_bilp.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/bilp
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/coloring
copying qubovert/problems/np/coloring/_job_sequencing.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/coloring
copying qubovert/problems/np/coloring/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/coloring
copying qubovert/problems/np/coloring/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/coloring
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/partitioning
copying qubovert/problems/np/partitioning/_graph_partitioning.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/partitioning
copying qubovert/problems/np/partitioning/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/partitioning
copying qubovert/problems/np/partitioning/_number_partitioning.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/partitioning
copying qubovert/problems/np/partitioning/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/partitioning
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/covering
copying qubovert/problems/np/covering/_set_cover.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/covering
copying qubovert/problems/np/covering/_vertex_cover.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/covering
copying qubovert/problems/np/covering/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/covering
copying qubovert/problems/np/covering/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/covering
creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/packing
copying qubovert/problems/np/packing/init.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/packing
copying qubovert/problems/np/packing/main.py -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/problems/np/packing
running egg_info
writing qubovert.egg-info/PKG-INFO
writing dependency_links to qubovert.egg-info/dependency_links.txt
writing requirements to qubovert.egg-info/requires.txt
writing top-level names to qubovert.egg-info/top_level.txt
reading manifest file 'qubovert.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
adding license file 'LICENSE'
writing manifest file 'qubovert.egg-info/SOURCES.txt'
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/setuptools/command/build_py.py:202: SetuptoolsDeprecationWarning: Installing 'qubovert.sim.src' as data is deprecated, please list it in packages.
!!

      ############################
      # Package would be ignored #
      ############################
      Python recognizes 'qubovert.sim.src' as an importable package,
      but it is not listed in the `packages` configuration of setuptools.
  
      'qubovert.sim.src' has been automatically added to the distribution only
      because it may contain data files, but this behavior is likely to change
      in future versions of setuptools (and therefore is considered deprecated).
  
      Please make sure that 'qubovert.sim.src' is included as a package by using
      the `packages` configuration field or the proper discovery methods
      (for example by using `find_namespace_packages(...)`/`find_namespace:`
      instead of `find_packages(...)`/`find:`).
  
      You can read more about "package discovery" and "data files" on setuptools
      documentation page.
  
  
  !!
  
    check.warn(importable)
  copying qubovert/sim/_canneal.c -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim
  creating build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/anneal_puso.c -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/anneal_puso.h -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/anneal_quso.c -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/anneal_quso.h -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/pcg_basic.c -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/pcg_basic.h -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/random.c -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  copying qubovert/sim/src/random.h -> build/lib.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  running build_ext
  building 'qubovert.sim._canneal' extension
  creating build/temp.macosx-10.9-universal2-cpython-310
  creating build/temp.macosx-10.9-universal2-cpython-310/qubovert
  creating build/temp.macosx-10.9-universal2-cpython-310/qubovert/sim
  creating build/temp.macosx-10.9-universal2-cpython-310/qubovert/sim/src
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -arch arm64 -arch x86_64 -g -I./qubovert/sim/src/ -I/Library/Frameworks/Python.framework/Versions/3.10/include/python3.10 -c ./qubovert/sim/_canneal.c -o build/temp.macosx-10.9-universal2-cpython-310/./qubovert/sim/_canneal.o
  In file included from ./qubovert/sim/_canneal.c:1:
  In file included from /Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h:11:
  In file included from /Library/Developer/CommandLineTools/usr/lib/clang/11.0.3/include/limits.h:21:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/limits.h:63:
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:807:2: error: Unsupported architecture
  #error Unsupported architecture
   ^
  In file included from ./qubovert/sim/_canneal.c:1:
  In file included from /Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h:11:
  In file included from /Library/Developer/CommandLineTools/usr/lib/clang/11.0.3/include/limits.h:21:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/limits.h:64:
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/limits.h:8:2: error: architecture not supported
  #error architecture not supported
   ^
  In file included from ./qubovert/sim/_canneal.c:1:
  In file included from /Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h:25:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:64:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:71:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_types.h:27:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:33:
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/_types.h:34:2: error: architecture not supported
  #error architecture not supported
   ^
  In file included from ./qubovert/sim/_canneal.c:1:
  In file included from /Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h:25:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:64:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:71:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_types.h:27:
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:55:9: error: unknown type name '__int64_t'
  typedef __int64_t       __darwin_blkcnt_t;      /* total blocks */
          ^
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:56:9: error: unknown type name '__int32_t'; did you mean '__int128_t'?
  typedef __int32_t       __darwin_blksize_t;     /* preferred block size */
          ^
  note: '__int128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:57:9: error: unknown type name '__int32_t'; did you mean '__int128_t'?
  typedef __int32_t       __darwin_dev_t;         /* dev_t */
          ^
  note: '__int128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:60:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
  typedef __uint32_t      __darwin_gid_t;         /* [???] process and group IDs */
          ^
  note: '__uint128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:61:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
  typedef __uint32_t      __darwin_id_t;          /* [XSI] pid_t, uid_t, or gid_t*/
          ^
  note: '__uint128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:62:9: error: unknown type name '__uint64_t'
  typedef __uint64_t      __darwin_ino64_t;       /* [???] Used for 64 bit inodes */
          ^
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:68:9: error: unknown type name '__darwin_natural_t'
  typedef __darwin_natural_t __darwin_mach_port_name_t; /* Used by mach */
          ^
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:70:9: error: unknown type name '__uint16_t'; did you mean '__uint128_t'?
  typedef __uint16_t      __darwin_mode_t;        /* [???] Some file attributes */
          ^
  note: '__uint128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:71:9: error: unknown type name '__int64_t'
  typedef __int64_t       __darwin_off_t;         /* [???] Used for file sizes */
          ^
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:72:9: error: unknown type name '__int32_t'; did you mean '__int128_t'?
  typedef __int32_t       __darwin_pid_t;         /* [???] process and group IDs */
          ^
  note: '__int128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:73:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
  typedef __uint32_t      __darwin_sigset_t;      /* [???] signal set */
          ^
  note: '__uint128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:74:9: error: unknown type name '__int32_t'; did you mean '__int128_t'?
  typedef __int32_t       __darwin_suseconds_t;   /* [???] microseconds */
          ^
  note: '__int128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:75:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
  typedef __uint32_t      __darwin_uid_t;         /* [???] user IDs */
          ^
  note: '__uint128_t' declared here
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:76:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
  typedef __uint32_t      __darwin_useconds_t;    /* [???] microseconds */
          ^
  note: '__uint128_t' declared here
  In file included from ./qubovert/sim/_canneal.c:1:
  In file included from /Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h:25:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:64:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:71:
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_types.h:43:9: error: unknown type name '__uint32_t'; did you mean '__uint128_t'?
  typedef __uint32_t      __darwin_wctype_t;
          ^
  note: '__uint128_t' declared here
  In file included from ./qubovert/sim/_canneal.c:1:
  In file included from /Library/Frameworks/Python.framework/Versions/3.10/include/python3.10/Python.h:25:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:64:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:75:
  In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types/_va_list.h:31:
  /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/types.h:37:2: error: architecture not supported
  #error architecture not supported
   ^
  fatal error: too many errors emitted, stopping now [-ferror-limit=]
  20 errors generated.
  error: command '/usr/bin/clang' failed with exit code 1
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> qubovert

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

Suspected bug: cannot pickle and unpickle

Pickling and then unpickling a PUSO currently fails even for a trivial PUSO, see below. This severely limits the ability to use qubovert since one cannot save and load problems...

Minimal example:

import pickle
pickle.loads(pickle.dumps(PUSO({('a',):1})))

which gives an AttributeError that is tracked back to the degree property:

    380 k = self.__class__.squash_key(key)
    381 if value:
--> 382     self._degree = max(self._degree, len(k))
    383     for i in filter(lambda x: x not in self._variables, k):
    384         self._variables.add(i)

AttributeError: 'PUSO' object has no attribute '_degree'

During the calculation, a variable is missing

>>> import qubovert as qv
>>> x = qv.PUBO({('a[0][0][0]', 'q_w_L[1][0][0]'): 4.0, ('a[0][0][0]', 'q_w_L[0][0][0]'): 2.0, ('a[0][0][0]',): -2.0, ('q_w_L[1][0][0]',): -2.0, ('q_w_L[0][0][0]',): -1.0, (): 1.0})
>>> x * x
{('q_w_L[0][0][0]', 'q_w_L[1][0][0]'): 4.0, ('q_w_L[0][0][0]',): -1.0, (): 1.0}

why is 'a[0][0][0]' missing?

Pairs

I have my cost function:

C: qubovert.PUBO = x[0] * x[1] * x[2]

I am testing Qubovert to force pair 0, 2 rather than the default it does, which is 0, 1

so I call it as following:

Q: qubovert.utils._qubomatrix.QUBOMatrix = C.to_qubo(pairs=((0, 2),))

However, I still get the following answer:

6 x(3) + 2 x(0) x(1) - 4 x(0) x(3) - 4 x(1) x(3) + x(2) x(3)

I was expecting last part to be x(1) x(3).

Am I doing something wrong? Full code follows:

import qubovert
from qubovert import boolean_var
from sympy import Symbol

x = [boolean_var("x%d" % i) for i in range(5)]
C: qubovert.PUBO = x[0] * x[1] * x[2]
lam = Symbol("lam", real=True, positive=True)
Q: qubovert.utils._qubomatrix.QUBOMatrix = C.to_qubo(pairs=((0, 2),))

print("num PUBO variables", C.num_binary_variables)
print("num QUBO variables", Q.num_binary_variables)
print(Q.pretty_str())

two simulated annealer give different solution

Hello Joseph,

I got different solutions from qubovert.sim.anneal_qubo() and neal.SimulatedAnnealingSampler().sample_qubo().

Here is my code if you would like to run it on your side:
simulated_annealer.zip
Please let me know if you have some explanations, or there is something wrong in my code.

Also I am confused of SimulatedAnnealingSampler().sample_qubo(dwave_qubo, num_runs=10)
I looked into cource code of neal: I did not find any statement about num_runs. Could you please clarify it with me?

Thank you,
Yuxin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.