TeachMeBitcoin

The Legacy Solver: The Knapsack Algorithm for Subset Sums

From TeachMeBitcoin, the free encyclopedia Reading time: 4 min

The Legacy Solver: The Knapsack Algorithm for Subset Sums

When the "Perfect Fit" (BnB) fails to find a solution, the wallet falls back to its "Workhorse": the Knapsack Solver. This algorithm is named after the classic mathematical "Knapsack Problem": if you have a bag of a certain size, and a collection of items of different values and weights, which items should you put in the bag to maximize the value? In Bitcoin, we use this to find a set of coins that is "At Least" the target amount, but as close as possible to it. The Knapsack Solver is a "Stochastic Approximation" algorithm, meaning it uses "Randomness" to find a good solution quickly. It is the "Resilience of the Core."

The Knapsack algorithm is the "Legacy Solver" of Bitcoin. It has been in the code since the early days and is designed to be "Guaranteed" to find a solution if you have enough money. Unlike BnB, it doesn't care about "Avoiding Change." It will happily create a change output if it means completing the payment. It is the "Reliability of the Bank," ensuring that the "Money Always Moves."

Analyzing the Random Solver: KnapsackSolver

In the source code (src/wallet/coinselection.cpp), we can see how the Knapsack logic works. It uses a series of "Passes" to find the best approximation of the target.

/**
 * This is the Knapsack Solver. It uses random "Guesses" to find the best subset of coins.
 */
util::Result<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, ...)
{
 // 1. We "Shuffle" the coins to ensure we don't pick the same ones every time.
 // This provides a tiny bit of "Privacy through Randomness."
 std::shuffle(groups.begin(), groups.end(), rng);

 // 2. The "Approximation Pass." We try 1,000 random combinations.
 // We look for the set that is closest to our target without going under.
 ApproximateBestSubset(rng, applicable_groups, nTotalLower, nTargetValue, vfBest, nBest, ...);

 // 3. If we found a "Good Enough" set...
 if (nBest >= nTargetValue) {
 // We add the selected coins to the final transaction draft.
 for (int i = 0; i < groups.size(); i++) {
 if (vfBest[i]) result.AddInput(groups[i]);
 }
 }

 return result;
}

Explaining the Knapsack: The Random Grab

The "Change-Heavy" Reality

The downside of the Knapsack solver is that it often creates "Change Outputs." Over time, your wallet will fill up with hundreds of tiny "Leftover" coins (Dust). This is why a Sovereign Architect must occasionally perform "Consolidation"—manually picking all those tiny coins and sending them to yourself in one single transaction. This "Pruning of the Vault" keeps your bank healthy and ensures your future transactions remain cheap. The Knapsack solver is your "Steady Worker," ensuring that the check always clears, even if the "Accounting" is a bit messy. You are the "Manager of the Health," the one who ensures the vault never fills with dust.

☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!