Skip to content

Commit

Permalink
Circuit decomposition for all ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
Wout4 committed Oct 13, 2023
1 parent d603bc0 commit da98d93
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
16 changes: 11 additions & 5 deletions cpmpy/expressions/globalconstraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,21 @@ def decompose(self):
"""
succ = cpm_array(self.args)
n = len(succ)
order = intvar(0,n-1, shape=n)
order = intvar(0,n-1, shape=n, name='order')
constraining = []
constraining += [AllDifferent(succ)] # different successors
constraining += [AllDifferent(order)] # different orders
constraining += [order[n-1] == 0] # symmetry breaking, last one is '0'

defining = [order[0] == succ[0]]
defining += [order[i] == succ[order[i-1]] for i in range(1,n)] # first one is successor of '0', ith one is successor of i-1

a = boolvar(name='a')

defining = [a == ((Minimum(succ) >= 0) & (Maximum(succ) < n))]
for i in range(n):
defining += [(~a).implies(order[i] == 0)] #make order be totally defined
if i == 0:
defining += [a.implies(order[0] == succ[0])]
else:
defining += [a.implies(
order[i] == succ[order[i - 1]])] # first one is successor of '0', ith one is successor of i-1
return constraining, defining

def value(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_globalconstraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ def test_circuit(self):
self.assertTrue(cp.Circuit(x).value())

def test_not_circuit(self):
x = cp.intvar(lb=0, ub=2, shape=3)
x = cp.intvar(lb=-1, ub=5, shape=4)
circuit = cp.Circuit(x)

model = cp.Model([~circuit, x == [1,2,0]])
model = cp.Model([~circuit, x == [1,2,3,0]])
self.assertFalse(model.solve())

model = cp.Model([~circuit])
Expand Down

0 comments on commit da98d93

Please sign in to comment.