Code Monkey home page Code Monkey logo

dwavebinarycsp's People

Contributors

arcondello avatar bellert avatar joelpasvolsky avatar m3ller avatar randomir avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dwavebinarycsp's Issues

"get_penalty_model" in stitch-function does not allow graph size larger than 8

Description
Using dwavebinarycsp.stitch() , if a graph with more than 8 nodes is entered into the function and max_graph_size is extended to 9 an error occurs in the "generate"-function included in the "get_penalty_model"-function. This allows to only build BQMs with small number of connections between variables.

image

Steps To Reproduce
Execute the Jupyter Notebook below using the sample data provided in the repository. As input enter for example:
departure: Hamburg
destination: Kiel
https://github.com/annaehhh/Quantum-Computing/blob/main/ferrylines.ipynb

Expected Behavior
Build a BQM like the method does for smaller graph sizes. (in the above code, enter departure: Hamburg, destination: Bremerhaven)

Environment

  • OS: macOS Big Sur Version 11.4
  • Python version: 3.10.1

Additional Context
Problem seems to be known already, as in the code of generation.py the following comment was found. (Line 178)
image

ImpossibleBQM error

Constraint.from_configurations(frozenset([(0, 1, 1, 0, 1, 0, 1, 0), (0, 1, 0, 0, 0, 1, 0, 1), (0, 1, 0, 1, 0, 1, 1, 0), (0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 0, 1, 1, 0, 0, 0), (0, 1, 0, 1, 1, 0, 1, 0), (0, 0, 0, 0, 1, 0, 1, 0), (0, 0, 1, 0, 0, 1, 0, 1), (0, 0, 0, 1, 0, 0, 1, 0), (0, 1, 0, 1, 1, 0, 0, 1), (0, 1, 1, 0, 0, 1, 1, 0), (0, 1, 0, 0, 1, 0, 0, 1), (1, 0, 0, 1, 0, 0, 0, 1), (0, 0, 0, 0, 0, 1, 0, 0), (1, 0, 0, 0, 1, 0, 0, 0), (1, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 1, 0, 1, 0, 1), (0, 0, 0, 0, 0, 1, 1, 0), (0, 0, 1, 0, 1, 0, 0, 1), (0, 1, 1, 0, 1, 0, 0, 1), (0, 1, 0, 0, 0, 1, 1, 0), (0, 1, 0, 1, 0, 1, 0, 1), (0, 1, 0, 1, 1, 0, 0, 0), (0, 1, 0, 0, 0, 1, 0, 0), (0, 0, 0, 0, 1, 0, 0, 1), (0, 0, 1, 0, 0, 1, 1, 0), (1, 0, 1, 0, 0, 0, 0, 1), (0, 0, 1, 0, 0, 0, 0, 0), (0, 0, 1, 0, 0, 1, 0, 0), (0, 1, 0, 0, 1, 0, 1, 0), (0, 1, 0, 0, 1, 0, 0, 0), (0, 0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 0, 1, 0), (1, 0, 0, 0, 0, 0, 0, 1), (0, 0, 0, 1, 0, 1, 0, 0), (0, 0, 1, 0, 1, 0, 0, 0), (1, 0, 0, 1, 0, 0, 1, 0), (0, 0, 0, 1, 1, 0, 1, 0), (0, 1, 1, 0, 0, 1, 0, 0), (0, 1, 0, 0, 0, 0, 0, 0), (1, 0, 0, 1, 0, 0, 0, 0), (1, 0, 1, 0, 0, 0, 0, 0), (0, 1, 0, 1, 0, 0, 0, 1), (0, 1, 0, 0, 0, 0, 1, 0), (1, 0, 0, 1, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0, 1, 0), (0, 1, 1, 0, 0, 0, 1, 0), (0, 1, 1, 0, 0, 0, 0, 1), (0, 0, 0, 1, 0, 0, 0, 0), (0, 0, 1, 0, 0, 0, 0, 1), (1, 0, 0, 0, 0, 0, 1, 0), (0, 1, 0, 1, 0, 1, 0, 0), (0, 0, 0, 0, 0, 0, 0, 1), (1, 0, 1, 0, 1, 0, 1, 0), (1, 0, 0, 0, 0, 1, 0, 1), (0, 0, 0, 1, 1, 0, 0, 1), (0, 1, 0, 1, 0, 0, 1, 0), (0, 1, 0, 0, 0, 0, 0, 1), (0, 1, 0, 1, 0, 0, 0, 0), (1, 0, 1, 0, 0, 1, 0, 0), (1, 0, 0, 1, 1, 0, 0, 1), (1, 0, 1, 0, 0, 1, 1, 0), (1, 0, 0, 0, 1, 0, 0, 1), (1, 0, 0, 1, 1, 0, 1, 0), (1, 0, 1, 0, 0, 0, 1, 0), (0, 1, 1, 0, 0, 1, 0, 1), (1, 0, 1, 0, 1, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0), (1, 0, 1, 0, 1, 0, 0, 1), (1, 0, 0, 0, 0, 1, 1, 0), (1, 0, 0, 1, 0, 1, 0, 1), (0, 0, 0, 0, 0, 0, 0, 0), (1, 0, 0, 0, 0, 1, 0, 0), (0, 1, 1, 0, 0, 0, 0, 0), (1, 0, 0, 1, 0, 1, 0, 0), (0, 0, 0, 1, 0, 0, 0, 1), (0, 1, 1, 0, 1, 0, 0, 0), (1, 0, 1, 0, 0, 1, 0, 1), (1, 0, 0, 0, 1, 0, 1, 0), (1, 0, 0, 1, 0, 1, 1, 0)]), ('AB0', 'BC0', 'AB1', 'BC1', 'AB2', 'BC2', 'AB3', 'BC3'), Vartype.BINARY, name='Constraint')

