Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ claude-output.log
.worktrees/
.worktree/
*.json
.claude/worktrees/
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,13 @@ PLAN_FILE ?= $(shell ls -t docs/plans/*.md 2>/dev/null | head -1)
run-plan:
@NL=$$'\n'; \
BRANCH=$$(git branch --show-current); \
PLAN_FILE="$(PLAN_FILE)"; \
if [ "$(AGENT_TYPE)" = "claude" ]; then \
PROCESS="1. Read the plan file$${NL}2. Use /subagent-driven-development to execute tasks$${NL}3. Push: git push origin $$BRANCH$${NL}4. Create a pull request"; \
PROCESS="1. Read the plan file$${NL}2. Choose the right skill to execute: use /add-model for new problem models, /add-rule for new reduction rules, or /subagent-driven-development for other tasks$${NL}3. Push: git push origin $$BRANCH$${NL}4. Create a pull request"; \
else \
PROCESS="1. Read the plan file$${NL}2. Execute the tasks step by step. For each task, implement and test before moving on.$${NL}3. Push: git push origin $$BRANCH$${NL}4. Create a pull request"; \
fi; \
PROMPT="Execute the plan in '$${PLAN_FILE}'."; \
PROMPT="Execute the plan in '$$PLAN_FILE'."; \
Comment on lines 189 to +198
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

This PR is described as adding the BinPacking model, but it also changes the run-plan Makefile workflow/prompt logic. If these Makefile changes are intentional, please mention them in the PR description; otherwise consider splitting them into a separate PR to keep scope focused and make review/audit easier.

Copilot uses AI. Check for mistakes.
if [ -n "$(INSTRUCTIONS)" ]; then \
PROMPT="$${PROMPT}$${NL}$${NL}## Additional Instructions$${NL}$(INSTRUCTIONS)"; \
fi; \
Expand Down
41 changes: 41 additions & 0 deletions docs/paper/reductions.typ
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"BMF": [Boolean Matrix Factorization],
"PaintShop": [Paint Shop],
"BicliqueCover": [Biclique Cover],
"BinPacking": [Bin Packing],
)

// Definition label: "def:<ProblemName>" — each definition block must have a matching label
Expand Down Expand Up @@ -801,6 +802,46 @@ Biclique Cover is equivalent to factoring the biadjacency matrix $M$ of the bipa
) <fig:biclique-cover>
]

#problem-def("BinPacking")[
Given $n$ items with sizes $s_1, dots, s_n in RR^+$ and bin capacity $C > 0$, find an assignment $x: {1, dots, n} -> NN$ minimizing $|{x(i) : i = 1, dots, n}|$ (the number of distinct bins used) subject to $forall j: sum_(i: x(i) = j) s_i lt.eq C$.
][
Bin Packing is one of the classical NP-hard optimization problems @garey1979, with applications in logistics, cutting stock, and cloud resource allocation. The best known exact algorithm runs in $O^*(2^n)$ time via inclusion-exclusion over set partitions @bjorklund2009.

*Example.* Consider $n = 6$ items with sizes $(6, 6, 5, 5, 4, 4)$ and capacity $C = 10$. The lower bound is $ceil(30 slash 10) = 3$ bins. An optimal packing uses exactly 3 bins: $B_1 = {6, 4}$, $B_2 = {6, 4}$, $B_3 = {5, 5}$, each with total load $10 = C$.

#figure({
canvas(length: 1cm, {
let s = 0.28
let w = 1.0
let gap = 0.6
let bins = ((6, 4), (6, 4), (5, 5))
let fills = (
(graph-colors.at(0), graph-colors.at(1)),
(graph-colors.at(0), graph-colors.at(1)),
(graph-colors.at(2), graph-colors.at(2)),
)
for i in range(3) {
let x = i * (w + gap)
draw.rect((x, 0), (x + w, 10 * s), stroke: 0.8pt + black)
let y = 0
for j in range(bins.at(i).len()) {
let sz = bins.at(i).at(j)
let c = fills.at(i).at(j)
draw.rect((x, y), (x + w, y + sz * s), stroke: 0.4pt, fill: c)
draw.content((x + w / 2, y + sz * s / 2), text(8pt, fill: white)[#sz])
y += sz * s
}
draw.content((x + w / 2, -0.3), text(8pt)[$B_#(i + 1)$])
}
draw.line((-0.15, 10 * s), (2 * (w + gap) + w + 0.15, 10 * s),
stroke: (dash: "dashed", paint: luma(150), thickness: 0.5pt))
draw.content((-0.5, 10 * s), text(7pt)[$C$])
})
},
caption: [Optimal packing of items with sizes $(6, 6, 5, 5, 4, 4)$ into 3 bins of capacity $C = 10$. Numbers indicate item sizes; all bins are fully utilized.],
) <fig:binpacking-example>
]

// Completeness check: warn about problem types in JSON but missing from paper
#{
let json-models = {
Expand Down
16 changes: 16 additions & 0 deletions docs/src/reductions/problem_schemas.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@
}
]
},
{
"name": "BinPacking",
"description": "Assign items to bins minimizing number of bins used, subject to capacity",
"fields": [
{
"name": "sizes",
"type_name": "Vec<W>",
"description": "Item sizes s_i for each item"
},
{
"name": "capacity",
"type_name": "W",
"description": "Bin capacity C"
}
]
},
{
"name": "CircuitSAT",
"description": "Find satisfying input to a boolean circuit",
Expand Down
Loading