问题: 从 $N$ 个候选集中挑选出 $K$ 个,构建一个能够最大化综合得分的组合。得分计算复杂, 所以我们考虑启发式的算法.

1. greedy boost算法的优化

A. 精准种子筛选 (Precise Seed Selection)

  • 增量正交过滤:结合单因子的 predict_score 计算 seed_priority, 按优先级排序后,只有与已选种子集最大相关性 < 0.7 的因子才能入选。这保证了搜索起点的逻辑多样性。

B. 双阶段呼吸逻辑 (Expansion & Purging)

  1. 扩张阶段 (Expansion) - 带 Top-K 随机化:
    • Top-K 采样(非绝对贪心):从能提升分数的 Top-K(默认 3)个候选者中随机抽取一个加入组合。
  2. 清理阶段 (Purging) - 呼吸机制:扩张停止后,尝试移除组合中的每一个因子。只要移除后分数能提升 >0.001,就将其剔除。
  3. 振荡收敛:上述两个阶段在 while True 中交替,直到没有任何变动。

2. 遗传算法的优化

A. 初始化组合

  • 启发式权重初始化:利用 ind_scores 分布进行概率采样。
  • 参数选择: pop_size(初始化种群数量) gen_size(迭代次数)
    • 完全随机的情况下, pop_size为了保证某个特定因子在初始种群中至少出现一次的概率达到 99%:每个个体没有被选中的概率为 $1-\frac{50}{4439} \approx 0.989$。在 pop_size = N 个个体中一次都没出现的概率:$(0.989)^N < 0.01$ 解得:$N > 418$。
    • 每次迭代的选择操作都会有劣势基因被彻底淘汰, gen_size应该是pop_size的对数( Birth–death_process )

      B. 交叉和局部搜索

  • 共性保留交叉:锁定父母共有的“优良基因块”,仅对分歧位进行交叉。
  • Memetic 局部搜索:在初始化和变异后,强制执行缩减版的“扩张-收缩”爬山逻辑。

3. 算法性能对比总结

  • 遗传算法的交叉特性适合的场景应该是局部中度相关, 而这个问题是高度非线性耦合 的, 导致交叉反倒破坏了组合结构无法产出更优组合1
  • 组合数为 $C(400, 50) \approx 10^{64}$ 数量级, 不适合用任何完全随机的操作.
  • greedy boost和遗传算法的优化手段趋同, 最后结果也相似

代码

ga_optimize_portfolio.py,
optimize_wl_portfolio.py