Skip to content

onedimensional: add full-bin, perfect-pair, dominant-set, lift, bin-shrinking and dominated-bin-type reductions - #597

Merged
fontanf merged 1 commit into
masterfrom
onedimensional-reduction-dominant-sets-shrink-dominated-bins
Sep 28, 2026
Merged

fontanf merged 1 commit into
masterfrom
onedimensional-reduction-dominant-sets-shrink-dominated-bins

Conversation

@fontanf

@fontanf fontanf commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Extends the onedimensional Reduction with dedicated-bin reservations and ports of the remaining rectangle operations.

New operations

  • Full-bin items / perfect pairs (reduce_full_bin_items, reduce_perfect_pairs): an item type whose length matches the bin, or a pair whose lengths sum to it, gets a dedicated bin.

  • Dominant sets (reduce_dominant_sets): the Martello-Toth reduction procedure. For each free item, by decreasing length, look for a set of items that fits beside it and dominates every other such set, and reserve them a dedicated bin, until nothing more can be fixed. Three rules are checked:

    • everything fitting beside the item fits together;
    • a single item exactly fills the space, or no two items fit together beside it;
    • a pair, when no three items fit together beside it and no two items longer than the second one do either.

    Identical dedicated bins are grouped into a single record.

  • Item length lifting (lift_item_lengths): grow a single-copy item type's length to close a margin no combination of the other items could ever fill. The bound uses subsetsumsolver::dynamic_programming_bellman_word_ram (new dependency, pinned to the commit with the out-of-bounds fix, Fix out-of-bounds read in dynamic_programming_bellman_word_ram subsetsumsolver#1). Nesting items count at their smallest footprint, so the bound is never underestimated. Not for Knapsack and BinPackingWithLeftovers.

  • Bin shrinking (shrink_bin, port of rectangle's compute_shrunk_bin_sizes): the operations above reason against the largest length the remaining items can fill instead of the bin's true length, recomputed as items get reserved. The reduced instance keeps the true bin length.

  • Dominated bin types (remove_dominated_bin_types, port of rectangle's operation): for Knapsack, Feasibility and VariableSizedBinPacking with several bin types. The dominating bin type must have as many copies as the number of items plus its own copies_min. unreduce_solution maps bin type ids back to the original instance.

  • Classical knapsack: for a single-bin knapsack with no constraint beyond lengths and copies, only remove_negative_profit_items is applied, since the knapsack primal-dual dynamic programming already performs the useful reductions. Other single-bin knapsacks still get every applicable reduction, since the dynamic programming only relaxes them there.

Soundness of the dedicated-bin reductions

The dedicated-bin reductions rely on an exchange argument that moves the other items of an optimal solution between bins. So full_bin_reduction_applies requires every item type of the instance, not only the reserved ones, to have no nesting length, no finite maximum_weight_after and no binding maximum_stackability. For example, with bin length 10, items 6 and 4, and two items of length 7 with nesting length 3, reserving the perfect pair {6, 4} gives 3 bins (and is reported as optimal), while {6, 7} and {4, 7} only need 2. This case is now a regression test.

Testing

  • Onedimensional unit tests: 61/61 pass. New reduction fixtures cover each rule of the dominant-set reduction, lifting with nesting items, bin shrinking, dominated bin types (including the bin type id mapping in unreduce_solution), the classical-knapsack case, and the nesting counterexample above.
  • Random cross-check: 1,500 small BinPacking instances, solved with and without the reduction. No mismatch attributable to the reduction. The remaining mismatches come from two existing solver issues with nesting, not addressed here:
    • Solution does not clamp an item's start at 0, so a nesting item longer than its predecessor can start before the bin.
    • Some lower bound ignores nesting: bin length 16 with items 14 and (3, nesting 1) gets a dual bound of 2, although both fit in one bin.

…hrinking and dominated-bin-type reductions

- 'reduce_full_bin_items'/'reduce_perfect_pairs': an item type whose
  length matches the bin, or a pair whose lengths sum to it, gets a
  dedicated bin. Only for 'BinPacking' with a single bin type, and only
  when 'Instance::weight_matters()'/'resources_matter()' (new) are both
  false.
- 'reduce_dominant_sets': Martello-Toth reduction procedure. For each
  free item, by decreasing length, look for a set of items that fits
  beside it and dominates every other such set, and reserve them a
  dedicated bin, until nothing more can be fixed. Three rules: everything
  fitting beside the item fits together; a single item fills the space or
  no two items fit together beside it; a pair when no three items fit
  together and no two items longer than the second one do. Identical
  dedicated bins are grouped into a single record.
- 'lift_item_lengths': grow a single-copy item type's length to close a
  margin no combination of the other items could ever fill, bounded with
  'subsetsumsolver::dynamic_programming_bellman_word_ram' (new
  dependency). Nesting items count at their smallest footprint so that
  the bound is never underestimated. Not for 'Knapsack' and
  'BinPackingWithLeftovers'.
- 'shrink_bin': port of rectangle's 'compute_shrunk_bin_sizes'. The
  full-bin-item, perfect-pair, dominant-set and lift operations reason
  against the largest length the remaining items can fill instead of the
  bin's true length, recomputed as items get reserved.
- 'remove_dominated_bin_types': port of rectangle's operation, for
  'Knapsack', 'Feasibility' and 'VariableSizedBinPacking' with several bin
  types. The dominating bin type needs as many copies as the number of
  items plus its own 'copies_min'. 'unreduce_solution' maps bin type ids
  back to the original instance.
- For a classical knapsack (single bin, no constraint beyond lengths and
  copies), only 'remove_negative_profit_items' is applied: the knapsack
  primal-dual dynamic programming already performs the useful reductions.

The dedicated-bin reductions rely on an exchange argument that moves the
other items of an optimal solution between bins, so
'full_bin_reduction_applies' requires every item type of the instance,
not only the reserved ones, to have no nesting length, no finite
'maximum_weight_after' and no binding 'maximum_stackability'. (Bin length
10, items 6 and 4, and two items of length 7 with nesting length 3:
reserving the perfect pair {6, 4} would give 3 bins instead of 2.) Like
the existing operations, they never touch an item type involved in a
precedence.
@fontanf
fontanf force-pushed the onedimensional-reduction-dominant-sets-shrink-dominated-bins branch from 2575a23 to c2e23c3 Compare September 23, 2026 13:07
@fontanf
fontanf merged commit 8039bd9 into master Sep 28, 2026
0 of 3 checks passed
@fontanf
fontanf deleted the onedimensional-reduction-dominant-sets-shrink-dominated-bins branch September 28, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant