Skip to content

Commit 53c13f1

Browse files
zazabapclaude
andauthored
Fix #114: Add Knapsack model (#171)
* Add plan for #114: Knapsack * feat: add Knapsack model with unit tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: register Knapsack in CLI dispatch and aliases Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add Knapsack problem definition to paper Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: regenerate schemas after Knapsack addition Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add Knapsack re-export and edge-case tests - Re-export Knapsack from models/mod.rs (structural review finding) - Add tests: zero capacity, single item, greedy-not-optimal adversarial case Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: consistent 0-based indexing in paper, add Knapsack to prelude - Paper definition: use w_0,...,w_(n-1) to match 0-based subset S ⊆ {0,...,n-1} - Add Knapsack to prelude re-export for consistency with other misc models Resolves Copilot review comments on PR #171. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove plan file and KS/BP aliases per review - Delete docs/plans/2026-03-04-knapsack-model.md - Remove KS and BP short aliases; case-insensitive full names still work Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: regenerate reduction_graph.json and problem_schemas.json to include Knapsack The Knapsack node was missing from the exported graph and schemas, which would cause the paper's completeness check to fail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9085ba5 commit 53c13f1

11 files changed

Lines changed: 423 additions & 119 deletions

File tree

docs/paper/reductions.typ

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"SpinGlass": [Spin Glass],
4040
"QUBO": [QUBO],
4141
"ILP": [Integer Linear Programming],
42+
"Knapsack": [Knapsack],
4243
"Satisfiability": [SAT],
4344
"KSatisfiability": [$k$-SAT],
4445
"CircuitSAT": [CircuitSAT],
@@ -886,6 +887,14 @@ Biclique Cover is equivalent to factoring the biadjacency matrix $M$ of the bipa
886887
) <fig:binpacking-example>
887888
]
888889

890+
#problem-def("Knapsack")[
891+
Given $n$ items with weights $w_0, dots, w_(n-1) in NN$ and values $v_0, dots, v_(n-1) in NN$, and a capacity $C in NN$, find $S subset.eq {0, dots, n - 1}$ maximizing $sum_(i in S) v_i$ subject to $sum_(i in S) w_i lt.eq C$.
892+
][
893+
One of Karp's 21 NP-complete problems @karp1972. Knapsack is only _weakly_ NP-hard: a classical dynamic-programming algorithm runs in $O(n C)$ pseudo-polynomial time, and a fully polynomial-time approximation scheme (FPTAS) achieves $(1 - epsilon)$-optimal value in $O(n^2 slash epsilon)$ time @ibarra1975. The special case $v_i = w_i$ for all $i$ is the Subset Sum problem. Knapsack is also a special case of Integer Linear Programming with a single constraint. The best known exact algorithm is the $O^*(2^(n slash 2))$ meet-in-the-middle approach of Horowitz and Sahni @horowitz1974, which partitions items into two halves and combines sorted sublists.
894+
895+
*Example.* Let $n = 4$ items with weights $(2, 3, 4, 5)$, values $(3, 4, 5, 7)$, and capacity $C = 7$. Selecting $S = {1, 2}$ (items with weights 3 and 4) gives total weight $3 + 4 = 7 lt.eq C$ and total value $4 + 5 = 9$. Selecting $S = {0, 3}$ (weights 2 and 5) gives weight $2 + 5 = 7 lt.eq C$ and value $3 + 7 = 10$, which is optimal.
896+
]
897+
889898
// Completeness check: warn about problem types in JSON but missing from paper
890899
#{
891900
let json-models = {

docs/paper/references.bib

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,24 @@ @article{alber2004
366366
doi = {10.1016/j.jalgor.2003.10.001}
367367
}
368368

369+
@article{horowitz1974,
370+
author = {Ellis Horowitz and Sartaj Sahni},
371+
title = {Computing Partitions with Applications to the Knapsack Problem},
372+
journal = {Journal of the ACM},
373+
volume = {21},
374+
number = {2},
375+
pages = {277--292},
376+
year = {1974},
377+
doi = {10.1145/321812.321823}
378+
}
379+
380+
@article{ibarra1975,
381+
author = {Oscar H. Ibarra and Chul E. Kim},
382+
title = {Fast Approximation Algorithms for the Knapsack and Sum of Subset Problems},
383+
journal = {Journal of the ACM},
384+
volume = {22},
385+
number = {4},
386+
pages = {463--468},
387+
year = {1975},
388+
doi = {10.1145/321906.321909}
389+
}

docs/src/reductions/problem_schemas.json

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@
88
"type_name": "Vec<Vec<bool>>",
99
"description": "Target boolean matrix A"
1010
},
11-
{
12-
"name": "m",
13-
"type_name": "usize",
14-
"description": "Number of rows"
15-
},
16-
{
17-
"name": "n",
18-
"type_name": "usize",
19-
"description": "Number of columns"
20-
},
2111
{
2212
"name": "k",
2313
"type_name": "usize",
@@ -75,11 +65,6 @@
7565
"name": "circuit",
7666
"type_name": "Circuit",
7767
"description": "The boolean circuit"
78-
},
79-
{
80-
"name": "variables",
81-
"type_name": "Vec<String>",
82-
"description": "Circuit variable names"
8368
}
8469
]
8570
},
@@ -183,6 +168,27 @@
183168
}
184169
]
185170
},
171+
{
172+
"name": "Knapsack",
173+
"description": "Select items to maximize total value subject to weight capacity constraint",
174+
"fields": [
175+
{
176+
"name": "weights",
177+
"type_name": "Vec<i64>",
178+
"description": "Item weights w_i"
179+
},
180+
{
181+
"name": "values",
182+
"type_name": "Vec<i64>",
183+
"description": "Item values v_i"
184+
},
185+
{
186+
"name": "capacity",
187+
"type_name": "i64",
188+
"description": "Knapsack capacity C"
189+
}
190+
]
191+
},
186192
{
187193
"name": "MaxCut",
188194
"description": "Find maximum weight cut in a graph",
@@ -337,24 +343,9 @@
337343
"description": "Minimize color changes in paint shop sequence",
338344
"fields": [
339345
{
340-
"name": "sequence_indices",
341-
"type_name": "Vec<usize>",
342-
"description": "Car sequence as indices"
343-
},
344-
{
345-
"name": "car_labels",
346+
"name": "sequence",
346347
"type_name": "Vec<String>",
347-
"description": "Unique car labels"
348-
},
349-
{
350-
"name": "is_first",
351-
"type_name": "Vec<bool>",
352-
"description": "First occurrence flags"
353-
},
354-
{
355-
"name": "num_cars",
356-
"type_name": "usize",
357-
"description": "Number of unique cars"
348+
"description": "Car labels (each must appear exactly twice)"
358349
}
359350
]
360351
},

0 commit comments

Comments
 (0)