Skip to content

[Model] NumericalMatchingWithTargetSums #817

@isPANN

Description

@isPANN

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" (for declare_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

No one assigned

    Labels

    GoodAn issue passed all checks.modelA model problem to be implemented.

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions