Skip to content

Commit

Permalink
Merge pull request #36 from arcondello/bugfix_8_variable_constraint
Browse files Browse the repository at this point in the history
Bugfix: 8 variable constraint
  • Loading branch information
arcondello committed May 15, 2018
2 parents 21ba919 + 40e2bcb commit d4d131f
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 4 deletions.
9 changes: 8 additions & 1 deletion dwavebinarycsp/compilers/stitcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ def aux_factory():
for const in csp.constraints:
configurations = const.configurations

if len(const.variables) > max_graph_size:
msg = ("The given csp contains a constraint {const} with {num_var} variables. "
"This cannot be mapped to a graph with {max_graph_size} nodes. "
"Consider checking whether your constraint is irreducible."
"").format(const=const, num_var=len(const.variables), max_graph_size=max_graph_size)
raise ImpossibleBQM(msg)

pmodel = None

if len(const) == 0:
Expand All @@ -149,7 +156,7 @@ def aux_factory():
# if configurations in penalty_models:
# raise NotImplementedError

for G in iter_complete_graphs(const.variables, max_graph_size, aux):
for G in iter_complete_graphs(const.variables, max_graph_size + 1, aux):

# construct a specification
spec = pm.Specification(
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
penaltymodel[all]==0.14.0
networkx==2.0
dimod==0.6.7
dimod==0.6.8
six==1.11.0

coverage
Expand Down
34 changes: 33 additions & 1 deletion tests/test_int_stitcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_csp_one_xor(self):
# if classical gap is less than 2
self.assertTrue(csp.check(sample))

def test_csp_one_xor(self):
def test_csp_one_xor_impossible(self):

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

Expand All @@ -105,3 +105,35 @@ def test_csp_one_xor(self):

with self.assertRaises(pm.ImpossiblePenaltyModel):
bqm = dwavebinarycsp.stitch(csp, max_graph_size=3)

def test_eight_variable_constraint_smoketest(self):

csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

variables = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

# this is reducible but for our purposes here that's fine
def f(a, b, c, d, e, f, g, h):
if a and b:
return False
if c and d:
return False
if e and f:
return False
return not (g and h)

csp.add_constraint(f, variables)

bqm = dwavebinarycsp.stitch(csp)

resp = dimod.ExactSolver().sample(bqm)

ground_energy = min(resp.data_vectors['energy'])

for sample, energy in resp.data(['sample', 'energy']):
if energy == ground_energy:
self.assertTrue(csp.check(sample))
else:
if abs(energy - ground_energy) < 2:
# if classical gap is less than 2
self.assertTrue(csp.check(sample))
26 changes: 25 additions & 1 deletion tests/test_stitcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from dwavebinarycsp.compilers import stitcher


class TestStitch(unittest.TestCase):
class TestIterCompleteGraph(unittest.TestCase):
def test_iter_complete_graph_simple(self):

graphs = list(stitcher.iter_complete_graphs(4, 6))
Expand Down Expand Up @@ -76,6 +76,19 @@ def factory():

self.assertEqual(set(G2), {'a', 'b', 'aux0', 'aux1'})

def test_start_8_stop_8(self):
variables = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

# should produce at least one graph
G, = stitcher.iter_complete_graphs(variables, 9)

G0 = nx.complete_graph(variables)

self.assertEqual(G.nodes, G0.nodes)
self.assertEqual(G.edges, G0.edges)


class TestStitch(unittest.TestCase):
def test__bqm_from_1sat(self):
const = dwavebinarycsp.Constraint.from_configurations([(0,)], ['a'], dwavebinarycsp.BINARY)

Expand Down Expand Up @@ -192,6 +205,17 @@ def test_stitch_max_graph_size_is_1(self):
with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM):
bqm = dwavebinarycsp.stitch(csp, max_graph_size=1)

def test_stitch_constraint_too_large(self):
csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)

def f(*args):
return all(args)

csp.add_constraint(f, list('abcdefghijk')) # 11 variables

with self.assertRaises(dwavebinarycsp.exceptions.ImpossibleBQM):
bqm = dwavebinarycsp.stitch(csp, max_graph_size=8)


def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
Expand Down

0 comments on commit d4d131f

Please sign in to comment.