Knapsack problem
The knapsack problem is a classic problem in combinatorial optimization, in which one seeks to maximize the total value of a subset of items—each characterized by a weight and a value—that can be included in a container (the "knapsack") without exceeding its fixed weight capacity.[1] Formally, for a set of n items with weights w_j and profits p_j (j = 1 to n), and capacity C, the objective is to solve
\max \sum_{j=1}^n p_j x_j \quad \text{subject to} \quad \sum_{j=1}^n w_j x_j \leq C,
where x_j \in \{0,1\} in the standard 0–1 variant.[1]
Systematic study of the knapsack problem began in the 1950s within operations research and computer science, evolving into a benchmark for algorithmic techniques due to its NP-hard nature, which implies that no known polynomial-time algorithm exists for exact solutions in the worst case unless P = NP.[1] Despite this, pseudo-polynomial time algorithms, such as dynamic programming, solve it exactly in O(nC) time, making it tractable for moderate capacities, while approximation algorithms like greedy heuristics provide near-optimal solutions efficiently.[2] Parallel implementations on GPUs can further accelerate solutions for large instances with up to 100,000 variables, reducing computation time by factors of up to 26.[3]
The problem has numerous variants, including the unbounded knapsack (allowing multiple copies of items), multidimensional knapsack (multiple capacity constraints), and quadratic or multiobjective extensions, all of which remain NP-hard and extend the core challenge to more complex resource allocation scenarios.[1] Applications span diverse fields, such as optimizing cargo loading in logistics, user allocation in wireless networks, clinical trial planning for resource-constrained experiments, and cryptographic protocols like zero-knowledge proofs.[1]
Introduction and Definition
The knapsack problem derives its name from the classic scenario of a traveler or hiker packing a limited-capacity knapsack with valuable items while adhering to weight constraints, evoking the practical challenge of selecting what to carry on a journey. According to mathematical folklore, the term was coined by mathematician Tobias Dantzig (1884–1956) in the early 20th century to capture this intuitive packing dilemma.[4]
At its core, the problem presents a collection of items, each with an associated weight and value, alongside a knapsack of fixed capacity. The task is to choose a subset of items that maximizes the overall value without surpassing the weight limit, highlighting essential trade-offs between high-value but heavy options and combinations of lighter, lower-value alternatives. This setup mirrors real-world decisions under scarcity, such as budgeting or inventory management.[5]
Consider a straightforward example with a knapsack capacity of 7 units and three items: item A (weight 5, value 10), item B (weight 4, value 7), and item C (weight 3, value 5). Selecting item A alone yields a value of 10 but leaves unused capacity, while combining items B and C achieves a total weight of 7 and value of 12, demonstrating how forgoing a single heavy item can enable a more rewarding mix of lighter ones.[6]
This formulation positions the knapsack problem as a quintessential model for constrained optimization, where the goal is to balance competing priorities to extract the greatest possible utility from finite resources.[7]
The 0-1 knapsack problem, the standard discrete variant, is defined as follows. Given a set of n items, where each item i (for i = 1, \dots, n) has a positive integer weight w_i > 0 and a positive integer value v_i > 0, along with a knapsack capacity W > 0 (also a positive integer), the goal is to select a subset of items that maximizes the total value without exceeding the capacity. This is expressed mathematically as the integer optimization problem:
\begin{align*}
\max &\quad \sum_{i=1}^n v_i x_i \\
\text{s.t.} &\quad \sum_{i=1}^n w_i x_i \leq W, \\
&\quad x_i \in \{0, 1\} \quad \forall i = 1, \dots, n,
\end{align*}
where x_i = 1 if item i is included in the knapsack and x_i = 0 otherwise.
The unbounded knapsack problem relaxes the binary restriction on x_i, allowing multiple instances of each item. Here, the formulation modifies the decision variables to non-negative integers:
\begin{align*}
\max &\quad \sum_{i=1}^n v_i x_i \\
\text{s.t.} &\quad \sum_{i=1}^n w_i x_i \leq W, \\
&\quad x_i \in \mathbb{Z}_{\geq 0} \quad \forall i = 1, \dots, n,
\end{align*}
with the same assumptions on positive integer weights, values, and capacity. This variant models scenarios where items can be taken in unlimited quantities.
In contrast, the fractional knapsack problem permits partial inclusion of items, treating them as divisible. The decision variables are now continuous in [0, 1]:
\begin{align*}
\max &\quad \sum_{i=1}^n v_i x_i \\
\text{s.t.} &\quad \sum_{i=1}^n w_i x_i \leq W, \\
&\quad 0 \leq x_i \leq 1 \quad \forall i = 1, \dots, n,
\end{align*}
again assuming positive integer parameters unless otherwise specified. This continuous relaxation is solvable via a greedy algorithm by sorting items by value density v_i / w_i.
The decision version of the 0-1 knapsack problem, used in complexity analysis, asks whether there exists a feasible solution achieving at least a target value V > 0: Does there exist x \in \{0, 1\}^n such that \sum_{i=1}^n v_i x_i \geq V and \sum_{i=1}^n w_i x_i \leq W? This binary question inherits the same parameter assumptions.
Applications
Resource Allocation and Logistics
The knapsack problem finds extensive application in resource allocation and logistics, where decision-makers must select subsets of items to maximize value under constraints like weight, volume, or budget. In operations research, these problems emerged prominently after World War II, as researchers developed combinatorial optimization techniques to address military logistics and industrial efficiency challenges, building on linear programming foundations laid by figures like George Dantzig. This historical context underscored the knapsack model's utility in modeling limited-resource scenarios, influencing postwar advancements in supply chain management.
In cargo loading for shipping and airlines, the knapsack problem models the selection of payloads to maximize revenue or value while respecting aircraft or vessel capacity limits on weight and volume. For instance, airlines treat cargo shipments as items with associated profits (e.g., freight rates) and weights, formulating the acceptance of bookings as a 0-1 knapsack to avoid overloading while filling available space.[8] This approach ensures efficient utilization of hold space, particularly in revenue management systems where dynamic decisions balance spot market demands against contract allotments.[9]
Investment portfolio selection leverages the knapsack framework to allocate a fixed budget across assets, treating securities as indivisible items with returns as values and costs (e.g., share prices) as weights. Under uncertainty, models incorporate interval-valued parameters for expected returns and budgets, using parametric linear programming to determine optimal integer share allocations while enforcing cardinality limits on the number of assets.[10] This formulation addresses the limitations of fractional solutions in classical mean-variance optimization, prioritizing high-return portfolios without exceeding capital constraints.
In manufacturing, cutting stock problems—such as slicing rolls of paper, metal, or fabric—rely on knapsack subproblems to generate efficient cutting patterns that minimize waste. Seminal work by Gilmore and Gomory formulated the one-dimensional case using column generation, where each new pattern is derived by solving a knapsack maximization to fit demanded widths within stock length. For two-dimensional variants, sequential knapsacks first allocate lengths to strips and then widths to combine them, reducing material overuse in production lines.[11]
A representative example is truck loading, where a vehicle with a capacity of 730 weight units must select from parcels (e.g., 15 items with weights from 50 to 120 units and values based on priority) to maximize total delivery value. The optimal selection—A, B, C, D, H, I, N, O—fills the truck exactly at 730 units for a value of 1418, illustrating binary decisions to balance load without overflow.[12] Such instances highlight the model's role in daily logistics, often extending to multidimensional constraints like volume alongside weight.
Cryptography and Coding Theory
The subset sum problem, a special case of the knapsack problem where the value of each item equals its weight (i.e., v_i = w_i for all i), forms the basis for early knapsack-based cryptosystems. In these systems, the hardness of solving the subset sum problem is leveraged to ensure security, as finding a subset of weights that sums to a target value is computationally infeasible for general instances. The seminal Merkle-Hellman knapsack cryptosystem, proposed in 1978, uses a "trapdoor" mechanism to transform a hard subset sum instance into an easy one for the key holder, enabling efficient encryption and decryption while appearing intractable to outsiders.[13]
A key feature of the Merkle-Hellman scheme is the use of superincreasing sequences, where each weight satisfies w_i > \sum_{j=1}^{i-1} w_j, allowing straightforward greedy decoding for the legitimate recipient after applying a modular transformation with a secret multiplier and modulus. For example, encryption involves computing a ciphertext as the sum of selected public weights corresponding to message bits, and decryption reverses the transformation to recover the superincreasing instance, which can be solved in linear time. This approach was extended to digital signatures, where the trapdoor enables signing without revealing the private key, and to zero-knowledge proofs, such as interactive protocols demonstrating knowledge of a solution to a knapsack instance without disclosing it.[14][15]
In coding theory, knapsack problems arise in the decoding of certain linear error-correcting codes, where finding a low-weight error vector corresponds to solving a subset sum instance over the code's parity-check matrix. Harald Niederreiter's 1986 framework formalized knapsack-type cryptosystems using algebraic coding theory, proposing schemes where encryption hides messages in syndromes, and decoding relies on efficient knapsack solvers for structured codes. These ideas influenced code-based public-key systems, though practical implementations often shift to more robust decoding algorithms to avoid direct knapsack vulnerabilities.[16]
Despite initial promise, knapsack cryptosystems were largely abandoned in the 1980s following lattice-based attacks, such as those using the Lenstra-Lenstra-Lovász (LLL) lattice reduction algorithm introduced in 1982, which efficiently recover the trapdoor from the public key by solving the closest vector problem in low-dimensional lattices. Adi Shamir's 1982 attack and subsequent improvements, including those by Lagarias and Odlyzko, demonstrated that even variants with superincreasing sequences succumb to these methods, rendering pure knapsack-based protocols insecure against modern computational resources. As a result, contemporary cryptography avoids reliance on knapsack hardness, favoring lattice-based primitives that resist such attacks or code-based systems with hidden structure.[14][17]
Bioinformatics and Other Domains
In bioinformatics, the knapsack problem arises in genome sequencing, particularly in shotgun sequencing approaches where the goal is to select a subset of DNA fragments (reads or clones) to maximize genome coverage while adhering to limited sequencing capacity, such as machine runtime or budget constraints. This formulation treats each DNA fragment as an item with a "weight" corresponding to its sequencing cost (e.g., length or processing time) and a "value" based on the unique genomic regions it covers, aiming to minimize redundancies and gaps in assembly. A hybrid algorithm combining the cross-entropy method, dynamic programming, and corridor method has been proposed for DNA sequencing modeled as an orienteering problem incorporating knapsack constraints, outperforming prior algorithms on benchmark instances from GenBank.[18]
The problem also appears in drug design, where selecting combinations of molecular features or partial atomic charges for candidate compounds involves balancing efficacy (value) against potential side effects or synthesis costs (weights) within regulatory or resource limits. For instance, assigning partial atomic charges in drug-like molecules can be modeled as a multiple-choice knapsack problem, allowing selection from groups of charge options per atom to optimize molecular properties like binding affinity while ensuring consistency across simulations. This approach, solved via dynamic programming and approximation techniques, has been shown to reduce computational errors in quantitative structure-activity relationship (QSAR) models, enabling faster virtual screening of large chemical libraries.[19]
Constraint logic programming has been applied to protein structure prediction on lattice models, optimizing energy minimization under constraints like secondary structure and compactness, outperforming exhaustive search for small proteins and providing insights into misfolding diseases like Alzheimer's.[20]
Beyond biology, the knapsack problem is prominent in VLSI design for placing circuit components, where modules or cells are allocated to chip areas to maximize functionality (e.g., performance metrics) without exceeding silicon real estate or power budgets. Dynamic programming solutions to the 0-1 knapsack variant have been integrated into placement heuristics, selecting subsets of components to resolve overcrowding while preserving signal integrity, as seen in multilevel partitioning algorithms that achieve up to 20% better wirelength reduction in industrial benchmarks.[21]
Recent applications in sustainable energy, post-2020, leverage the knapsack problem for optimizing battery charge scheduling in renewable systems, selecting charging intervals or power levels to maximize energy storage or revenue under grid capacity and time-of-use pricing constraints. For example, a knapsack-based formulation integrated with genetic algorithms has been proposed for power usage scheduling in smart grids with battery energy storage systems (BESS), distributing loads to off-peak hours and balancing supply-demand fluctuations, resulting in up to 15% cost savings in simulated solar-integrated homes. Quadratic extensions, accounting for interaction costs like degradation rates, have also been explored but remain computationally intensive for real-time use.[22]
Computational Complexity
Decision and Optimization Versions
The Knapsack problem is formulated in two primary variants: the decision version and the optimization version. In the decision version, given an integer n representing the number of items, each with a positive integer weight w_i and value v_i for i = 1, \dots, n, along with positive integers W (the knapsack capacity) and V (the target value), the question is whether there exists a subset S of {1, \dots, n} such that \sum_{i \in S} w_i \leq W and \sum_{i \in S} v_i \geq V.[23] This yes/no formulation captures the core combinatorial challenge of selecting items without exceeding the weight limit while meeting or surpassing a value threshold.[23]
The optimization version extends this by seeking the maximum achievable value, or equivalently the subset S that maximizes \sum_{i \in S} v_i subject to \sum_{i \in S} w_i \leq W.[24] The two versions are closely related through self-reducibility: the optimization problem can be solved using an oracle for the decision problem by performing a binary search over possible target values V in the range from 0 to the sum of all v_i, which requires O(\log(\sum v_i)) decision queries, each polynomial in the input size.[24] This reduction demonstrates that polynomial-time solvability of the decision version implies the same for the optimization version, highlighting their equivalent computational difficulty in the complexity hierarchy.[25]
The decision version belongs to NP because a proposed subset serves as a polynomial-length certificate that can be verified in linear time O(n) by computing the total weight and value sums and checking against W and V, respectively.[26] Historically, Richard Karp identified the Knapsack decision problem as one of 21 NP-complete problems in his seminal 1972 paper, establishing its foundational role in computational complexity theory by showing polynomial-time reductions from other hard problems.[27]
NP-Hardness Proofs
The decision version of the 0-1 Knapsack problem—determining whether there exists a subset of items with total weight at most W and total value at least V—is NP-complete. This follows from a polynomial-time many-one reduction from the Partition problem, which is itself NP-complete. Given a Partition instance consisting of positive integers a_1, \dots, a_n with even total sum S = \sum a_i, construct a Knapsack instance by setting the weight and value of each item i to w_i = v_i = a_i, the capacity to W = S/2, and the target value to V = S/2. This reduction runs in linear time relative to the input size. A "yes" instance of Partition corresponds to a subset summing exactly to S/2, which satisfies the Knapsack constraints with equality; conversely, any feasible Knapsack solution yields a valid Partition by the identical weights and values.
The unbounded Knapsack problem, allowing multiple copies of each item, is also NP-complete in its decision version. Strong NP-hardness for the unbounded case arises via a polynomial-time reduction from the 3-Partition problem, which is strongly NP-complete. In this reduction, each element of the 3-Partition instance (a set of $3m integers bounded by a polynomial in m) is mapped to an item type in the unbounded Knapsack with weight and value equal to the element's size, capacity set to the total sum divided by m, and target value matching the per-bin sum; feasibility requires exactly three copies per "bin" without overflow, mirroring the partition constraint. This establishes strong NP-hardness, as the numbers remain polynomially bounded, ruling out pseudo-polynomial solvability in the unary encoding.
These hardness results imply that no polynomial-time algorithm exists for solving the (decision or optimization) Knapsack problem unless P = NP. However, the existence of a pseudo-polynomial-time dynamic programming algorithm running in O(n[W](/page/W)) time provides a practical exact solution when the capacity [W](/page/W) is not too large, highlighting the weakly NP-hard nature of the standard 0-1 and unbounded variants.
In parameterized complexity theory, the Knapsack problem is fixed-parameter tractable when parameterized by the number of items n, solvable in O(2^n n) time via enumeration or dynamic programming over subsets. However, it is W[28]-hard when parameterized by the capacity [W](/page/W) in multidimensional generalizations, though the standard single-dimensional case remains FPT in [W](/page/W) due to the pseudo-polynomial dynamic program.[29]
Recent extensions confirm NP-hardness in generalized settings, such as the Knapsack Problem with Group Fairness, where items belong to fairness groups and solutions must satisfy proportionality constraints across groups; this variant remains NP-hard via reduction from Partition, even with two groups.[30]
Unit-Cost and Real-Number Models
In the unit-cost random access machine (RAM) model, arithmetic operations and comparisons on integers fitting within machine words are assumed to take constant time, regardless of the word size needed to represent the capacity W. Under this model, the dynamic programming algorithm for the 0-1 knapsack problem computes the optimal solution in O(nW) time, where n is the number of items, by filling a table of size O(nW) with constant-time updates per entry.[31] This running time is pseudo-polynomial, as it is polynomial in the magnitude of W but exponential in the input size \Theta(n \log W + n \log V), where V is the total value bound, since hard instances can have W exponentially large in n.[32]
The unit-cost model highlights the dependence of the knapsack problem's solvability on the numeric scale of the inputs, contrasting with the standard multi-tape Turing machine model where bit operations dominate and the same dynamic programming approach yields only pseudo-polynomial time relative to the full input length. In the log-cost RAM model, where the time for arithmetic is proportional to the bit lengths of the operands (e.g., O((\log W)^2) per addition or multiplication), the dynamic programming runtime becomes super-polynomial for instances with large W, reinforcing the NP-hardness established via reductions in the Turing machine model.
When weights and values are real numbers, the real-number RAM model assumes constant-time operations on reals, including comparisons and arithmetic. In this setting, the fractional knapsack problem—which permits taking fractional portions of items—is solvable exactly via a greedy algorithm that sorts items by decreasing value-to-weight ratio and fills the knapsack sequentially, achieving O(n \log n) time dominated by sorting. (Note: This briefly references the greedy approach for the fractional variant, with full details in approximation methods.)
The availability of a fully polynomial-time approximation scheme (FPTAS) for the 0-1 knapsack in the standard model enables (1 - ε)-approximations in O(n^2 / \epsilon) time, independent of W and V, by scaling values and applying dynamic programming on bounded targets.[33]
Although theoretically insightful for analyzing scale dependence, the unit-cost model is unrealistic for practical large-W instances, as real machines incur costs scaling with bit lengths for big integers, aligning more closely with log-cost assumptions; nonetheless, it underscores why pseudo-polynomial algorithms suffice for many applications where capacities remain manageable.
Exact Solving Methods
Dynamic Programming Approaches
The dynamic programming solution for the 0-1 knapsack problem computes the maximum value achievable by considering subsets of items under a weight constraint. It employs a two-dimensional table where dp represents the maximum value using the first i items with a knapsack capacity of w. The recurrence relation is defined as:
dp =
\begin{cases}
\max(dp[i-1], \, dp[i-1][w - w_i] + v_i) & \text{if } w \geq w_i \\
dp[i-1] & \text{otherwise}
\end{cases}
with base cases dp{{grok:render&&&type=render_inline_citation&&&citation_id=0&&&citation_type=wikipedia}} = 0 for all w and dp{{grok:render&&&type=render_inline_citation&&&citation_id=0&&&citation_type=wikipedia}} = 0 for all i, where w_i and v_i are the weight and value of item i.
This approach fills the table iteratively, achieving a time complexity of O(nW) and space complexity of O(nW), where n is the number of items and W is the knapsack capacity. Space can be optimized to O(W) by using a one-dimensional array, updating values in reverse order from W down to each item's weight to avoid overwriting dependencies.
The following pseudocode illustrates the optimized 1D implementation for the 0-1 knapsack:
function zeroOneKnapsack(weights[], values[], W):
n = length(weights)
dp = array of size W+1, initialized to 0
for i from 1 to n:
for w from W down to weights[i]:
dp[w] = max(dp[w], values[i] + dp[w - weights[i]])
return dp[W]
function zeroOneKnapsack(weights[], values[], W):
n = length(weights)
dp = array of size W+1, initialized to 0
for i from 1 to n:
for w from W down to weights[i]:
dp[w] = max(dp[w], values[i] + dp[w - weights[i]])
return dp[W]
To demonstrate, consider an example with n=3 items and W=5: item 1 (weight 2, value 3), item 2 (weight 3, value 4), item 3 (weight 4, value 5). The 1D DP array evolves as follows:
- Initialize: dp = [0, 0, 0, 0, 0, 0]
- After item 1: dp = [0, 0, 3, 3, 3, 3] (updates for w ≥ 2)
- After item 2: dp = [0, 0, 3, 4, 4, 7] (updates for w ≥ 3, e.g., dp[34] = max(3, 4 + dp) = 4; dp[35] = max(3, 4 + dp[28]) = 4; dp[36] = max(3, 4 + dp[37]) = 7)
- After item 3: dp = [0, 0, 3, 4, 5, 7] (updates for w ≥ 4, e.g., dp[35] = max(4, 5 + dp) = 5; dp[36] = max(7, 5 + dp[28]) = 7)
The final maximum value is 7, achieved by selecting items 1 and 2.
For the unbounded knapsack problem, where multiple instances of each item are allowed, the dynamic programming formulation modifies the recurrence to permit repeated use. A 1D array dp stores the maximum value for capacity w, updated by considering each item for every weight. The relation is dp = \max(dp, v_i + dp[w - w_i]) for each item i where w \geq w_i. This yields the same O(nW) time and O(W) space complexities.
Pseudocode for the unbounded variant is:
function unboundedKnapsack(weights[], values[], W):
dp = array of size W+1, initialized to 0
for w from 1 to W:
for i from 1 to n:
if w >= weights[i]:
dp[w] = max(dp[w], values[i] + dp[w - weights[i]])
return dp[W]
function unboundedKnapsack(weights[], values[], W):
dp = array of size W+1, initialized to 0
for w from 1 to W:
for i from 1 to n:
if w >= weights[i]:
dp[w] = max(dp[w], values[i] + dp[w - weights[i]])
return dp[W]
The inner loop order ensures multiples are considered without restriction.
These dynamic programming methods provide exact solutions but are pseudo-polynomial, with running time exponential in the bit length of W, rendering them impractical for instances where W exceeds typical memory limits, such as W > 10^6.
Meet-in-the-Middle Algorithm
The meet-in-the-middle algorithm provides an exact solution to the 0-1 knapsack problem by employing a divide-and-conquer strategy that splits the items into two halves, making it particularly suitable for instances where the number of items n is up to about 40 and the knapsack capacity W is large. Introduced by Horowitz and Sahni in 1974, this approach enumerates all subset sums for each half separately and then combines them efficiently to identify the optimal solution without exploring the full $2^n search space.
The algorithm begins by partitioning the n items into two subsets A and B, each of size approximately n/2. For subset A, all $2^{n/2} possible subsets are generated, recording pairs (w_A, v_A) where w_A is the total weight and v_A is the total value of the subset. The same process is applied to subset B, yielding pairs (w_B, v_B). One of these lists, say for A, is sorted by weight w_A in ascending order.
To find the maximum value, the algorithm iterates over each subset in B. For a given (w_B, v_B), it performs a binary search on the sorted list for A to locate the largest v_A such that w_A \leq W - w_B. The value v_A + v_B is then computed, and the global maximum across all such pairs is retained as the solution. This ensures all feasible combinations are considered while avoiding redundant computations.
The time complexity is O(2^{n/2} n), arising from the O(2^{n/2}) subset generations per half (each taking O(n) time in total across all subsets via recursive or iterative methods), the O(2^{n/2} \log 2^{n/2}) sorting step, and the O(2^{n/2} \log 2^{n/2}) binary searches. The space complexity is O(2^{n/2}), required to store the pairs for both halves. An optimization replaces sorting and binary search with a hash table that maps each possible w_A to the maximum v_A, enabling average O(1) lookups and reducing the overall time to O(2^{n/2} n) more tightly in practice.
For illustration, consider n=20 items with weights and values such that W is large, say $10^6. The dynamic programming baseline requires O(20 \times 10^6) = 2 \times 10^7 operations, which may be feasible but grows linearly with W. In contrast, the meet-in-the-middle approach generates $2^{10} = [1024](/page/1024) subsets per half, with sorting and $1024[binary](/page/Binary) searches each takingO(1024 \log 1024) \approx 10^4operations, yielding a total time of roughlyO(20 \times 1024) \approx 2 \times 10^4operations—significantly faster whenW \gg 2^{n/2}. This demonstrates its advantage over dynamic programming for large W$.
Subsequent extensions have refined the technique for even harder instances. For example, Howgrave-Graham and Joux (2010) developed an advanced variant using recursive partitioning and optimized storage of subset sums, achieving a time complexity of \tilde{O}(2^{0.337n}) for knapsacks of density near 1, with space \tilde{O}(2^{0.256n}). These post-2010 improvements build on the core idea but incorporate more sophisticated data structures for denser problem instances.[38]
The meet-in-the-middle algorithm excels when n \leq 40, as $2^{20} \approx 10^6 fits in modern memory and computation budgets, and it outperforms dynamic programming precisely when W is too large for the O(nW) pseudo-polynomial bound to be practical.
Branch-and-Bound and Dominance Techniques
The branch-and-bound (B&B) algorithm represents a foundational exact method for solving the 0-1 knapsack problem, employing a systematic tree search to explore decision variables while pruning unpromising branches to ensure computational efficiency. Introduced by Kolesar in 1967, the approach constructs a search tree where each node corresponds to a partial assignment of items, typically using depth-first traversal by sequentially deciding whether to include (x_i = 1) or exclude (x_i = 0) the next item i. At each node, an upper bound on the maximum achievable value is computed for the remaining subproblem; if this bound is less than or equal to the value of the best feasible solution found so far, the branch is pruned, avoiding exhaustive enumeration of infeasible or suboptimal paths.[39]
Upper bounds in B&B for the 0-1 knapsack are often derived from linear programming (LP) relaxations, where binary constraints are replaced by continuous variables [0,1], or from greedy heuristics that order items by decreasing value-to-weight ratio (v_i / w_i) and fill the remaining capacity fractionally. Martello and Toth (1977) proposed an enhanced upper bound that dominates the standard LP relaxation by incorporating surrogate relaxations and reduction techniques, enabling tighter pruning and faster convergence in the search tree. These bounds are evaluated at each node to guide the search, with depth-first ordering typically prioritizing the exclusion branch (x_i = 0) to quickly generate feasible solutions and update the incumbent value.[40]
Dominance techniques further refine the B&B process by eliminating redundant partial solutions or states within the search. In the context of node comparison, a node representing a partial solution with current value v, remaining capacity w, and items considered up to index i is dominated by another node with v' ≥ v, w' ≤ w, and i' ≥ i (i.e., fewer or equal unassigned items); the dominated node can be discarded as it cannot yield a better overall solution. This criterion, as applied in early B&B implementations, reduces the effective search space by avoiding symmetric or inferior branches.[39]
Implementations often integrate dynamic programming (DP) elements to compute bounds more efficiently, such as solving a relaxed subproblem over remaining items to obtain precise upper estimates, while applying dominance to prune states in the auxiliary DP table—discarding any state (i, w, v) if a superior state (i', w', v') exists with i' ≥ i, w' ≤ w, and v' ≥ v. This hybrid approach minimizes the computational overhead of bound calculations, transforming the exponential search into a practical method for medium-sized instances.[40]
Consider a small 0-1 knapsack instance with capacity W = 10 and three items: item 1 (w_1=6, v_1=30), item 2 (w_2=5, v_2=20), item 3 (w_3=3, v_3=15). The B&B tree starts at the root (i=0, w=10, v=0). Branching on item 1 yields: include (node A: i=1, w=4, v=30, upper bound ≈ 30 + greedy fractional on remaining ≈ 30 + 15 = 45, taking item 3 fully) and exclude (node B: i=1, w=10, v=0, upper bound ≈ 35 from items 2 and 3). From node B, branching on item 2: include (node C: i=2, w=5, v=20, upper bound ≈ 20 + 15 = 35) and exclude (node D: i=2, w=10, v=0, upper bound ≈ (10/3)*15 ≈ 50 from fractional item 3). Node D's bound (50) exceeds early incumbents but guides further exploration. Continuing, node A branches on item 2 (exclude, since w=4 <5), then on item 3 (include: feasible solution v=45), updating incumbent; subsequent nodes like C (include item 3: v=35 <45, pruned if bound ≤45). The optimal v=45 (items 1 and 3) is verified with pruned nodes reducing exploration from 8 to 5 leaves.[39]
Empirically, B&B with dominance achieves significant speedups on hard instances, such as strongly correlated problems where values and weights are closely related; Kolesar's implementation solved 50-item instances in under 0.1 minutes on 1960s hardware, generating median 300-500 nodes. These techniques form the core of commercial integer programming solvers like CPLEX, which embed knapsack B&B for cutting-plane generation and branching in mixed-integer programs, handling instances up to thousands of variables in practice.[39][40]
Approximation and Heuristic Methods
Greedy Algorithms
Greedy algorithms for the knapsack problem provide fast heuristic solutions by prioritizing items based on their value density, defined as the ratio v_i / w_i for each item i. These methods are particularly effective for the fractional knapsack variant, where items can be divided, and offer reasonable approximations for the more challenging 0-1 version, where items must be taken entirely or not at all.[41]
In the fractional knapsack problem, the greedy algorithm sorts the items in non-increasing order of value density and greedily adds as much of each item as possible until the knapsack capacity is reached. This approach yields the optimal solution because the optimal selection corresponds to filling the knapsack with the highest-density items first, maximizing total value without exceeding the weight limit. The time complexity is O(n \log n), dominated by the sorting step.[41]
For the 0-1 knapsack problem, the greedy algorithm follows the same sorting by value density but only includes an item if its full weight fits within the remaining capacity. To enhance performance, the algorithm computes the maximum of this greedy selection and the value of the single highest-value item that fits. This yields a \frac{1}{2}-approximation, meaning the solution value is at least half the optimal. The proof relies on the linear programming (LP) relaxation of the 0-1 knapsack, where the greedy solution bounds the integer optimum via duality: the LP optimum upper-bounds the true optimum, and the greedy fills the capacity with high-density items, ensuring the ratio holds.[41]
The \frac{1}{2}-approximation ratio is tight, as demonstrated by instances where the greedy solution achieves nearly half the optimal value. Consider a knapsack of capacity $2w and items: (value w + 4\epsilon, weight w + 2\epsilon), (value w + 2\epsilon, weight w + \epsilon), (value w - \epsilon, weight w - \epsilon), for small \epsilon > 0. The densities are approximately 1, but the greedy selects the first item (value w + 4\epsilon) and cannot add more, while the optimum selects the second and third items (total value $2w + \epsilon). As \epsilon \to 0, the ratio approaches \frac{1}{2}.[41]
Density-based variants extend the basic greedy by incorporating dynamic programming for subsets of small-weight items to refine selections. For instance, items with weights below a threshold can be solved exactly via DP, while larger items are handled greedily by density; this hybrid improves practical performance on instances with varied item sizes, though it increases time complexity beyond O(n \log n).[41]
Despite the worst-case \frac{1}{2}-approximation for 0-1 knapsack, greedy algorithms perform better on average, often achieving values much closer to optimal under typical distributions of item values and weights. Analysis shows the expected approximation ratio exceeds \frac{1}{2} significantly for the decreasing density greedy variant.[42] For stronger guarantees with tunable error, fully polynomial-time approximation schemes build on these ideas but require more sophisticated scaling.[41]
Fully Polynomial-Time Approximation Schemes
The fully polynomial-time approximation scheme (FPTAS) for the 0-1 knapsack problem constructs a (1 - ε)-approximate solution for any ε > 0 by scaling and rounding the item values, followed by exact dynamic programming on the reduced instance. Specifically, let OPT denote the optimal solution value. Define δ = ε OPT / n and set the scaled value for each item i as v_i' = ⌊v_i / δ⌋. This rounding reduces the maximum scaled value to at most n, ensuring that the dynamic programming table for achieving scaled values up to n has size polynomial in n and 1/ε. The exact solution on the scaled instance is computed using dynamic programming in time polynomial in n, 1/ε, and log(max v_i), typically O(n^2 / ε) for the basic implementation after scaling.[43]
The approximation guarantee holds because the optimal set S* in the original instance satisfies ∑{i ∈ S*} v_i' ≥ ∑{i ∈ S*} (v_i - δ) = OPT - n δ = OPT - ε OPT = (1 - ε) OPT. Let S' be the optimal set for the scaled instance; then ∑{i ∈ S'} v_i ≥ ∑{i ∈ S'} v_i' ⋅ δ ≥ (1 - ε) OPT ⋅ δ / δ = (1 - ε) OPT, since the scaled optimum is at least (1 - ε) OPT and each original value is at least the scaled value times δ. Since OPT is unknown, an upper bound U ≥ OPT (e.g., the sum of all v_i) is used in place, yielding δ = ε U / n; this ensures the error bound remains ≤ ε U ≤ ε (n max v_i), but the relative guarantee relative to OPT is preserved, with time depending on log U. The proof sketch relies on bounding the total rounding error across at most n items by n δ = ε OPT, ensuring the scaled optimum captures at least (1 - ε) of the original OPT.[43]
This FPTAS extends naturally to the unbounded knapsack problem, where multiple copies of items are allowed, using similar scaling and dynamic programming but with time complexity O(n + 1/ε^3) in seminal improvements. For the multiple knapsack problem, involving several knapsacks with individual capacities, scaling techniques lead to polynomial-time approximation schemes (PTAS) achieving (1 - ε)-optimality, though not fully polynomial unless P = NP. In practice, values of ε = 0.01 are commonly used to balance accuracy and computation time, often outperforming exact methods for large n due to the polynomial scaling.[44]
Quantum and Machine Learning-Based Approximations
The Quantum Approximate Optimization Algorithm (QAOA) has been adapted for approximate solutions to the 0-1 knapsack problem by encoding the objective as a variational quantum circuit, often reducing it to related combinatorial problems like max-cut for constraint handling. In one approach using a quadratic penalty term to enforce capacity constraints, QAOA with circuit depths p=1 to 5 yields approximation ratios improving from approximately 0.3 to 0.8 on benchmark instances, demonstrating progressive enhancement in solution quality as depth increases. These 2020s advances leverage hybrid quantum-classical optimization to navigate the problem's exponential search space more effectively than shallow circuits alone.[45]
Recent quantum algorithms further exploit Grover's search for speedups in 0-1 knapsack approximations, applying amplitude amplification to sub-problems that generate feasible subsets before refining the remainder. A 2025 method, the Quantum Tree Generator (QTG), uses successive Grover iterations to identify high-value solutions with a query complexity of O(\sqrt{2^n}) for practical instances, achieving success probabilities of at least 40% on hard cases (gap ≥7) and 80% on easier ones (gap ≤6) after around 700 + n²/16 iterations. This provides a quadratic speedup over classical unstructured search while requiring only O(n) qubits, outperforming classical solvers like COMBO on instances with ≥100 variables in terms of space efficiency.[46]
Reinforcement learning (RL) offers machine learning-based approximations by framing the knapsack as a sequential decision process, where an agent learns policies to select items under capacity limits. A 2025 RL framework defines states as (i, w)—the current item index i and remaining weight w—with binary actions to include or exclude each item, using a Q-learning variant (Dueling Deep Q-Network) trained on diverse instances for generalization. This approach produces near-optimal policies, outperforming greedy heuristics by up to 5% on n=100 instances while being over 9000 times faster than dynamic programming.[47]
Fairness-aware approximations extend these methods to incorporate group fairness constraints, ensuring equitable resource allocation across item classes. A 2025 integer linear programming (ILP) formulation for the knapsack problem with group fairness bounds resource consumption per class, solvable via dynamic programming reformulation as a multiple-choice knapsack with pseudopolynomial complexity O(n c h + ℓ c²), where h is the resource bound range and ℓ the number of classes. This ILP-based approach achieves optimality on 98.66% of tested instances, including hard participatory budgeting cases, while enforcing fairness without excessive solution degradation compared to unconstrained baselines.[30]
Variations
Bounded and Unbounded Knapsacks
The bounded knapsack problem extends the standard 0-1 knapsack by allowing multiple copies of each item type, up to a specified limit b_i for item i, where the decision variable x_i satisfies $0 \leq x_i \leq b_i and x_i is integer.[48] This formulation generalizes the 0-1 case, which corresponds to b_i = 1 for all i, enabling modeling of scenarios with limited availability of identical items.[49]
In contrast, the unbounded knapsack problem removes any upper limit on the number of copies, setting b_i = \infty for all i, so x_i \geq 0 is integer without bound.[48] This variant is suitable for situations involving unlimited supplies of item types, such as selecting from an infinite stock of materials.[49]
Dynamic programming solves the unbounded knapsack in pseudo-polynomial time O(nW), where n is the number of item types and W is the knapsack capacity, by iterating over items and updating capacities in a single pass per item, allowing reuse without tracking counts.[49] For the bounded case, the approach extends the 0-1 dynamic programming by either treating each possible copy as a distinct item or using a modified recurrence that loops up to b_i times per item, yielding time complexity O(n W \sum b_i).[49]
Applications of the bounded knapsack include inventory management where stock levels limit selections, such as a retailer choosing limited quantities of products to maximize profit under weight constraints for shipping.[49] The unbounded variant applies to problems like cutting stock optimization, where material is available in unlimited lengths and pieces are cut to maximize utilization without quantity restrictions.[49]
Both problems are NP-hard in the strong sense, as reductions from the 0-1 knapsack preserve this property.[50] However, the unbounded knapsack admits a simpler fully polynomial-time approximation scheme (FPTAS) due to its structure allowing greedy-like scaling in the approximation, whereas bounded variants require more involved adjustments to achieve similar guarantees.[51]
Multiple and Multidimensional Knapsacks
The multiple knapsack problem extends the classical 0-1 knapsack by considering m knapsacks, each with its own capacity W_j for j = 1, \dots, m. Given n items, each with profit p_i > 0 and weight w_i > 0, the goal is to assign each item to at most one knapsack such that the total weight in knapsack j does not exceed W_j, while maximizing the total assigned profit.[52] This problem is strongly NP-complete, as it includes the single knapsack problem as a special case when m=1, and lacks a fully polynomial-time approximation scheme (FPTAS) even for m=2.[52] Approximation algorithms achieve strong performance through techniques like profit and size rounding, which group items into a logarithmic number of classes to enable a polynomial-time approximation scheme (PTAS) guaranteeing a (1 - \epsilon)-approximation for any \epsilon > 0.[52]
The multidimensional knapsack problem generalizes further by imposing constraints across d > 1 dimensions, such as weight, volume, and cost. Each item i has a profit p_i > 0 and a weight vector \mathbf{w}_i = (w_{i,1}, \dots, w_{i,d}) with w_{i,k} > 0 for dimension k = 1, \dots, d, while the knapsack has capacity vector \mathbf{W} = (W_1, \dots, W_d) with W_k > 0. The objective is to select a subset of items maximizing total profit subject to \sum_i x_i w_{i,k} \leq W_k for each k = 1, \dots, d, where x_i \in \{0,1\}.[53] For fixed d, dynamic programming yields a pseudo-polynomial-time algorithm, and scaling techniques extend the single-dimensional FPTAS to produce a (1 - \epsilon)-approximation in time polynomial in n and $1/\epsilon but exponential in d.[32] However, when d is part of the input (variable d), the problem is strongly NP-hard with no pseudo-polynomial algorithm unless P = NP.[53]
The multiple knapsack problem relates closely to the bin packing problem, which can be viewed as its minimization dual: while multiple knapsack maximizes profit (or packed weight) using a fixed number of bins with given capacities, bin packing minimizes the number of uniform-capacity bins needed to pack all items without exceeding capacities per bin.[54] A practical example of the two-dimensional case (d=2) arises in cargo loading, where items must respect both weight limits (W_1) and volume limits (W_2) to optimize shipment value within a container.[55]
Quadratic, Geometric, and Online Variants
The quadratic knapsack problem (QKP) extends the classical 0-1 knapsack by incorporating pairwise interactions between items in the objective function, modeling scenarios such as facility location or portfolio optimization where selecting one item affects the value of others. Formally, given items with weights w_i > 0, linear profits p_i \in \mathbb{R}, and quadratic coefficients q_{ij} \in \mathbb{R} for i, j = 1, \dots, n, the goal is to solve
\max \sum_{i=1}^n p_i x_i + \sum_{i=1}^n \sum_{j=1}^n q_{ij} x_i x_j \quad \text{subject to} \quad \sum_{i=1}^n w_i x_i \leq c, \quad x_i \in \{0,1\},
where c > 0 is the knapsack capacity and x_i indicates selection of item i.[56] This formulation was introduced by Gallo et al. in 1980, who provided initial exact and heuristic methods.[56]
The QKP is strongly NP-hard, as it generalizes the maximum clique problem via a polynomial reduction where weights are set to 1 and quadratic terms encode graph edges.[57] Exact solution approaches rely on branch-and-bound techniques enhanced with cutting planes and Lagrangian relaxations; for instance, a cut-and-branch framework generates valid inequalities from conic relaxations and solves subproblems via dynamic programming, achieving optimality on instances up to 100 items.[58] Heuristics, such as reactive tabu search, further support practical solving for larger instances by iteratively improving feasible solutions.[59]
In the geometric knapsack problem, items are represented as geometric shapes (typically axis-aligned rectangles or hyperrectangles in d dimensions) with associated values, and the knapsack is a fixed container (e.g., a unit square in 2D); the objective is to select and non-overlappingly pack a subset of items to maximize total value without rotations unless specified. This variant arises in applications like ad placement or 3D printing, where spatial constraints prevent overlap, distinguishing it from scalar-weight models. The problem is NP-hard even in 2D, with approximation algorithms focusing on shelf packing: items are grouped into horizontal "shelves" of equal height, packed left-to-right within each shelf, and shelves stacked vertically, yielding a polynomial-time approximation scheme (PTAS) with ratio $1 + \epsilon for arbitrary rectangles.[60] Recent advances include near-linear time algorithms for d-dimensional cases, achieving (1 + \epsilon)-approximations for hypercubes via dynamic programming over rounded sizes.
The online knapsack problem requires irrevocable decisions on items arriving sequentially, without knowledge of future arrivals, extending the classical problem to streaming settings like real-time resource allocation. In the fractional variant, partial acceptance is allowed, and the greedy algorithm—accepting the maximum feasible fraction of each item—achieves a competitive ratio of $1/2, meaning the algorithm's value is at least half the offline optimum in the worst case.[61] For the 0-1 integer version with arbitrary value-to-weight ratios, no constant competitive ratio exists, as adversaries can force arbitrarily poor performance by presenting small high-value items after filling with low-value ones; constant ratios require assumptions like bounded densities.[61]
Recent developments incorporate machine learning predictions to mitigate online limitations; for example, in the online fractional knapsack with input predictions (e.g., future item densities), algorithms achieve consistency (near-optimal under accurate predictions) and robustness (bounded degradation under errors), with a 2024 scheme providing O(1)-competitive ratios when predictions err by at most \epsilon.[62] Such prediction-augmented methods, analyzed under the "predictions with advice" framework, bridge online and offline performance for unit-profit or stochastic arrivals.[62]
Knapsacks with Additional Constraints
The knapsack problem with additional constraints extends the classical formulation by incorporating relational, fairness, or uncertainty requirements that reflect real-world complexities, such as incompatibilities between items or equitable distribution across groups. These variants maintain the core objective of maximizing value under capacity limits but introduce interdependencies that increase computational difficulty, often requiring specialized exact or approximate algorithms. Common applications arise in resource allocation scenarios where items cannot be selected independently, such as project selection with mutual exclusions or fair division of limited resources among stakeholders.[63]
In the knapsack problem with conflicts, items are represented as nodes in an undirected conflict graph, where edges denote incompatibilities preventing simultaneous selection, effectively combining the maximum independent set problem with knapsack optimization. This variant, known as the knapsack problem with conflict graph (KPCG), ensures that no two adjacent nodes are chosen, preserving the knapsack capacity while maximizing total value. The problem is NP-hard, as even dense conflict graphs can lead to exponentially many feasible independent sets, complicating enumeration. Recent advancements include branch-and-bound algorithms that exploit graph structure for bounding and pruning, achieving exact solutions for instances with up to 100 items and moderate conflict densities. For hard instances with high conflict density (e.g., 0.9), a 2025 MILP approach using CP-SAT solver solves benchmark instances (up to 1000 items, capacity 2000) in average 1.3 seconds, achieving 100% optimality and outperforming prior methods in runtime.[64][65][66]
Fairness constraints in the knapsack problem address group-based equity, such as ensuring proportional value allocation per demographic or category to avoid bias in decision-making. In the group fairness knapsack problem, items are partitioned into groups, with constraints requiring that the total value or weight from each group meets lower and upper bounds, often aiming for proportionality where each group receives value roughly proportional to its size. This formulation is NP-hard, but 2025 integer linear programming (ILP) methods provide the first exact branch-and-cut frameworks, incorporating valid inequalities based on group cardinalities to solve instances with 500 items and 10 groups within 1,000 seconds using commercial solvers like Gurobi. These ILP approaches dominate Lagrangian relaxation for exact solutions by tightening bounds through lifted cover inequalities tailored to fairness parameters.[67][30][68]
Robust and stochastic variants handle uncertainty in item weights or values, using scenario-based optimization to ensure solutions perform well across possible realizations. In the robust knapsack problem, weights belong to uncertainty intervals, and the goal is to maximize the worst-case value over all feasible scenarios within a budgeted uncertainty set, often modeled via Bertsimas-Sim-style Γ-uncertainty. Exact solutions employ mixed-integer programming reformulations, solvable in polynomial time for interval uncertainty but NP-hard for general polyhedral sets. Stochastic extensions generate scenarios via Monte Carlo simulation to approximate expected value maximization, with scenario-based ILPs reducing variance through sample average approximation for problems with 100 items and 1,000 scenarios. These methods guarantee robustness by penalizing high-variance solutions, achieving near-optimal performance in applications like inventory management under demand fluctuations.[69][70][71]
Precedence constraints impose ordering on item selection, where certain items can only be included if predecessors are chosen, modeled via a directed acyclic graph (DAG) of dependencies. The precedence constrained knapsack problem (PCKP) integrates these arcs into the formulation, adjusting item values to account for forced inclusions and using clique-based facets for polyhedral strengthening in branch-and-cut solvers. This adds structural complexity, remaining NP-hard even for tree-structured precedences, with exact algorithms solving instances of 200 items via separation of precedence cover inequalities in under 100 seconds. Applications include assembly line scheduling, where components must follow sequential prerequisites.[72][73]
These additional constraints elevate the problem's complexity beyond the standard NP-hardness of the 0-1 knapsack, with some formulations (e.g., those with dynamic precedences or extensive conflicts) reaching PSPACE-completeness due to the need to track state-dependent selections over exponential paths. Approximation algorithms, such as Lagrangian relaxation, decompose the problem by dualizing conflict or fairness constraints, providing (1-ε)-approximations in O(n^2 / ε) time for conflict graphs with bounded degree by relaxing incompatibilities into penalized terms. For instance, in pharmaceutical applications, a conflict graph models incompatible drugs (e.g., edges between interacting compounds like certain antibiotics and anticoagulants), ensuring safe combinations while maximizing therapeutic value under dosage limits.[74][75]