Skip to content

Add DisjointCover node#557

Draft
smharwood wants to merge 13 commits into
dwavesystems:mainfrom
smharwood:feature/disjoint-node
Draft

Add DisjointCover node#557
smharwood wants to merge 13 commits into
dwavesystems:mainfrom
smharwood:feature/disjoint-node

Conversation

@smharwood

Copy link
Copy Markdown
Contributor

Adds a logical-valued node that determines whether its predecessors are a disjoint cover of a given primary set

Reference issue

What does this implement/fix?

Implements a DisjointCover node, enabling construction of DisjointLists via List symbols

AI Generation Disclosure

No AI tools used

@arcondello arcondello left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple random aesthetic comments

Comment thread dwave/optimization/include/dwave-optimization/nodes/set_routines.hpp Outdated
Comment thread dwave/optimization/symbols/set_routines.pyx Outdated
@arcondello arcondello added the enhancement New feature or request label Jun 1, 2026
@smharwood
smharwood marked this pull request as ready for review June 1, 2026 17:39
@arcondello

Copy link
Copy Markdown
Member

Misc unhelpful notes from trying to find precedent for similar functions in other libraries we like to follow.

Maybe we want IsPartition? Though I am a little nervous about clashing with np.partition() which is a totally different thing. And I think a partition might actually requires that each subset be non-empty.

@arcondello

Copy link
Copy Markdown
Member

I think if we were writing this from scratch we'd want an API like

from dwave.optimization import Model, is_disjoint_cover

model = Model()

universe = 100
num_lists = 10

lists = [model.list(universe, min_size=0) for _ in range(num_lists)]

model.add_constraint(is_disjoint_cover(lists))

open to suggestions

@smharwood

Copy link
Copy Markdown
Contributor Author

Misc unhelpful notes from trying to find precedent for similar functions in other libraries we like to follow.

Maybe we want IsPartition? Though I am a little nervous about clashing with np.partition() which is a totally different thing. And I think a partition might actually requires that each subset be non-empty.

I'm convinced adding "Is" is the way to go. At least, its consistent with "IsIn", and its probably not a good idea to go the other way and rename that to just "In"

@smharwood

smharwood commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

I think if we were writing this from scratch we'd want an API like

from dwave.optimization import Model, is_disjoint_cover

model = Model()

universe = 100
num_lists = 10

lists = [model.list(universe, min_size=0) for _ in range(num_lists)]

model.add_constraint(is_disjoint_cover(lists))

open to suggestions

So, add is_disjoint_cover to the mathematical namespace?

Comment thread dwave/optimization/mathematical.py Outdated
return concatenate(arrays, 1)


def is_disjoint_cover(primary_set_size: int, subsets: list[ArraySymbol]) -> IsDisjointCover:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't tell if I should future-proof this interface and make the primary set an ArraySymbol? (but for now, just assert its a constant)

@smharwood
smharwood force-pushed the feature/disjoint-node branch from c9f86e2 to eed5066 Compare July 16, 2026 00:07
and include set_routines.hpp to nodes.hpp
@smharwood

smharwood commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

I think if we were writing this from scratch we'd want an API like

from dwave.optimization import Model, is_disjoint_cover

model = Model()

universe = 100
num_lists = 10

lists = [model.list(universe, min_size=0) for _ in range(num_lists)]

model.add_constraint(is_disjoint_cover(lists))

open to suggestions

Finally revisiting this and I think I understand your suggestion: you would prefer to remove the "primary set size" argument to is_disjoint_cover and just infer it from the (common) max value of the lists?

I'm tempted to agree - this would address my other comment about future-proofing the interface. Just wondering if we wouldn't want the flexibility in the future.

@arcondello

Copy link
Copy Markdown
Member

Can make it a kwarg with primary_set_size=None where None means infer from inputs?

@smharwood
smharwood marked this pull request as draft July 16, 2026 18:37
Allow primary_set_size to be optional on python side
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants