I’ve had need for this on several occasions, and never come up with a decent solution until now. The problem happens for me most frequently when dealing with a group of transactions, and I need to find a subset of them that add up to a specific amount.
My data might look like this:
+----+--------+ | id | total | +----+--------+ | 1 | 1.6 | | 2 | 0.8 | | 3 | 16.25 | ......... | 50 | 5 | | 51 | 2.5 | | 52 | 29 | | 53 | 3.5 | +----+--------+
And I need to find some combination of those that add up to a certain amount. I put together this quick recursive script that comes up with a solution:
$available = array(
1 => 1.6,
2 => 0.8,
3 => 16.25,
.....
50 => 5,
51 => 2.5,
52 => 29,
53 => 3.5,
);
function findCombination($count_needed, $amount_needed, $remaining)
{
if ($count_needed < 0) return false;
foreach ($remaining as $id => $this_amount) {
if ($count_needed == 1 && $this_amount == $amount_needed) {
echo "Found: {$id} for {$amount_needed}\n";
return true;
} else {
unset($remaining[$id]);
$correct = findCombination($count_needed - 1, $amount_needed - $this_amount, $remaining);
if ($correct) {
echo "Found: {$id} for {$this_amount}\n";
return true;
}
}
}
return false;
}
$count_needed = 9;
$amount_needed = 418;
findCombination($count_needed, $amount_needed, $available);
This will output something like:
Looking for 9 transactions totaling 418 Found: 38 for 59 Found: 37 for 45.5 Found: 36 for 34.75 Found: 33 for 44.75 Found: 31 for 57.75 Found: 30 for 48 Found: 26 for 23.5 Found: 22 for 2.5 Found: 20 for 102.25