This is a reducible constraint, but each of the four components can be mapped to two variables. So this should be able to be stitched to a bqm over 8 variables.

small example requires many many samples for valid solution

The attached program solves the max-cut graph problem by creating a circuit of 14 variables (3 full adders and 1 half adder) to see if a cut of size k exists. For cutSize=2, it takes anywhere from 817K samples to 17M samples to find a valid answer. Given that solving it randomly would require on average only 2^14 ~= 16K samples, this seems excessive.

Expected Behavior
When run as
$ python maxCut_csp.py
you will see output like
cutSize=0
cutSize=1
cutSize=2
nSamples=0, gathering 10000 more
nSamples=10000, gathering 10000 more
nSamples=20000, gathering 10000 more
[...]
nSamples=16990000, gathering 10000 more
nSamples=17000000, gathering 10000 more
valid sample=[('A', 0), ('AB', 1), ('AC', 1), ('B', 1), ('BC', 0), ('BD', 0), ('C', 1), ('C0', 1), ('C1', 0), ('C2', 0), ('CE', 0), ('D', 1), ('DE', 0), ('E', 1), ('S0', 0), ('S1', 0), ('aux0', 1), ('aux1', 1), ('aux10', 1), ('aux11', 1), ('aux12', 1), ('aux13', 1), ('aux2', 0), ('aux3', 0), ('aux4', 1), ('aux5', 1), ('aux6', 1), ('aux7', 1), ('aux8', 1), ('aux9', 0)]
result=[('A', 0), ('AB', 1), ('AC', 1), ('B', 1), ('BC', 0), ('BD', 0), ('C', 1), ('C0', 1), ('C1', 0), ('C2', 0), ('CE', 0), ('D', 1), ('DE', 0), ('E', 1), ('S0', 0), ('S1', 0), ('aux0', 1), ('aux1', 1), ('aux10', 1), ('aux11', 1), ('aux12', 1), ('aux13', 1), ('aux2', 0), ('aux3', 0), ('aux4', 1), ('aux5', 1), ('aux6', 1), ('aux7', 1), ('aux8', 1), ('aux9', 0)]
cutSize=3
nSamples=0, gathering 10000 more
nSamples=10000, gathering 10000 more

Source file
maxCut_csp.py.gz

Environment

  • OS: [macOS HighSierra / Darwin Kernel 17.7.0]
  • Python version: [Anaconda 2.7.14]

Check that stitch cascades through each penaltymodel

Application
The stitch function generates a BQM's penaltymodel by cascading thorough Cache, LP, MIP, and finally, MaxGap.

  • Make a test to verify that this cascade is happening in the expected order.
  • Make sure that the simpler BQMs are being caught earlier in the cascade (i.e. a problem that can be solved with LP should not be able to cascade down to MaxGap).

Proposed Solution
Make problems of varying "difficulty" so that we can observe that the proper penaltymodels are catching said problems. (Ex. LP should be able to catch an OR-gate, but not an XOR-gate. XOR-gate needs auxiliary variables and LP does not handle that, therefore the problem should be passed to MIP.)

Include energy gap in BQM returned by stitch function.

Application
In some scenarios, the BQM that is returned by the stitch function has a small energy gap, which results in multiple low energy states being returned by the solver, reducing the frequency of the lowest energy state being returned.

Proposed Solution
Include the energy gap in the BQM returned by the stitch function.

Alternatives Considered
Automatically optimizing energy gaps is not always trivial or practical.

Additional Context
By including the energy gap in the BQM that is returned from the stitch function it will allow the user to understand the results returned, and why they might be seeing non-optimal results compared to simulated annealing.

Non-zero minimum energy in BQM returned by stitch function

stitch function returns BQM with non-zero energy of ground state for constraint with 1 or 2 variables. In 3 and more variables cases, everything is fine(below I give examples). I'm not sure it's a bug, but zero energy might be useful if somebody combines many different constraints. Then, they may be assured that the final state has zero energy.

csp0 = ConstraintSatisfactionProblem(BINARY)
csp0.add_constraint(lambda a: a, ['a'])

csp1 = ConstraintSatisfactionProblem(BINARY)
csp1.add_constraint(lambda a, b: a == b, ['a', 'b'])

csp2 = ConstraintSatisfactionProblem(BINARY)
csp2.add_constraint(lambda a, b: a & b, ['a', 'b'])

csp3 = ConstraintSatisfactionProblem(BINARY)
csp3.add_constraint(lambda a, b, c: a == b == c, ['a', 'b', 'c'])

csp4 = ConstraintSatisfactionProblem(BINARY)
csp4.add_constraint(lambda a, b, c: a == b == c, ['a', 'b', 'c'])

csp5 = ConstraintSatisfactionProblem(BINARY)
csp5.add_constraint(lambda a, b, c, d: (a & b) & c | d, ['a', 'b', 'c', 'd'])

for csp in [csp0, csp1, csp2, csp3, csp4, csp5]:
    bqm = stitch(csp)
    response = SimulatedAnnealingSampler().sample(bqm, num_reads=100)
    print(sorted(response.data(), key=lambda x: x.energy)[0].energy)

As a result, we get:

-1.0
-1.0
-2.0
0.0
0.0
-2.0000000011677344e-07

Environment

  • OS: Ubuntu 18.04.2 LTS
  • Python version: 3.6.7
  • dwavebinarycsp: 0.0.11

Provide True/False as variable inputs for constraints

Application
Sometimes I want to create a constraint for which I already know the values for some of the variables. I can create the constraint and then immediately fix the variable after, but it might be nice to do it on creation (also can memory/time).

Proposed Solution
I would like to be able to provide boolean values in the place of variables. This would be equivalent to fixing them.

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

def and_gate(in0, in1, out):
    return (in0 and in1) == out

csp.add_constraint(and_gate, ['a', 'b', False])

In this case the constraint would be the identical to

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

def nand(in0, in1):
    return not (in0 and in1)

csp.add_constraint(nand, ['a', 'b'])

Support WCNF

Application
It would be good to also support weighted conjunctive normal form. Requires #73

circuits.py - num_multiplier_bits vs num_multiplicand_bits

In circuits.py, comments say that

    # throughout, we will use the following convention:
    #   i to refer to the bits of the multiplier
    #   j to refer to the bits of the multiplicand

In line 47 we have

num_multiplier_bits = num_multiplicand_bits = nbit

Then in lines 68-69 we have

    for i in range(num_multiplicand_bits):
        for j in range(num_multiplier_bits):

Although num_multiplier_bits and num_multiplicand_bits have the same value, perhaps for clarity this ought to be

    for i in range(num_multiplier_bits):
        for j in range(num_multiplicand_bits):

Or am I missing something?

Thank you.

Change the constraint factories to be functions

Application
Given the 'usual' ways to generate constraints, the pattern

