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

带依赖的4000个序列测试用例按10%/30%/30%/30%分配的算法咨询

解决带依赖的测试用例序列比例分组问题

嘿,这个问题本质上是带依赖约束的多组背包问题,再加上序列不可拆分的硬性要求,我来给你拆解一套可行的解决方案,完全贴合你提到的10%/30%/30%/30%占比目标:

第一步:先把依赖关系和序列信息理清楚

首先得把核心的基础信息整理到位,否则后续都是空中楼阁:

  • 先统计每个序列(比如s1-s50)包含的测试用例数量,记为每个序列的「大小」;
  • 梳理序列间的依赖关系:比如s3必须在s7之前执行,或者s5和s9是强绑定必须同组?这里默认是执行顺序依赖(即依赖的序列必须在被依赖序列的前面集合或同集合),而且不能有循环依赖(如果有,得先把循环里的序列合并成一个不可拆分的大单元,否则测试用例根本没法跑);
  • 把这些依赖关系转换成有向无环图(DAG),然后做一次拓扑排序,得到一个满足依赖顺序的序列列表——这样后续分组的时候,只要按这个顺序来,就不会打破依赖规则。

第二步:用动态规划+启发式搜索做分组优化

因为我们的目标是把序列分成4组,每组大小尽可能接近400、1200、1200、1200(对应4000总用例的比例),这里分两种场景处理:

场景1:集合是按执行顺序排列的(前一个集合跑完才能跑后一个)

这种情况最常见,比如测试是分阶段执行的。我们可以用前缀和+贪心+局部调整的方式快速找到近似最优解:

  1. 先算拓扑排序后的序列前缀和数组,比如prefix_sum[m]表示前m个序列的总测试用例数;
  2. 找第一个集合:找最小的m1,让prefix_sum[m1]尽可能接近400——比如如果前3个序列总和是380,前4个是420,那先选前3个,或者试试把第4个序列里有没有可能拆分?不行,序列不可拆分,那选380或者420,看哪个偏差小;
  3. 然后在剩下的序列里找第二个集合:让这个子集的总和尽可能接近1200,同样用前缀和找边界;
  4. 第三个集合同理,剩下的归为第四个;
  5. 如果初始分组的偏差太大(比如第四个集合只有1000),就做局部调整:比如把第二个集合末尾的一个小序列移到第三个,或者把第一个集合的一个大序列移到第二个,重新计算总偏差,选最优的组合。

场景2:集合内可以包含非连续的序列(只要依赖满足)

如果你的测试框架允许集合内的序列乱序执行(只要依赖的序列在更早的集合里),那可以用带约束的多目标动态规划:

  • 定义DP状态:dp[m][a][b][c]表示前m个序列,第一个集合总大小是a,第二个是b,第三个是c,第四个就是前m个的总和减去a+b+c;
  • 状态转移:对于第m+1个序列,我们可以把它放到四个集合中的任意一个,但必须满足:如果这个序列依赖某个已分配的序列,那它的集合编号不能比依赖序列的集合编号小;
  • 目标是最小化四个集合大小与目标值的偏差平方和(比如(sum1-400)² + (sum2-1200)² + ...),这样能保证整体偏差最小。

第三步:局部迭代优化

不管用哪种方法得到初始分组,都可以做一轮局部调整来缩小偏差:

  • 检查每个集合的偏差,把相邻集合边界附近的小序列来回移动,看看能不能让总偏差变小;
  • 比如如果第一个集合是390(差10),第二个是1220(超20),那看看第二个集合开头有没有一个大小为10的序列,移到第一个集合,这样两个集合的偏差都变成0,完美。

拿你给的例子验证一下

你说的序列大小是[14,17,25,11,14,14,5],总大小100,目标是10、30、30、30:

  • 拓扑排序后假设顺序不变;
  • 第一个集合找接近10的,选11(偏差+1);
  • 剩下的序列里找接近30的,14+14+5=33(偏差+3);
  • 再剩下的找接近30的,14+17=31(偏差+1);
  • 最后剩下25(偏差-5);
  • 总偏差平方和是1+9+1+25=36,这就是你提到的最优组合,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:10:20