题目重点:MLE 电面要求找出多组超参数的所有组合并设计测试;本文声明空组和重复值语义,给出迭代枚举与复杂度。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版输入为保持插入顺序的 name→choices 映射,每组任选一个值;值允许重复,重复值会产生重复配置。
- 零组参数产生一个空配置作为笛卡尔积单位元;存在空 choices 的组则无配置。实际 API 可把零组解释成空输出,需现场确认。
解题路线
- 从 [{}] 开始,逐组遍历:对每个已有配置和该组每个候选值,生成一份加入 name→value 的新配置。
- 处理完前 i 组时,不变量是结果恰好包含这些组全部选择的组合,且每个组合恰有 i 个参数;归纳加下一组即可证明完整与不重复路径。
- 先手算两组各两个值,确保排列顺序和参数键正确;再测零组、空 choices、单组、重复候选值及很大乘积时的内存限制。
- 若只需逐个执行实验而非保存全部配置,可改为 generator/DFS 逐个 yield,避免同时持有全部结果。
手动走一遍
learning_rate=[0.01,0.1]、depth=[2,4] 输出四项:(.01,2)、(.01,4)、(.1,2)、(.1,4)。若 depth=[],没有任何完整实验配置;若所有组都不存在,训练版返回一个空配置。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
"""Enumerate every configuration from named hyperparameter choices."""
def hyperparameter_combinations(groups: dict[str, list]):
combinations = [{}]
for name, choices in groups.items():
combinations = [dict(configuration, **{name: choice}) for configuration in combinations for choice in choices]
return combinations
复杂度
m 组、每组长度 n_i、总组合数 P=∏n_i,完整输出至少 Ω(mP) 字段;展示代码每次复制配置,总时间 O(mP)、最终输出空间 O(mP)。组合数可能指数增长,不可能在要求列出全部结果时只用多项式总时间。
易错点与追问
容易失分的边界
- 只拼接相邻两组,三组以上组合不完整。
- 任何一组空时仍返回部分配置。
- 没定义重复候选值是否产生重复配置。
- 把输出规模 P 忽略,声称整体 O(m)。
继续深挖
- 若约束某些参数组合非法,如何在 DFS 中尽早剪枝?
- 如何按需生成下一个配置而不存所有 P 项?
- 如何在分布式实验系统中给每个配置生成稳定 ID?