csp.add_constraint(and_gate(['a', 'b', 'c']))

seems more astonishing than

csp.add_constraint(and_gate, ['a', 'b', 'c'])

One anticipated problem is that this would make the constraint factories behave somewhat differently than csp factories.

Clarification about use of configurations within constraints

Description
This is not a bug, but a request of clarification.

We are currently working on a possible extension of the package that changes the internal representation of the Constraint to leverage on And Inverter Graphs (AIG) to leverage on the possibility to easily check equality among constraints and to compose constraints in an efficient manner to build a Constraint Satisfaction Problem (CSP). While doing this, we noticed that the stitch used to build a binary quadratic model (BQM) from binary constraints strongly relies on Constraint internally storing the models (truth assignments) of the constraint itself. Since the objective of this stitcher seems to be the check for satisfiability (SAT) of the CSP we do not understand the reason for storing the models of the constraints. Indeed, for the AIG representation one has to extract the models of the formula itself, and this might be as costly as solving the SAT instance.

Can you explain the reason for this choice?
Is there a way to avoid this and still build the BQM from the CSP?

Any advice would be helpful.

Additional Context
This is part of a collaboration between the group I belong to and D-WAVE team.

cc: @CatherineCMcGeoch @[email protected]
@roveri-marco

Use class vartype for default constraint vartype, not binary

Application & Proposed Solution

When adding a constraint to a CSP class, it would be nice to default to the class's vartype rather than always use binary:

 import dwavebinarycsp

In [2]: import dwavebinarycsp.factories.constraint.gates as gates

In [3]: csp = dwavebinarycsp.ConstraintSatisfactionProblem("SPIN")

In [4]: csp.add_constraint(gates.and_gate(['a', 'b', 'c'], name='AND'))

In [5]: csp.variables
Out[5]:
defaultdict(list,
            {'a': [Constraint.from_configurations(frozenset({(1, 0, 0), (1, 1, 1), (0, 1, 0), (0, 0, 0)}), ('a', 'b', 'c'), Vartype.BINARY, name='AND')],
             'b': [Constraint.from_configurations(frozenset({(1, 0, 0), (1, 1, 1), (0, 1, 0), (0, 0, 0)}), ('a', 'b', 'c'), Vartype.BINARY, name='AND')],
             'c': [Constraint.from_configurations(frozenset({(1, 0, 0), (1, 1, 1), (0, 1, 0), (0, 0, 0)}), ('a', 'b', 'c'), Vartype.BINARY, name='AND')]})

In [6]: bqm = dwavebinarycsp.stitch(csp)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-190cd5489319> in <module>
----> 1 bqm = dwavebinarycsp.stitch(csp)


ValueError: feasible_configurations type must match vartype. feasible_configurations have values {0, 1}, values permitted by vartype are frozenset({1, -1}).

Additional Context

dimod==0.9.13
dwave-cloud-client==0.8.4
dwave-greedy==0.1.2
dwave-hybrid==0.6.1
dwave-inspector==0.2.5
dwave-neal==0.5.7
dwave-networkx==0.8.8
dwave-ocean-sdk==3.3.0
dwave-qbsolv==0.3.2
dwave-system==1.4.0
dwave-tabu==0.3.1
dwavebinarycsp==0.1.2
penaltymodel==0.16.4
penaltymodel-cache==0.4.3
penaltymodel-lp==0.1.4
penaltymodel-mip==0.2.4

"dwavebinarycsp.stitch" raises AttributeError

Description
When I use dwavebinarycsp in following code as Steps To Reproduce,
I faced "AttibuteError: 'NoneType' object has no attibute 'classical_gap'".

I suspect that this should be modified as ImpossibleBQM or anything else.

Steps To Reproduce

import dwavebinarycsp

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.SPIN)

csp.add_constraint(lambda a, b, c, d, e, f, g, h, i: a * b * c * d * e * f * g * h * i == 1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
csp.add_constraint(lambda a, b, c, d, e, f, g, h, i: a + b + c + d + e + f + g + h * i < 2,  ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])

bqm = dwavebinarycsp.stitch(csp, max_graph_size=9)

print(bqm)

