Generate cartesian product in decreasing sum order
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Generating a Cartesian product in decreasing sum order means producing tuples from several input sequences so that tuples with larger element sums appear first. For small inputs, the simplest solution is to generate every tuple and sort the result. For large inputs, that becomes expensive, and a heap-based best-first algorithm can produce tuples in the right order without materializing the full product up front.
The Simple Solution: Generate and Sort
If the total product size is modest, use itertools.product and sort by sum.
This is easy to read and correct. The downside is that it builds the entire Cartesian product in memory and sorts all of it afterward.
That is fine when the product size is small enough that clarity matters more than optimization.
Why Large Products Need a Different Approach
Suppose you have three lists of length 1,000. The Cartesian product contains one billion tuples. Generating all of them just to sort by sum is not realistic.
If the input lists are sorted in descending order, you can do something smarter. The tuple made from all first elements has the maximum possible sum. From there, you can explore neighboring tuples in best-first order using a max-heap.
Heap-Based Best-First Generation
The idea is:
- sort each input list in descending order
- start from the tuple using index
0in every list - store candidates in a heap keyed by tuple sum
- each time you pop the current best tuple, push neighbors formed by advancing one index
Here is a working version:
This yields tuples from highest sum downward without generating the entire product first.
Why the Heap Approach Works
When each list is sorted descending, moving forward in any dimension cannot increase the tuple sum. That monotonic property is what makes best-first exploration valid.
The heap always exposes the largest not-yet-emitted candidate. The seen set prevents the same index combination from being inserted multiple times through different paths.
This is similar in spirit to best-first search on a grid of index combinations.
When to Use Each Approach
Use generate-and-sort when:
- the product is small
- code simplicity matters most
- you need all tuples anyway
Use the heap-based generator when:
- the product is huge
- you only need the first few highest-sum tuples
- input lists can be sorted descending
That second case is common in search, ranking, and top-k problems where the full Cartesian product is far larger than the answer you actually need.
Tie Handling and Custom Ordering
Two different tuples can have the same sum. The algorithms above do not guarantee any special secondary ordering among ties unless you add one yourself.
If you want a stable tiebreaker, sort with a compound key:
For the heap-based version, you would include a secondary key in the heap entry if deterministic tie behavior matters.
Common Pitfalls
The first pitfall is generating the full product for a problem that only needs the top few results. That wastes both memory and time.
Another issue is applying the heap-based method without first sorting the input lists in descending order. Without that monotonic structure, the best-first logic no longer guarantees correct output order.
Developers also forget to track visited index combinations, which causes duplicate tuples to be pushed into the heap repeatedly.
Finally, do not ignore tie behavior if your application depends on deterministic ordering among equal sums.
Summary
- For small inputs,
itertools.productplus sorting is the simplest correct solution. - For large inputs, a max-heap can generate tuples lazily in decreasing sum order.
- The heap-based method relies on each input list being sorted descending.
- Track visited index combinations to avoid duplicates.
- Choose the approach based on product size and whether you need all tuples or only the top results.

