I've programmed multi-head weighers and created my own recursive function in ANSI C to do it, though it would be possible to make it non-recursive and do things long hand with FOR loops easily enough (at the cost of processing power). My algorithm works for any number of heads, but the more heads you have, the more possible combinations to check. My program runs on a standard B&R PLC from 2007 and handles 24 head combination scales for a major packaging company at a cycle time of 4 dumps per second. When put on their fastest PLC from last year, it could get the cycle time down less than a hundredth of a second (much faster than the vertical baggers it goes on). So yes, these are run by PLCs these days to great effect.
Lets say you have 24 heads on the weigher (16,777,215 possible combinations of any number of buckets) and they are set to shoot for 20% of the total bag weight (average 5 buckets to get final weight). A vibrator or something starts filling buckets and when they get close to their 20% target, the top gate closes or whatever to stop more product going in. You can end up with buckets with next to nothing in them or really over full ones with like 70% final weight in them. You specify that it will take between 3 and 7 buckets to fill a bag to cut down on combination permutations and you start generating the weight of every possible combination of 3 to 7 buckets to see which one is the lowest that still meets the minimum. Bucket 1, 2 and 3? Too light. Bucket 1, 2, 3, and 4? 3 grams over. Etc.
So yes, good scales are brute force calculating thousands or even millions of possible combinations to pick the best one. The trick is paring things down to speed up the algorithm. You do things like knowing that bucket 1 + bucket 5 is already heavier than your best combination so far, so no need to check any other combinations that contain buckets 1 and 5. Of course, saying up front to only check combinations with 3 to 7 buckets instead of all possible combinations can cut things down a lot, especially if that range isn't near half your sample size (for a 24 bucket head, there are only 24 combinations of 1 bucket and 1 combination of 24 buckets, but there are 2,704,156 combinations of 12 buckets).
You also can show preference to buckets that haven't been used in a while or buckets that are really far off from the 20% they were supposed to contain. This prevents you ending up with buckets that never get dumped for a combination and the product in them going stale or whatever.
The most challenging thing is being very efficient with your program, since the same bit of code is going to run thousands of times. If you are able to remove a single multiplication step, you can save a noticeable fraction of a second.