This example code raises following error message.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-12-3030c141576b> in <module>
      4 csp.add_constraint(lambda a, b, c, d, e, f, g, h, i: a + b + c + d + e + f + g + h * i < 2,  ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
      5 
----> 6 bqm = dwavebinarycsp.stitch(csp, max_graph_size=9)
      7 
      8 print(bqm)

~/.pyenv/versions/3.6.10/lib/python3.6/site-packages/dwavebinarycsp/compilers/stitcher.py in stitch(csp, min_classical_gap, max_graph_size)
    185                 continue
    186 
--> 187             if pmodel.classical_gap >= min_classical_gap:
    188                 break
    189 

AttributeError: 'NoneType' object has no attribute 'classical_gap'

Expected Behavior
I think that "ImpossibleBQM: No penalty model can be build for constraint xxx." should be raised as written in dwavebinarycsp/compilers/stitcher.py line 195, though the example above raised AttributeError.

Environment

  • OS: MacOS Catalina 10.15.6
  • Python version: 3.6.0

Additional Context
In my understanding, this issue may be related to following files:

  • "stitch" (in dwavebinarycsp/compilers/stitcher.py)
  • "get_penalty_model" (in penaltymodel_mip/penaltymodel/mip/interface.py)
  • "generate_bqm" (in penaltymodel_mip/penaltymodel/mip/generation.py)

Original Implementation:
pm.get_penalty_model(spec) on "stitch" line 182 raises pm.ImpossiblePenaltyModel if the calculation is fault.
Many such cases are caught by try-except on line 183 and continued, so these are caught by else block on line 193 and line 195 raises ImpossibleBQM Error finally.

Problem:
If the max_graph_size is larger than 8 (max_graph_size=9 on my code example),
the graph instance G in "stitch" line 173 becomes larger than 8.

It seems that this max_graph_size isn't inputted into max_decision parameter on "generate_bqm" appropriately.
And especially if max_graph_size is larger than 8, this unexpected problem occurs.

On "get_penalty_model" line 56-60, no input parameter is assigned for max_decision for "generate_bqm".
This lead to the ValueError on "generate_bqm" line 111 because len(decision)=9 is larger than max_decision=8 (8 is default value on generate_bqm).

Question:
I wonder whether this behavior is bug or not...
I would appreciate it if you would give me some advice.

SoftConstraint subclass of Constraint

Application
Right now all the constraints are soft constraints when converted to BQMs. It would be good though to formalize that and allow users to specify the strength of their constraints

ImpossibleBQM raised for possible BQM

Description
The following:

import dwavebinarycsp

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)
def sum_to_one(*args):
    return sum(args) == 1
nvar = 7
ngroup = 4
for igroup in range(ngroup):
    vars = [igroup*nvar + i for i in range(nvar)]
    csp.add_constraint(sum_to_one, vars)
bqm = dwavebinarycsp.stitch(csp)

produces:

ImpossibleBQM: No penalty model can be build for constraint Constraint.from_configurations(frozenset({(0, 0, 1, 0, 0, 0, 0), 
(0, 0, 0, 0, 0, 1, 0), (0, 1, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1), (0, 0, 0, 0, 1, 0, 0), (1, 0, 0, 0, 0, 0, 0), (0, 0, 0, 
1, 0, 0, 0)}), (0, 1, 2, 3, 4, 5, 6), Vartype.BINARY, name='Constraint')  

This is misleading because the BQM should be possible.

Note that adding max_graph_size=9 to stitch() resolves the error.

Steps To Reproduce
See above.

Expected Behavior
Error message indicating that the problem is related to graph size as opposed to the BQM being impossible.

Environment

  • dwavebinarycsp version 0.1.2
  • python 3.7

dwavebinarycsp ignoring min_classical_gap

Description

Setting a min_classical_gap to a non-default values does not affect the BQM from stich()

