Skip to content

Consider adding a kwarg to skip checking whether a discrete constraint is valid #1364

@arcondello

Description

@arcondello

When one calls CQM.add_discrete() we check that the given constraint is a valid discrete constraint - that is that it doesn't overlap with any other discrete constraint. The check happens in one of two places:

for v in variables:
if v in self.variables:
# it already exists, let's make sure it's not already used
if any(v in self.constraints[label].lhs.variables for label in self.discrete):
raise ValueError(f"variable {v!r} is already used in a discrete variable")
if self.vartype(v) is not Vartype.BINARY:
raise ValueError(f"variable {v!r} has already been added but is not BINARY")
or
for v, bias in qm.iter_linear():
if v in self.variables:
# it already exists, let's make sure it's not already used
if any(v in self.constraints[label].lhs.variables for label in self.discrete):
raise ValueError(f"variable {v!r} is already used in a discrete variable")
if self.vartype(v) is not Vartype.BINARY:
raise ValueError(f"variable {v!r} has already been added but is not BINARY")
elif not vartype(v) is Vartype.BINARY:
raise ValueError("all variables in a discrete constraint must be binary, "
f"{v!r} is {vartype(v).name!r}")
# we could maybe do a scaling, but let's just keep it simple for now
if bias != 1:
raise ValueError("all linear biases in a discrete constraint must be 1")

This is quite a slow check, and many users therefore bypass it by adding the discrete constraint as a constraint and then marking it as discrete.

label = cqm.add_constraint(x + y + z == 1)
cqm.constraints[label].lhs.mark_discrete()

This bypasses the check. Luckily, dwave-preprocessing handles fixing overlapping discrete constraints, so I think it's fairly safe to make the bypass more "legal", albeit with caveats explained clearly in the docs.

Therefore, we should/could consider adding a keyword argument skip_check defaulting to False that would allow users to bypass the check. If they then create overlapping discrete constraints they will be removed by presolve later.

cqm.add_discrete(["a", "b", "c"], skip_check=True)

For experience users who promise to construct the model without overlapping discrete constraints by default this is likely to be useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions