-
Notifications
You must be signed in to change notification settings - Fork 3
[Model] NumericalMatchingWithTargetSums #817
Description
Motivation
NUMERICAL MATCHING WITH TARGET SUMS (P144) from Garey & Johnson, A3 SP17. A strongly NP-complete matching problem: given two disjoint sets X and Y each of size m with positive integer sizes, and a target vector <B_1,...,B_m>, can X ∪ Y be partitioned into m pairs (one from each set) such that pair i sums to B_i? This generalizes bipartite perfect matching with a numerical constraint on each matched pair. Notably, the problem becomes polynomial-time solvable when all targets are equal (B_1 = B_2 = ... = B_m), highlighting that the difficulty lies in the heterogeneity of target sums.
Associated rules:
- R82: NUMERICAL 3-DIMENSIONAL MATCHING -> NUMERICAL MATCHING WITH TARGET SUMS (establishes NP-completeness)
Definition
Name: NumericalMatchingWithTargetSums
Reference: Garey & Johnson, Computers and Intractability, A3 SP17
Mathematical definition:
INSTANCE: Disjoint sets X and Y, each containing m elements, a size s(a) in Z^+ for each element a in X union Y, and a target vector <B_1, B_2, ..., B_m> with positive integer entries.
QUESTION: Can X union Y be partitioned into m disjoint sets A_1, A_2, ..., A_m, each containing exactly one element from each of X and Y, such that, for 1 <= i <= m, sum_{a in A_i} s(a) = B_i?
Variables
- Count: m^2 (one binary variable for each possible pairing (x_i, y_j))
- Per-variable domain: binary {0, 1}
- Meaning: Variable z_{i,j} = 1 if and only if x_i and y_j are matched together. The constraints require: (1) each x_i appears in exactly one pair, (2) each y_j appears in exactly one pair, and (3) for each target index k, the pair assigned to target k satisfies s(x_i) + s(y_j) = B_k. The assignment of pairs to targets is part of the decision.
ILP alternative: Binary variables z_{i,j,k} = 1 if x_i and y_j are matched and assigned to target k. Constraints: each x_i in exactly one pair, each y_j in exactly one pair, each target used exactly once, and s(x_i) + s(y_j) = B_k for each selected assignment.
Schema (data type)
Type name: NumericalMatchingWithTargetSums
Variants: none (sizes and targets are positive integers)
| Field | Type | Description |
|---|---|---|
sizes_x |
Vec<i64> |
Sizes s(x_i) for elements of X (length m) |
sizes_y |
Vec<i64> |
Sizes s(y_j) for elements of Y (length m) |
targets |
Vec<i64> |
Target sums <B_1, ..., B_m> (length m) |
Notes:
- This is a feasibility (decision) problem:
Value = Or. - Key getter methods:
num_pairs()(= m = |X| = |Y|).
Complexity
- Decision complexity: NP-complete in the strong sense (Garey & Johnson, 1979; by transformation from NUMERICAL 3-DIMENSIONAL MATCHING). No pseudo-polynomial algorithm exists unless P = NP.
- Best known exact algorithm: O*(2^m) via dynamic programming on subsets, tracking which Y elements have been matched. Brute-force: O(m! * m) by enumerating all m! perfect matchings.
- Concrete complexity expression:
"2^num_pairs"(fordeclare_variants!) - Polynomial special case: Solvable in polynomial time when all targets are equal (B_1 = ... = B_m), reducing to bipartite matching with a single sum constraint.
- References:
- M.R. Garey and D.S. Johnson (1979). Computers and Intractability: A Guide to the Theory of NP-Completeness. W.H. Freeman.
Extra Remark
Full book text:
INSTANCE: Disjoint sets X and Y, each containing m elements, a size s(a) ∈ Z^+ for each element a ∈ X ∪ Y, and a target vector <B_1,B_2,…,B_m> with positive integer entries.
QUESTION: Can X ∪ Y be partitioned into m disjoint sets A_1,A_2,…,A_m, each containing exactly one element from each of X and Y, such that, for 1 ≤ i ≤ m, Σ_{a ∈ A_i} s(a) = B_i?
Reference: Transformation from NUMERICAL 3-DIMENSIONAL MATCHING.
Comment: NP-complete in the strong sense, but solvable in polynomial time if B_1 = B_2 = ··· = B_m.
How to solve
- It can be solved by (existing) bruteforce. (Enumerate all m! matchings of X to Y; for each matching, check if the multiset of pair sums equals the multiset of targets.)
- It can be solved by reducing to integer programming. (ILP with binary variables z_{i,j,k} = 1 if x_i and y_j are matched and assigned to target k; constraints: each x_i in exactly one pair, each y_j in exactly one pair, each target used exactly once, and s(x_i) + s(y_j) = B_k for each selected assignment. Companion rule issue to be filed separately.)
- Other: DP on subsets in O*(2^m); polynomial when all targets are equal.
Example Instance
Input:
X = {x_1, x_2, x_3}, Y = {y_1, y_2, y_3}, m = 3
Sizes: s(x_1) = 1, s(x_2) = 4, s(x_3) = 7, s(y_1) = 2, s(y_2) = 5, s(y_3) = 3
Targets: <B_1, B_2, B_3> = <3, 7, 12>
Valid matching:
- (x_1, y_1) → 1 + 2 = 3 = B_1 ✓
- (x_2, y_3) → 4 + 3 = 7 = B_2 ✓
- (x_3, y_2) → 7 + 5 = 12 = B_3 ✓
All elements used exactly once. Each pair sums to its assigned target. ✓
Answer: YES — this is the unique valid matching (1 out of 6 permutations).
Note: The naive identity matching (x_i ↔ y_i) gives sums {3, 9, 10}, which does not match the targets {3, 7, 12}. The correct matching requires x_2 to pair with y_3 and x_3 to pair with y_2.
Negative example:
X = {x_1, x_2}, Y = {y_1, y_2}, m = 2
Sizes: s(x_1) = 3, s(x_2) = 5, s(y_1) = 4, s(y_2) = 6
Targets: <B_1, B_2> = <8, 8>
Possible pairings:
- (x_1, y_1) and (x_2, y_2): sums 7 and 11 → multiset {7, 11} ≠ {8, 8} ✗
- (x_1, y_2) and (x_2, y_1): sums 9 and 9 → multiset {9, 9} ≠ {8, 8} ✗
Answer: NO — no valid matching exists.
Python validation script
from itertools import permutations
def find_valid_matchings(sizes_x, sizes_y, targets):
m = len(sizes_x)
target_sorted = sorted(targets)
valid = []
for perm in permutations(range(m)):
sums = [sizes_x[i] + sizes_y[perm[i]] for i in range(m)]
if sorted(sums) == target_sorted:
for tperm in permutations(range(m)):
if all(sums[i] == targets[tperm[i]] for i in range(m)):
valid.append((perm, tperm))
break
return valid
# Positive example
sx = [1, 4, 7]; sy = [2, 5, 3]; tgt = [3, 7, 12]
v = find_valid_matchings(sx, sy, tgt)
assert len(v) == 1
assert v[0][0] == (0, 2, 1) # x1↔y1, x2↔y3, x3↔y2
print(f"Positive: {len(v)} valid matching (unique, non-trivial)")
# Negative example
sx_neg = [3, 5]; sy_neg = [4, 6]; tgt_neg = [8, 8]
v_neg = find_valid_matchings(sx_neg, sy_neg, tgt_neg)
assert len(v_neg) == 0
print("Negative: No valid matching (correct)")Metadata
Metadata
Assignees
Labels
Type
Projects
Status