Steps To Reproduce
In [3]: csp_eq = dwavebinarycsp.ConstraintSatisfactionProblem('SPIN')
In [4]: csp_ne = dwavebinarycsp.ConstraintSatisfactionProblem('SPIN')
In [5]: csp_eq.add_constraint(operator.eq, ['a', 'b'])
In [6]: csp_ne.add_constraint(operator.ne, ['a', 'c'])
In [7]: bqm_eq = dwavebinarycsp.stitch(csp_eq, min_classical_gap=2.0, max_graph_size=2)
In [8]: bqm_ne = dwavebinarycsp.stitch(csp_ne, min_classical_gap=4.0, max_graph_size=2)
In [9]: bqm_ne
Out[9]: BinaryQuadraticModel({'a': 0.0, 'c': 0.0}, {('a', 'c'): 1.0}, 1.0, Vartype.SPIN)
In [10]: bqm_eq
Out[10]: BinaryQuadraticModel({'a': 0, 'b': 0}, {('a', 'b'): -1}, 0.0, Vartype.SPIN)

Difference between energies for gap of 2 is correct:

In [11]: bqm_eq.energy({'a': -1, 'b':-1})
Out[11]: -1.0
In [12]: bqm_eq.energy({'a': -1, 'b':1})
Out[12]: 1.0

Difference between energies for gap of 4 is incorrect (still 2):

In [14]: bqm_ne.energy({'a': -1, 'c':1})
Out[14]: 0.0
In [15]: bqm_ne.energy({'a': -1, 'c':-1})
Out[15]: 2.0

Expected Behavior
A different BQM based on the gap set

Environment

  • OS: Windows 10
  • Python version: 3.something_supported

Additional Context
Add any other background information about the problem.

Add a Circuit Repo for benchmarking circuit-satisfiability problems

Application

We need to make a collection of input repositories and generators, for future benchmarking purposes. The inputs need to be represented as QUBOs in general (pre-embedded) form.
They can have fixed structures, but should also have a random component for generating random weights; the user should be able to specify subsets of inputs that are wanted.

Proposed Solution

Build a standard circuit testbed for generating instances for Circuit-Satisfiability. This generator takes user specified parameters of which circuits to use, plus a description of a way to generate the (output) bitstrings that are part of the problem.

There is a standard circuit testbed set known as ISCAS-85 available in many places on the internet. It contains the c-series and the 74-series (these are combinational circuits):

http://web.eecs.umich.edu/%7Ejhayes/iscas.restore/benchmark.html

Alternatives Considered

Considered just storing a fixed bunch of QUBOs, but it needs to have a generator capable of generating one circuit with multiple bitstrings to create multiple QUBOs. The user should be able to specify which subset of circuits they want to use, and how many bitstrings to generate per circuit.

Additional Context

Early steps in building a larger repo of input generators for future benchmarking purposes.

Disable or warn if variables are given in dict for added constraints

I understand that it's nice to have flexibility, and it's a user mistake, but this is a hole I likely will not be the only one to fall into:

import dwavebinarycsp
csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)
csp.add_constraint([(0, 0, 0), (0, 1, 0), (1, 0, 0), (1, 1, 1)], {'a', 'b', 'c'})
csp.constraints
Out[89]: [Constraint.from_configurations(frozenset([(1, 0, 0), (0, 1, 0), (0, 0, 0), (1, 1, 1)]), ('a', 'c', 'b'), Vartype.BINARY, name='Constraint')]

It's very easy to inadvertently use {} instead of [] or () and how often will someone really want random assignment of variables on a constraint?

CSP --> BQM not returning valid transformation

The following map coloring does not work

HALF CANADA 4 COLORS

import dwavebinarycsp
from dwave.system.samplers import DWaveSampler
from dwave.system.composites import EmbeddingComposite
import operator

provinces = ['AB', 'BC', 'NT', 'SK', 'YT']
neighbors = [('AB', 'BC'), ('AB', 'NT'), ('AB', 'SK'), ('BC', 'NT'), ('BC', 'YT'), ('NT', 'SK'), ('NT', 'YT')]

one_color_configurations = {(0, 0, 0, 1), (0, 0, 1, 0), (0, 1, 0, 0), (1, 0, 0, 0)}

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

for province in provinces:
vars = [province+'0', province+'1', province+'2', province+'3']
csp.add_constraint(one_color_configurations, vars)

for neighbor in neighbors:
v, u = neighbor
for i in range(4):
var = [v+str(i), u+str(i)]
csp.add_constraint(operator.ne, var)

bqm = dwavebinarycsp.stitch(csp)

sampler = EmbeddingComposite(DWaveSampler())
response = sampler.sample(bqm, chain_strength=3, num_reads=1000)

Document factories

The csp/constraint factories need complete docstrings and to be included in the online documentation.

version problem?

after pip install dwave_ocean_sdk

import dwavebinarycsp as dbc

and_gate = dbc.factories.and_gate(["x1", "x2", "y1"])
and_csp = dbc.ConstraintSatisfactionProblem('BINARY')
and_csp.add_constraint(and_gate)
and_bqm = dbc.stitch(and_csp)
and_bqm.remove_offset()

and_bqm

gives the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-18-2e6477ca2e14> in <module>()
      4 and_csp = dbc.ConstraintSatisfactionProblem('BINARY')
      5 and_csp.add_constraint(and_gate)
----> 6 and_bqm = dbc.stitch(and_csp)
      7 and_bqm.remove_offset()
      8 

/opt/conda/lib/python3.6/site-packages/dwavebinarycsp/compilers/stitcher.py in stitch(csp, min_classical_gap, max_graph_size)
    167                 continue
    168 
--> 169             if pmodel.classical_gap >= min_classical_gap:
    170                 break
    171 

AttributeError: 'NoneType' object has no attribute 'classical_gap'

`load_cnf` returns no constraints from CNF file

Description
I'm reading a CNF file with load_cnf, but the function returns a csp object without constraints

Steps To Reproduce

In [1]: import dwavebinarycsp as dbcsp

In [2]: cnf_file = "nae3sat_ratio210_size10_inst1.cnf"

In [3]: with open(cnf_file, 'r') as fp:
   ...:     csp = dbcsp.cnf.load_cnf(fp)
   ...:     

In [4]: csp.constraints
Out[4]: []

nae3sat_ratio210_size10_inst1.cnf.zip

Expected Behavior
I would expect the csp object to have the constraints in the file

Environment

  • OS: Mac OS 10.14.6
  • Python version: 3.7.0
  • dwavebinarycsp version: 0.1.1

Lots of new warnings on an old problem

Description
I reran dwavebinarycsp.stitch() on my old multi-gate circuit for the first time in months.

def logic_circuit(a, b, c, d, z):
    not1 = not b
    or2 = b or c
    and3 = a and not1
    or4 = or2 or d
    and5 = and3 and or4
    not6 = not or4
    or7 = and5 or not6
    return (z == or7)

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)
csp.add_constraint(logic_circuit, ['a', 'b', 'c', 'd', 'z'])

It now outputs a lot of warnings:

>>> bqm = dwavebinarycsp.stitch(csp)
...scipy\optimize\_linprog_util.py:763: OptimizeWarning: A_eq does not appear to be of full row rank. To improve performance, check the problem formulation for redundant equality constraints.
  warn(redundancy_warning, OptimizeWarning)
...penaltymodel\lp\generation.py:150: OptimizeWarning: Solving system with option 'cholesky':True failed. It is normal for this to happen occasionally, especially as the solution is approached. However, if you see this frequently, consider setting option 'cholesky' to False.
  A_ub=unnoted_matrix, b_ub=unnoted_bound, bounds=bounds)
...penaltymodel\lp\generation.py:150: OptimizeWarning: Solving system with option 'sym_pos':True failed. It is normal for this to happen occasionally, especially as the solution is approached. However, if you see this frequently, consider setting option 'sym_pos' to False.
  A_ub=unnoted_matrix, b_ub=unnoted_bound, bounds=bounds)
...scipy\optimize\_linprog_ip.py:110: LinAlgWarning: Ill-conditioned matrix (rcond=3.36003e-18): result may not be accurate.
  return sp.linalg.solve(M, r, sym_pos=sym_pos)

Steps To Reproduce
Given above

Expected Behavior
Previously it ran silently. It can be a good thing to present users with more information about the construction of the BQM and its limitations, but I am concerned that this will be more scary than useful for most new users. They won't know what to make of these warnings and might conclude that the method failed or gave bad results.

Maybe any non-critical warnings can be suppressed unless the user turns on a verbose flag?

Environment

  • OS: Windows
  • Python version: 3.6

Additional Context
dwave-ocean-sdk==1.5.0
dwavebinarycsp==0.0.12
penaltymodel==0.16.2
penaltymodel-cache==0.4.0
penaltymodel-lp==0.1.0
penaltymodel-mip==0.2.1

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.