You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求1000+个桶的4元组合筛选方案:总重量<100kg

可行解决方案

1. 排序+剪枝+二分查找优化

先将所有桶的重量按从小到大排序,这是核心优化的基础。排序后可以通过剪枝和二分查找大幅减少无效组合的遍历:

  • 提前终止无效分支:比如当选中前k个桶的总和,加上后续最小的(4-k)个桶的总和已≥100时,直接跳过当前分支,无需继续遍历。
  • 用二分查找快速定位有效范围:对于已选的3个桶,计算剩余允许的最大重量(100 - 三个桶的总和),通过二分查找找到数组中最后一个符合条件的桶的索引,一次性确定所有可搭配的第四个桶,避免逐个遍历。

示例代码:

import bisect

# 假设weights是所有桶的重量列表
weights.sort()
valid_combinations = []

n = len(weights)
for i in range(n - 3):
    w1 = weights[i]
    # 前四个最小的组合已超标,后续更大的组合必然超标,直接终止循环
    if w1 + weights[i+1] + weights[i+2] + weights[i+3] >= 100:
        break
    for j in range(i+1, n - 2):
        w12 = w1 + weights[j]
        if w12 + weights[j+1] + weights[j+2] >= 100:
            break
        for k in range(j+1, n - 1):
            w123 = w12 + weights[k]
            # 处理浮点数精度,避免等于100的情况被误判
            max_allowed = 100 - w123 - 1e-9
            # 找到第一个大于max_allowed的索引,减1就是最大有效索引
            l_upper = bisect.bisect_left(weights, max_allowed, k+1) - 1
            if l_upper > k:
                # 批量生成所有有效4元组
                for l in range(k+1, l_upper + 1):
                    valid_combinations.append((weights[i], weights[j], weights[k], weights[l]))
                # 若仅需统计数量,直接累加(l_upper - k)即可,无需生成每个组合

2. 重复重量的组合数优化

如果存在大量重量相同的桶,可先去重并记录每个重量对应的桶的数量,用组合数学公式计算有效组合数,避免生成重复组合:

  • 比如有m个重量为w的桶,从中选k个的组合数为math.comb(m, k)
  • 跨不同重量的组合,比如选2个w1和2个w2,组合数为math.comb(m1,2)*math.comb(m2,2)

这种方式能将万亿级的枚举量直接压缩为数学计算,速度提升几个数量级。

3. 分块处理(超大数据量场景)

当桶的数量过万时,全量处理可能导致内存溢出,可将排序后的数组分块处理:

  • 拆分数组为多个小模块,分别计算:
    • 单模块内的4元组合
    • 跨2个模块的组合(1+3、2+2、3+1)
    • 跨3个模块的组合(1+1+2、1+2+1、2+1+1)
    • 跨4个模块的组合(1+1+1+1)
  • 每块处理完成后直接输出结果,再清理内存处理下一块,避免内存过载。

关键注意事项

  • 浮点数精度:若重量为浮点数,判断总和时需预留微小误差(如sum < 100 - 1e-9),避免因精度问题误判临界值。
  • 优先级:优先用重复重量的组合数计算,其次是排序+剪枝+二分查找,最后考虑分块处理,根据数据规模选择最优方案。

内容的提问来源于stack exchange,提问作者vamshi krishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:47:43