You need to enable JavaScript to run this app. 从宝可梦属性DataFrame筛选合规可重复6行组合的方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

从宝可梦属性DataFrame筛选合规可重复6行组合的方案咨询

问题本质梳理

当前面临的核心效率瓶颈,本质是49个属性行允许重复选取6次,全量可重复组合数约2580万组,硬遍历逐组校验的计算复杂度极高;且这个问题不属于连续优化范畴,硬套常规scipy优化模块反而容易因为非凸、离散属性的问题拉低求解效率。
两个核心规则的本质是:

  • 硬约束:排除max列后剩下的48个属性列,每一列的取值都要从选中的6行里拿到≥预设阈值的最大值,等价于每一个属性列,选中的6行中至少有1行在该列的取值达到阈值要求。
  • 优化目标:所有满足硬约束的组合中,6行的max列累加和越大越好,最后按这个和降序排列所有合规组合。
为什么不建议直接硬套scipy.optimize常规接口

常规scipy优化模块的线性规划、非线性优化接口大多面向连续变量,而这个问题是典型的离散集合覆盖变种——即从49个可选元素里选6次(可重复),满足所有列的覆盖要求,最大化目标和。硬把离散问题松弛成连续求解,不仅解的准确性没保障,额外的整数分支定界开销反而不如针对性的剪枝算法效率高。

高效可落地方案

1. 预处理阶段大幅降本

先对原始DataFrame做两步轻量处理,把后续每一步的计算成本压到最低:

  • 对每一个排除max列的属性列,按照预设阈值对每行做二值映射:只要某行在该列的取值≥阈值,就标记为1,否则为0。处理完之后,每一行就对应一个长度48的0-1特征向量,代表这一行能覆盖哪些属性列的阈值要求。
  • 为了进一步加快计算速度,可以把每个行的48位0-1向量压缩成一个64位整数,后续列覆盖的校验只需要做整数按位或运算,比逐列判断快几个数量级。
  • 最后把所有行按照max列的数值做降序排序,因为优化目标是max和越大越好,优先从max值最高的行开始搜索,天然适配后续剪枝逻辑。

2. 回溯搜索+分支剪枝(比硬遍历快几个数量级)

搜索逻辑非常简单,按照排序后的行顺序依次决策:

  • 每一层搜索决策:对当前行,决定选0次、1次直到剩余可选取的总次数(毕竟总共只选6行),不需要跳转到其他行选重复值。
  • 剪枝规则1(约束剪枝):算当前已经选中的行累计覆盖了多少列,如果剩下所有能选的行(哪怕全选max值最高的剩余行)都补不齐未覆盖的列,直接跳过这个分支,不用往下搜索。
  • 剪枝规则2(目标剪枝):算当前已经累计的max和,就算把剩下的选取额度全选max值最高的行,都达不到已经记录的合规组合的最高max和,直接剪掉这个分支。

这种方式实际运行时,通常只需要遍历整个组合空间的不到1%,就能把所有合规组合全部找出来。

3. 若需要调用scipy生态求解器

如果只需要找到max和最高的那一组最优组合,不需要枚举所有合规结果,可以使用scipy.optimize.milp(混合整数线性规划接口)构造问题,具体构造方式:

  • 决策变量:x_i代表第i行被选中的次数,是整数类型,取值范围0 ≤ x_i ≤6
  • 目标函数:最小化-sum(x_i * max_i),milp默认求解最小值,加负号就等价于最大化总max和
  • 约束条件:
    • 总选取次数约束:sum(x_i) =6
    • 列覆盖约束:对每一个属性列c,所有在c列取值≥阈值的行i,满足sum(x_i) ≥1——确保每个列都有至少一行能达到阈值要求
常见效率踩坑提示
  • 不要提前生成全量2500万组的可重复组合再逐组校验,哪怕每组只花1微秒计算,整体也需要几十秒的运行时间,加上逐列取最大值的开销,速度会非常慢。
  • 二值化预处理不要省略,这一步能把后续的覆盖校验计算量降低90%以上。
  • 不要把允许重复选行的规则想得太复杂,回溯搜索的时候允许在当前行选多次就行,不需要额外生成重复行扩大可选池。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 14:36:02