量化交易中文教材

第 12 章 约束优化理论

学习目标

读完本章,你应当能够:

  1. 写出一般约束优化问题的 Lagrange 函数和 KKT 条件,逐条说明每个条件的含义(平稳性、可行性、乘子符号、互补松弛),并能在具体问题上求出 KKT 点、判断哪些是解。
  2. 理解约束规范(LICQ、MFCQ、线性约束)为什么需要,以及它失效时 KKT 条件会出什么问题。
  3. 跟随原书的完整证明链:局部最优 ⇒ 可行序列的极限方向非下降 ⇒(LICQ)极限方向即线性化锥 ⇒(Farkas 引理)乘子存在。
  4. 把乘子解释为影子价格,用 \(df^*/d\epsilon=-\lambda_i^*\|\nabla c_i\|\) 量化"放松一条约束值多少钱"。
  5. 用临界锥和投影 Hessian \(Z^T\nabla^2_{xx}\mathcal LZ\) 检验二阶条件,判断问题是否为凸规划,知道凸规划中 KKT 点即全局最优。
  6. 对均值–方差组合优化(预算约束、目标收益约束、只做多、权重上限)写出并解读 KKT 条件:等边际原则、两基金分离、约束的影子价格,并用代码数值验证。

读前导读

这一章在解决什么问题

前面各章做的是"无约束"优化:想往哪里走就往哪里走,最优点处梯度为零。现实问题几乎都带约束:组合权重加起来要等于 1,不能做空,单只股票不超过 10%,行业偏离不超过 3%。这时最优点往往"顶在墙上",梯度并不为零,旧的判断标准失效了。本章回答一个问题:带约束时,怎样判断一个点是最优的? 答案就是 KKT 条件。

你其实早就见过它的结论,只是没见过推导。CFA 里的最小方差组合、有效前沿、两基金分离、切点组合,全是本章 KKT 条件的直接推论(12.10 节会逐条推出来)。公司金融里的资本限额(capital rationing)问题也是同一个结构:预算有限,项目很多,按盈利指数(PI)排序选项目。那个"排到哪里为止"的门槛,就是本章的 Lagrange 乘子,经济学叫影子价格:约束资源再多给一单位,最优目标值能改善多少。

本章最值得带走的一句话:乘子就是约束的边际价值。 预算约束的乘子告诉你"多 1 元资本值多少 NPV";权重上限的乘子告诉你"这条风控限制每年让你损失多少期望收益"。没用满的资源,边际价值为零(互补松弛);用满的资源,边际价值非负(乘子符号)。KKT 条件的五行公式,翻译成财务语言就是这两句话加上"所有在用的资源,边际收益必须相等"。

需要先想起来的数学

1. 偏导数与梯度 \(\nabla f\)。 多个变量的函数,对其中一个变量求导、其他变量当常数,叫偏导数。把所有偏导数排成一列,就是梯度 \(\nabla f(x)\)(读作 nabla f),它指向函数上升最快的方向,长度是上升速率。例:\(f(x_1,x_2)=x_1+x_2\),\(\nabla f=(1,1)^T\);\(c(x)=x_1^2+x_2^2\),\(\nabla c=(2x_1,2x_2)^T\),在 \((1,1)\) 处是 \((2,2)^T\),正好指向圆外。一阶近似 \(f(x+d)\approx f(x)+\nabla f(x)^Td\) 和久期近似"价格变化 ≈ −久期 × 收益率变化"是同一回事,只是变量多了。见 第 00 册第 05 章 多元微积分与优化。

2. Hessian \(\nabla^2 f\) 与正定。 二阶偏导数排成的矩阵,描述曲率,是凸性的多元版本。矩阵 \(H\) 正定(记作 \(H\succ0\))指对任何非零向量 \(w\) 都有 \(w^THw>0\),即沿任何方向都向上弯;半正定(\(H\succeq0\))允许等于 0。协方差矩阵 \(\Sigma\) 一定半正定,因为 \(w^T\Sigma w\) 是组合方差,不可能为负。见 第 00 册第 06 章 线性代数速成。

3. 拉格朗日乘子的基本做法。 有等式约束 \(c(x)=0\) 时,构造 \(\mathcal L=f-\lambda c\),让 \(\mathcal L\) 对 \(x\) 的偏导为零,再加上约束本身,联立求解。例:\(\min x_1^2+x_2^2\) s.t. \(x_1+x_2=2\),\(\mathcal L=x_1^2+x_2^2-\lambda(x_1+x_2-2)\),得 \(2x_1=\lambda\)、\(2x_2=\lambda\),所以 \(x_1=x_2=1\),\(\lambda=2\)。本章把它推广到不等式约束。见 第 00 册第 05 章。

4. 线性无关、零空间与秩。 一组向量线性无关,指其中任何一个都不能由其他几个线性组合出来。矩阵 \(A\) 的零空间 \(\operatorname{Null}(A)\) 是所有满足 \(Aw=0\) 的 \(w\),几何上就是"与 \(A\) 每一行都垂直"的方向。例:\(A=(1,1)\),零空间是 \(\{(t,-t)\}\),即"一只股票加仓、另一只同等减仓、总权重不变"的方向。见 第 00 册第 06 章。

5. 小 o 记号与证明的读法。 \(o(h)\) 表示"比 \(h\) 更快趋于零的量",即 \(o(h)/h\to0\)。泰勒展开里把高阶项统统写成 \(o(\cdot)\),意思是"步子足够小时可以忽略"。12.5 节是一个三步反证链,读之前可以先看 第 00 册第 08 章 读懂数学证明与符号 里"反证法"和"当且仅当"的读法。

怎么读这一章

核心必读是 12.2(三个小例子,KKT 的全部直觉都在这里)、12.3(KKT 条件本身)、12.4(影子价格)、12.7(凸规划中 KKT 就是全局最优)和 12.10(组合优化的 KKT 分析)。建议按 12.2 → 12.3 → 12.4 → 12.10 → 12.7 的顺序先读一遍,每个公式都对照一个金融场景。

第一次可以只看结论的是 12.5(KKT 的完整证明)、12.6 的证明部分、12.8(其他约束规范)和 12.9(几何观点)。12.5 的价值在于理解"为什么需要约束规范",但对实务来说,记住引理 12.8 的结论就够了:组合优化的约束全是线性的,KKT 条件一定适用。 12.11 的代码建议边读 12.10 边跑,尤其是代码二的输出表格,它把等边际原则和影子价格变成了看得见的数字。


12.1 问题、局部解与光滑化

从本章起进入原书第二部分:带约束的优化。一般形式是

\[ \min_{x\in\mathbb R^n}f(x)\quad\text{s.t.}\quad \begin{cases}c_i(x)=0, & i\in\mathcal E,\\ c_i(x)\ge0, & i\in\mathcal I,\end{cases}\tag{12.1} \]

\(f\) 与 \(c_i\) 光滑,\(\mathcal E\)、\(\mathcal I\) 分别是等式和不等式约束的指标集。可行集 \(\Omega=\{x:c_i(x)=0\ (i\in\mathcal E);\ c_i(x)\ge0\ (i\in\mathcal I)\}\)。注意原书的不等式约定是"\(c_i\ge0\)",与很多凸优化教材和软件的"\(g_i\le0\)"相反,12.3.4 节会给出对照表。

本章的目标是给出约束问题解的刻画——类比无约束情形的必要条件(\(\nabla f=0\)、\(\nabla^2f\succeq0\))和充分条件(\(\nabla f=0\)、\(\nabla^2f\succ0\))。这些条件是所有约束优化算法的理论基础:算法停在哪里、怎么判断收敛、乘子怎么估计,都来自本章。对量化而言,组合优化的几乎所有经典结论都是本章 KKT 条件的直接推论。

12.1.1 局部解与全局解

\(x^*\) 是局部解,若 \(x^*\in\Omega\) 且存在邻域 \(\mathcal N\) 使 \(f(x)\ge f(x^*)\) 对所有 \(x\in\mathcal N\cap\Omega\) 成立;严格不等号(\(x\ne x^*\) 时)对应严格局部解;若 \(x^*\) 是 \(\mathcal N\cap\Omega\) 中唯一的局部极小点,叫孤立局部解。

约束可能排除许多局部极小,使全局最优更容易找;也可能制造大量局部解。例如 \(\min\|x\|_2^2\) s.t. \(\|x\|_2^2\ge1\):无约束时唯一解是 \(x=0\),加约束后单位球面上每一点都是解。又如

\[ \min\ (x_2+100)^2+0.01x_1^2\quad\text{s.t.}\quad x_2-\cos x_1\ge0,\tag{12.4} \]

无约束解是 \((0,-100)\),加约束后在 \((k\pi,-1)\)(\(k=\pm1,\pm3,\pm5,\dots\))附近有无穷多个互不连通的局部解。组合优化中加入"持仓股票数不超过 \(K\)"这类非凸约束后,局部解的数目会爆炸,原因与此相同。

12.1.2 把非光滑问题改写成光滑约束问题

可行域边界常有棱角,但通常可以用几条光滑约束描述。菱形 \(|x_1|+|x_2|\le1\) 等价于四个线性约束 \(\pm x_1\pm x_2\le1\)。更重要的技巧是引入辅助变量把非光滑目标变成光滑约束:

\[ \min_x\ \max(x^2,x)\quad\Longleftrightarrow\quad\min_{x,t}\ t\quad\text{s.t.}\quad t\ge x,\ t\ge x^2.\tag{12.7–12.8} \]

目标是若干函数的最大值、或者向量的 \(\ell_1\)、\(\ell_\infty\) 范数时,都可以这样做。这一招在量化里极其常用:

  • \(\ell_1\) 交易成本 \(\sum_i c_i|w_i-w_i^0|\):令 \(w_i-w_i^0=u_i-v_i\),\(u_i,v_i\ge0\),成本变为线性的 \(\sum c_i(u_i+v_i)\);
  • 最大回撤、最大跟踪偏离这类 \(\max\) 型指标:引入上界变量 \(t\);
  • CVaR:Rockafellar–Uryasev 把 \(\text{CVaR}_\alpha\) 写成 \(\min_\zeta\ \zeta+\frac1{(1-\alpha)S}\sum_s[\text{loss}_s-\zeta]^+\),再对每个情景引入辅助变量 \(u_s\ge\text{loss}_s-\zeta\)、\(u_s\ge0\),整个问题变为线性规划。

12.2 从三个例子看最优性条件

术语:可行点 \(x\) 处,不等式约束 \(i\in\mathcal I\) 若 \(c_i(x)=0\) 称为活跃(active),\(c_i(x)>0\) 称为非活跃(inactive)。等式约束总是活跃的。

12.2.1 例 12.1:单个等式约束

\[ \min\ x_1+x_2\quad\text{s.t.}\quad x_1^2+x_2^2-2=0.\tag{12.9} \]

可行集是半径 \(\sqrt2\) 的圆周,解是 \(x^*=(-1,-1)^T\)。圆上任何其他点都能沿圆周移动使 \(f\) 下降。在解处,约束法向 \(\nabla c_1(x^*)=(-2,-2)^T\) 与 \(\nabla f(x^*)=(1,1)^T\) 平行:

\[ \nabla f(x^*)=\lambda_1^*\nabla c_1(x^*),\qquad \lambda_1^*=-\tfrac12.\tag{12.10} \]

为什么必须平行? 从可行点 \(x\) 走一小步 \(d\),要保持可行需 \(0=c_1(x+d)\approx c_1(x)+\nabla c_1^Td\),即 \(\nabla c_1(x)^Td=0\);要使目标下降需 \(\nabla f(x)^Td<0\)。最优的必要条件是不存在同时满足两者的 \(d\)。若 \(\nabla f\) 与 \(\nabla c_1\) 不平行,则方向

\[ d=-\Big(I-\frac{\nabla c_1\nabla c_1^T}{\|\nabla c_1\|^2}\Big)\nabla f(x)\tag{12.14} \]

(负梯度在约束切空间上的投影)同时满足两者。

推导拆解:为什么 (12.14) 这个 \(d\) 两个条件都满足?记 \(a=\nabla c_1\),\(g=\nabla f\),\(P=I-\frac{aa^T}{\|a\|^2}\)。 第一步,验证保持可行:\(a^Td=-a^Tg+\frac{(a^Ta)(a^Tg)}{\|a\|^2}=-a^Tg+a^Tg=0\)。\(P\) 的作用就是把 \(g\) 中沿 \(a\) 方向的分量减掉,只留下与 \(a\) 垂直的部分。 第二步,验证下降:\(g^Td=-g^TPg=-\big(\|g\|^2-\frac{(a^Tg)^2}{\|a\|^2}\big)\)。由 Cauchy–Schwarz 不等式 \((a^Tg)^2\le\|a\|^2\|g\|^2\),括号非负;等号当且仅当 \(g\) 与 \(a\) 平行。所以只要不平行,\(g^Td<0\)。 金融上可以这样理解:\(a=\nabla c_1\) 是"会破坏约束的方向",\(P\) 把它剔掉,就像把组合调整中改变总权重的部分剔掉、只保留"一边加一边减"的部分。只要剔完后还剩下改善目标的空间,当前点就不是最优。

引入 Lagrange 函数 \(\mathcal L(x,\lambda_1)=f(x)-\lambda_1c_1(x)\),(12.10) 就是 \(\nabla_x\mathcal L(x^*,\lambda_1^*)=0\),\(\lambda_1\) 叫 Lagrange 乘子。这一条件必要但不充分:\(x=(1,1)\)(\(\lambda_1=\tfrac12\))也满足,它却是 \(f\) 在圆上的最大点。等式约束的乘子也没有符号限制:把约束写成 \(2-x_1^2-x_2^2=0\),解不变,乘子却从 \(-\tfrac12\) 变成 \(\tfrac12\)。

12.2.2 例 12.2:单个不等式约束

\[ \min\ x_1+x_2\quad\text{s.t.}\quad 2-x_1^2-x_2^2\ge0.\tag{12.17} \]

可行域是圆盘,\(\nabla c_1\) 在边界上指向内部。解仍是 \((-1,-1)\),平行条件在 \(\lambda_1^*=\tfrac12\) 时成立,但这回乘子的符号很重要。保持可行的条件变为 \(c_1(x)+\nabla c_1(x)^Td\ge0\)。

  • 情形 I(内点,\(c_1(x)>0\)):任何足够短的 \(d\) 都保持可行;只要 \(\nabla f\ne0\),取 \(d=-c_1(x)\nabla f/\|\nabla f\|\) 即可下降。所以内点处最优要求 \(\nabla f(x)=0\)。
  • 情形 II(边界,\(c_1(x)=0\)):要求 \(\nabla f^Td<0\)(开半空间)和 \(\nabla c_1^Td\ge0\)(闭半空间)。两者不相交,当且仅当
    \[ \nabla f(x)=\lambda_1\nabla c_1(x),\qquad\lambda_1\ge0.\tag{12.20} \]
    若 \(\lambda_1<0\),两个梯度反向,满足条件的方向构成整个开半平面。

两种情形可以统一写成

\[ \nabla_x\mathcal L(x^*,\lambda_1^*)=0,\quad \lambda_1^*\ge0,\quad \lambda_1^*c_1(x^*)=0.\tag{12.21–12.22} \]

最后一个条件叫互补条件(complementarity):乘子只有在约束活跃时才可能为正。情形 I 中 \(c_1>0\) 迫使 \(\lambda_1^*=0\),退化为 \(\nabla f=0\);情形 II 中就是 (12.20)。

金融直觉:互补条件 \(\lambda_1c_1=0\) 就是"没用完的资源不值钱"。设想一个部门的年度资本预算 1000 万,最后只批了 800 万的项目。这时再追加 1 元预算,什么都不会改变,预算的边际价值(乘子)为 0。反过来,只有预算被花光(约束活跃、\(c_1=0\)),追加预算才可能带来好处,乘子才可能为正。两者至少有一个为零,乘积必然为零。 乘子非负 \(\lambda_1\ge0\) 也有直接含义:放宽一个"\(\ge\)"型限制,最优结果只会变好或不变,不会变差。多给预算不会让你选出更差的项目组合,因为你总可以不用多给的那部分。

几何直观:不等式约束的乘子非负,是因为约束只能"推"不能"拉"——它阻止你往可行域外走,但不阻止你往里走。最优点处,目标的下降方向 \(-\nabla f\) 必须恰好被约束的"墙"挡住,即 \(-\nabla f\) 指向可行域外(与 \(\nabla c_1\) 反向),也就是 \(\nabla f=\lambda\nabla c_1\)、\(\lambda\ge0\)。

12.2.3 例 12.3:两个不等式约束

\[ \min\ x_1+x_2\quad\text{s.t.}\quad 2-x_1^2-x_2^2\ge0,\quad x_2\ge0.\tag{12.23} \]

可行域是上半圆盘,解 \(x^*=(-\sqrt2,0)^T\),两个约束都活跃。条件推广为

\[ \nabla_x\mathcal L(x^*,\lambda^*)=0,\quad\lambda^*\ge0,\quad\lambda_1^*c_1(x^*)=0,\ \lambda_2^*c_2(x^*)=0,\tag{12.25–12.26} \]

\(\mathcal L=f-\lambda_1c_1-\lambda_2c_2\)。在 \(x^*\) 处 \(\nabla f=(1,1)^T\),\(\nabla c_1=(2\sqrt2,0)^T\),\(\nabla c_2=(0,1)^T\),取 \(\lambda^*=(\tfrac1{2\sqrt2},1)^T\),两个分量都为正。

对照两个非最优点:

  • \(x=(\sqrt2,0)\):两个约束也都活跃,但 \(\nabla_x\mathcal L=0\) 要求 \(\lambda=(-\tfrac1{2\sqrt2},1)\),\(\lambda_1<0\),违反符号条件;确实 \(d=(-1,0)\) 是可行下降方向。
  • \(x=(1,0)\):只有 \(c_2\) 活跃,互补条件迫使 \(\lambda_1=0\),需要 \(\nabla f=\lambda_2\nabla c_2\),即 \((1,1)=\lambda_2(0,1)\),无解;\(d=(-\tfrac12,\tfrac14)\) 是可行下降方向。

这三个例子已经包含了 KKT 条件的全部要素。下面把它们一般化。


12.3 KKT 条件

12.3.1 Lagrange 函数、活跃集与 LICQ

Lagrange 函数:

\[ \mathcal L(x,\lambda)=f(x)-\sum_{i\in\mathcal E\cup\mathcal I}\lambda_ic_i(x).\tag{12.28} \]

活跃集:\(\mathcal A(x)=\mathcal E\cup\{i\in\mathcal I:c_i(x)=0\}\)。

\(\nabla c_i(x)\) 叫约束 \(c_i\) 在 \(x\) 处的法向,一般垂直于约束的等值线,对不等式约束指向可行一侧。但约束的代数写法可能让法向退化。例如把 (12.9) 的约束写成 \((x_1^2+x_2^2-2)^2=0\),可行集完全一样,但所有可行点处 \(\nabla c_1=0\),在最优点 \(\nabla f=\lambda_1\nabla c_1\) 不再可能成立。所以需要一个约束规范(constraint qualification)排除这类退化。最常用的是:

定义 12.1(LICQ,线性无关约束规范):在 \(x^*\) 处,活跃约束梯度 \(\{\nabla c_i(x^*),\ i\in\mathcal A(x^*)\}\) 线性无关。

12.3.2 一阶必要条件

定理 12.1(一阶必要条件 / KKT 定理):设 \(x^*\) 是 (12.1) 的局部解,且 LICQ 在 \(x^*\) 成立,则存在 Lagrange 乘子向量 \(\lambda^*\) 使

\[ \boxed{\begin{aligned} &\nabla_x\mathcal L(x^*,\lambda^*)=0, &&\text{(12.30a) 平稳性}\\ &c_i(x^*)=0,\ i\in\mathcal E, &&\text{(12.30b) 等式可行}\\ &c_i(x^*)\ge0,\ i\in\mathcal I, &&\text{(12.30c) 不等式可行}\\ &\lambda_i^*\ge0,\ i\in\mathcal I, &&\text{(12.30d) 对偶可行}\\ &\lambda_i^*c_i(x^*)=0,\ i\in\mathcal E\cup\mathcal I. &&\text{(12.30e) 互补松弛} \end{aligned}} \]

这就是 Karush–Kuhn–Tucker(KKT)条件,满足它的 \((x^*,\lambda^*)\) 叫 KKT 点。(Kuhn 与 Tucker 在 1951 年发表;W. Karush 在 1939 年的硕士论文里已独立导出,但未发表。)因为非活跃约束的乘子为零,平稳性可以只写活跃约束:

\[ \nabla f(x^*)=\sum_{i\in\mathcal A(x^*)}\lambda_i^*\nabla c_i(x^*).\tag{12.31} \]

用一句话记住 KKT:在最优点,目标的梯度可以写成活跃约束法向的组合,其中不等式约束的系数非负。

白话解释:把五行条件逐条翻成资本预算的语言。设公司在若干项目上分配资金 \(x\),目标是 \(\min f=-\text{NPV}(x)\),约束包括资本预算、人员上限等。 (12.30a) 平稳性:每个项目上多投 1 元带来的边际 NPV,恰好等于它消耗的各种资源乘以各自的影子价格之和。边际收益 = 边际资源成本,这就是微观经济学的"边际收益等于边际成本"。 (12.30b)(12.30c) 可行性:方案必须守规矩,预算不能超。 (12.30d) 对偶可行:稀缺资源的影子价格不能为负。 (12.30e) 互补松弛:没用满的资源影子价格为零;影子价格为正的资源一定用满了。 这里的符号:\(\mathcal E\)、\(\mathcal I\) 是等式、不等式约束的编号集合,\(i\in\mathcal I\) 读作"\(i\) 属于不等式约束";\(\lambda^*\) 的星号表示"最优点处的值"。

定义 12.2(严格互补):对每个 \(i\in\mathcal I\),\(\lambda_i^*\) 与 \(c_i(x^*)\) 恰好有一个为零;即活跃不等式约束的乘子都严格为正。严格互补成立时,活跃集在解附近是"稳定"的,许多算法的局部分析都需要它。

满足 (12.30) 的乘子可能不唯一;LICQ 成立时乘子唯一(原书习题 12.17:活跃梯度线性无关,(12.31) 的系数唯一确定)。

12.3.3 例 12.4

\[ \min_x\ \Big(x_1-\frac32\Big)^2+\Big(x_2-\frac12\Big)^4\quad\text{s.t.}\quad \begin{bmatrix}1-x_1-x_2\\1-x_1+x_2\\1+x_1-x_2\\1+x_1+x_2\end{bmatrix}\ge0.\tag{12.32} \]

可行域是菱形,解 \(x^*=(1,0)^T\),前两个约束活跃。\(\nabla f(x^*)=(-1,-\tfrac12)^T\),\(\nabla c_1=(-1,-1)^T\),\(\nabla c_2=(-1,1)^T\)。由 (12.31):\(-1=-\lambda_1-\lambda_2\),\(-\tfrac12=-\lambda_1+\lambda_2\),解得 \(\lambda^*=(\tfrac34,\tfrac14,0,0)^T\),非负,KKT 成立。

(更正说明:精读笔记把目标第二项记为 \((x_2-\tfrac18)^4\),此时 \(\partial f/\partial x_2=4(-\tfrac18)^3=-\tfrac1{128}\),与原书给出的 \(\nabla f(x^*)=(-1,-\tfrac12)\) 不一致;取 \((x_2-\tfrac12)^4\) 则 \(4(-\tfrac12)^3=-\tfrac12\),全部数字自洽,12.11 节的代码也验证了这一点。)

12.3.4 符号约定对照

读文献、用软件时,乘子的符号约定是最常见的混乱来源:

约定 不等式写法 Lagrange 函数 乘子符号 平稳性
原书(Nocedal–Wright) \(c_i(x)\ge0\) \(f-\sum\lambda_ic_i\) \(\lambda_i\ge0\) \(\nabla f=\sum\lambda_i\nabla c_i\)
Boyd–Vandenberghe 等凸优化教材 \(g_i(x)\le0\) \(f+\sum\mu_ig_i\) \(\mu_i\ge0\) \(\nabla f=-\sum\mu_i\nabla g_i\)

令 \(g_i=-c_i\),两者完全等价。scipy.optimize.minimize 中 {'type':'ineq'} 约束的含义是 \(c(x)\ge0\),与原书一致;CVXPY 等凸优化建模工具一般采用第二种约定,读 dual_value 时要先弄清它对应哪种写法。等式约束的乘子没有符号限制,其正负取决于约束写成 \(c=0\) 还是 \(-c=0\)。


12.4 乘子的含义:敏感性与影子价格

乘子 \(\lambda_i^*\) 刻画最优值对约束 \(c_i\) 的敏感程度——目标"推"或"拉"这条约束的力度。

非活跃约束:微小扰动后仍然非活跃,\(x^*\) 仍是局部解,\(\lambda_i^*=0\) 准确地反映了它无关紧要。

活跃约束:把 \(c_i(x)\ge0\) 放松为 \(c_i(x)\ge-\epsilon\|\nabla c_i(x^*)\|\),设 \(\epsilon\) 足够小使活跃集不变、乘子变化不大,记新解为 \(x^*(\epsilon)\)。则

\[ -\epsilon\|\nabla c_i\|=c_i(x^*(\epsilon))-c_i(x^*)\approx(x^*(\epsilon)-x^*)^T\nabla c_i, \]

其他活跃约束 \(0\approx(x^*(\epsilon)-x^*)^T\nabla c_j\)。由平稳性 (12.31),

\[ f(x^*(\epsilon))-f(x^*)\approx(x^*(\epsilon)-x^*)^T\nabla f=\sum_j\lambda_j^*(x^*(\epsilon)-x^*)^T\nabla c_j\approx-\epsilon\|\nabla c_i\|\lambda_i^*. \]

取极限:

\[ \boxed{\frac{df(x^*(\epsilon))}{d\epsilon}=-\lambda_i^*\|\nabla c_i(x^*)\|.}\tag{12.33} \]

\(\lambda_i^*\|\nabla c_i\|\) 大,最优值对这条约束的位置就敏感;放松约束(\(\epsilon>0\))使目标下降,下降速率正是这个量。经济学里这叫影子价格(shadow price)。对等式约束,扰动 \(c_i(x)=\epsilon\) 时同理有 \(df^*/d\epsilon=\lambda_i^*\)(乘子可正可负)。

推导拆解:上面的推导只用了两样东西。第一,一阶泰勒近似 \(f(x^*(\epsilon))-f(x^*)\approx(x^*(\epsilon)-x^*)^T\nabla f\),与"债券价格变化 ≈ −修正久期 × 价格 × 收益率变化"同理。第二,平稳性 (12.31) 把 \(\nabla f\) 换成 \(\sum_j\lambda_j^*\nabla c_j\),于是目标的变化被拆成"每条约束的变化 × 它的乘子"。其他活跃约束没动(变化约为 0),只剩被放松的第 \(i\) 条,变化量 \(-\epsilon\|\nabla c_i\|\) 乘以 \(\lambda_i^*\)。 公式里的 \(\|\nabla c_i\|\) 只是因为原书用"几何距离" \(\epsilon\) 来度量放松幅度。实务中更常见的是直接改约束右端的常数:约束写成 \(b-a^Tx\ge0\),把 \(b\) 改成 \(b+\Delta b\),这时 \(\epsilon\|\nabla c_i\|=\Delta b\),公式化简为 \(\dfrac{df^*}{db}=-\lambda_i^*\)。乘子就是"右端常数每放宽 1 单位,最优目标改善多少"。

金融直觉:用资本预算把影子价格讲透。某公司有 100(百万元)资本,可以分给两个事业部,投入 \(x_1\)、\(x_2\) 产生的 NPV 分别是 \(4\sqrt{x_1}\) 和 \(3\sqrt{x_2}\)(开平方表示边际回报递减)。按原书约定写成 \(\min f=-4\sqrt{x_1}-3\sqrt{x_2}\),s.t. \(c=100-x_1-x_2\ge0\)。 平稳性 \(\nabla f=\lambda\nabla c\) 逐分量写出来:\(-2/\sqrt{x_1}=-\lambda\),\(-1.5/\sqrt{x_2}=-\lambda\)。左边的 \(2/\sqrt{x_1}\) 正是事业部 1 每多投 1 元的边际 NPV。所以平稳性说的是:两个事业部的边际 NPV 相等,都等于 \(\lambda\)。若不相等,把钱从边际回报低的部门挪到高的部门,总 NPV 一定上升。 解得 \(\sqrt{x_1}/\sqrt{x_2}=4/3\),配合 \(x_1+x_2=100\) 得 \(x_1=64\)、\(x_2=36\),总 NPV \(=32+18=50\),\(\lambda=2/8=0.25\)。 检验影子价格:把预算增加到 101,重新按 16:9 分配得 \(x_1=64.64\)、\(x_2=36.36\),总 NPV 约 50.249,增加约 0.25,与 \(\lambda\) 吻合。含义很直接:多融 1 百万元资本,能多创造约 0.25 百万元 NPV。如果追加融资的额外成本(发行费用、更高的资本成本折成现值)低于这个数,就值得融;高于它就不值得。 你在 CFA 公司金融里学的"资本限额下按盈利指数 PI 排序"是同一件事的线性版本:项目可按比例投资时,预算的影子价格等于最后那个被部分投资的项目的"每元投资 NPV";每元 NPV 高于这个门槛的项目全额投,低于门槛的不投。第 13 章线性规划会把这个结论严格化。

定义 12.3:活跃不等式约束 \(c_i\) 若对某个 KKT 乘子 \(\lambda_i^*>0\),称为强活跃(strongly active)或绑定(binding);若对所有 KKT 乘子都有 \(\lambda_i^*=0\),称为弱活跃(weakly active)。弱活跃约束"恰好碰到",但放松它一阶意义上没有好处。

尺度无关性:把 \(c_i\) 换成 \(10c_i\),问题不变,\(\lambda_i^*\) 变为原来的 \(1/10\),但 \(\|\nabla c_i\|\) 变为 10 倍,乘积不变;把 \(f\) 换成 \(10f\),所有乘子变为 10 倍,敏感性也变为 10 倍,符合直觉。实务启示:比较不同约束的"昂贵程度"时,不能直接比乘子大小,必须统一到同一单位——比如都换算成"每放松 1% 权重上限,目标改善多少",或者都换算成年化期望收益的等价值。


12.5 KKT 条件的证明

原书强调:这一完整证明是理解所有约束优化算法的关键。证明分三步。

12.5.1 第一步:可行序列与极限方向

可行序列:给定可行点 \(x^*\),序列 \(\{z_k\}\) 满足 (i) \(z_k\ne x^*\);(ii) \(z_k\to x^*\);(iii) \(k\) 充分大时 \(z_k\) 可行。所有这样的序列记为 \(T(x^*)\)。局部解的刻画是:所有可行序列在 \(k\) 充分大时都有 \(f(z_k)\ge f(x^*)\)。

极限方向:\(d\) 是可行序列的极限方向,若沿某个子序列 \(\frac{z_k-x^*}{\|z_k-x^*\|}\to d\)。单位向量落在紧的单位球面上,所以至少有一个极限方向。

例如在例 12.1 的非最优点 \(x=(-\sqrt2,0)\) 附近,可行序列 \(z_k=(-\sqrt{2-1/k^2},\,-1/k)\) 的极限方向是 \((0,-1)\),\(f\) 沿它递减——所以 \(x\) 不是解。不等式约束下可行序列多得多:既可以沿边界趋近,也可以从内部沿直线、曲线甚至随机地趋近。

定理 12.2:若 \(x^*\) 是局部解,则所有可行序列的任一极限方向 \(d\) 满足

\[ \nabla f(x^*)^Td\ge0.\tag{12.37} \]

证明:若某可行序列有极限方向 \(d\) 使 \(\nabla f^Td<0\),沿对应子列由 Taylor 定理, \(f(z_k)=f(x^*)+\|z_k-x^*\|\,d^T\nabla f(x^*)+o(\|z_k-x^*\|)<f(x^*)+\tfrac12\|z_k-x^*\|\,d^T\nabla f(x^*)<f(x^*)\), 在 \(x^*\) 的任意邻域内都有函数值更小的可行点,矛盾。证毕。

推导拆解:这是一个反证法:先假设结论不成立,推出矛盾。 第一步,写出 \(z_k\):因为 \(\frac{z_k-x^*}{\|z_k-x^*\|}\to d\),所以 \(z_k-x^*=\|z_k-x^*\|d+o(\|z_k-x^*\|)\),即"步长 × 方向 + 可忽略的误差"。 第二步,一阶泰勒展开 \(f(z_k)=f(x^*)+\nabla f^T(z_k-x^*)+o(\|z_k-x^*\|)\),代入上式得到第一个等号。 第三步,第一个"<":\(d^T\nabla f<0\) 是一个固定的负数,\(o(\cdot)\) 项相对于 \(\|z_k-x^*\|\) 趋于零,所以 \(k\) 足够大时误差连 \(\frac12\|z_k-x^*\|d^T\nabla f\) 那么大都不到,可以被吸收掉,只剩一半的负值。 第四步,\(z_k\) 可行、离 \(x^*\) 任意近、函数值却更小,与"局部解"的定义矛盾。 一句话:若存在一条能走进去的下坡路,当前点就不是谷底。

这个定理也说明了为什么可以忽略非活跃约束:只有序列的渐近行为重要,而非活跃约束在序列后段始终满足。

12.5.2 第二步:用 LICQ 刻画极限方向

记 \(A(x^*)\) 为以活跃约束梯度 \(\nabla c_i(x^*)^T\)(\(i\in\mathcal A(x^*)\))为行的矩阵。定义线性化可行方向锥

\[ F_1=\{\alpha d:\ \alpha>0,\ d^T\nabla c_i^*=0\ (i\in\mathcal E),\ d^T\nabla c_i^*\ge0\ (i\in\mathcal A(x^*)\cap\mathcal I)\}. \]

引理 12.3: (i) 若 \(d\) 是可行序列的极限方向,则 \(d\in F_1\),即

\[ d^T\nabla c_i^*=0\ (i\in\mathcal E),\qquad d^T\nabla c_i^*\ge0\ (i\in\mathcal A(x^*)\cap\mathcal I).\tag{12.39} \]
(ii) 若 \(d\) 满足 (12.39)、\(\|d\|=1\) 且 LICQ 成立,则 \(d\) 是某个可行序列的极限方向。

证明 (i):\(z_k=x^*+\|z_k-x^*\|d+o(\|z_k-x^*\|)\)。对等式约束,\(0=\frac{c_i(z_k)}{\|z_k-x^*\|}=\nabla c_i^Td+o(1)\),取极限得 \(\nabla c_i^Td=0\);活跃不等式同理得 \(\ge0\)。

证明 (ii)(用隐函数定理构造可行序列):不妨设所有约束都活跃(共 \(m\) 个)。LICQ 说明 \(m\times n\) 矩阵 \(A\) 行满秩,取 \(Z\) 为 \(A\) 的零空间的一组基(\(AZ=0\),\(Z\) 列满秩)。对参数 \(t\) 考虑方程组

\[ R(z,t)=\begin{bmatrix}c(z)-tAd\\ Z^T(z-x^*-td)\end{bmatrix}=0.\tag{12.41} \]

\(t=0\) 时 \(z=x^*\) 是解,且 Jacobian \(\nabla_zR(x^*,0)=\begin{bmatrix}A\\Z^T\end{bmatrix}\) 非奇异。由隐函数定理,对足够小的 \(t_k>0\) 有唯一解 \(z_k\)。由第一行,\(c_i(z_k)=t_k\nabla c_i^Td\):等式约束为 0,活跃不等式 \(\ge0\),所以 \(z_k\) 可行;且 \(z_k\ne x^*\)(否则推出 \(Ad=0\)、\(Z^Td=0\),即 \(d=0\))。再对 \(R(z_k,t_k)=0\) 做 Taylor 展开,\(\begin{bmatrix}A\\Z^T\end{bmatrix}(z_k-x^*-t_kd)=o(\|z_k-x^*\|)\),除以 \(\|z_k-x^*\|\) 并利用非奇异性和 \(\|d\|=1\),得 \(\frac{z_k-x^*}{\|z_k-x^*\|}\to d\)。证毕。

含义:LICQ 下,"真实可行方向"(可行序列的极限方向)恰好等于"线性化后的可行方向" \(F_1\)。于是定理 12.2 的条件等价于:不存在 \(d\in F_1\) 使 \(\nabla f^{*T}d<0\)。

白话解释:引理 12.3 在解决"线性近似可不可信"的问题。真实可行集边界是弯的,\(F_1\) 是把每条活跃约束换成它的切线(一阶泰勒近似)之后得到的"直边"可行区域。(i) 说真实能走的方向一定在 \(F_1\) 里;(ii) 说在 LICQ 下 \(F_1\) 里的方向也都真的能走。两者合起来,才可以放心用线性代数代替弯曲几何。 这和用久期近似债券价格是同一种思路:久期在收益率小幅变动时可靠,但遇到嵌入期权等"退化"情形会失真。LICQ 的角色就是排除退化情形,保证一阶近似不说错话。(ii) 证明里的隐函数定理可以只记结论:方程组的 Jacobian(各方程对各变量的偏导排成的矩阵)可逆时,参数 \(t\) 稍微变一点,方程仍有一个随 \(t\) 平滑变化的解。

12.5.3 第三步:Farkas 引理给出乘子

上述条件仍不便验证(要检查无穷多个方向)。下面的引理——本质上就是 Farkas 引理——把它变成可以检验的乘子条件。

引理 12.4:不存在 \(d\in F_1\) 使 \(d^T\nabla f^*<0\),当且仅当存在 \(\lambda\) 使

\[ \nabla f^*=\sum_{i\in\mathcal A(x^*)}\lambda_i\nabla c_i^*=A(x^*)^T\lambda,\qquad\lambda_i\ge0\ (i\in\mathcal A(x^*)\cap\mathcal I).\tag{12.46} \]

证明:定义锥 \(N=\{s=\sum_{i\in\mathcal A}\lambda_i\nabla c_i^*:\ \lambda_i\ge0\ (i\in\mathcal A\cap\mathcal I)\}\),(12.46) 即 \(\nabla f^*\in N\)。\(N\) 是闭凸锥(闭性直观,严格证明不平凡,LICQ 下见下方注记)。

"⇒":若 (12.46) 成立,对任意 \(d\in F_1\),\(d^T\nabla f^*=\sum_{\mathcal E}\lambda_i(d^T\nabla c_i^*)+\sum_{\mathcal A\cap\mathcal I}\lambda_i(d^T\nabla c_i^*)\ge0\)(第一项为零,第二项非负)。

"⇐"(分离超平面的构造):若 \(\nabla f^*\notin N\),令 \(\hat s\) 为 \(N\) 中离 \(\nabla f^*\) 最近的点。因为 \(t\hat s\in N\)(\(t\ge0\))且 \(t=1\) 最优,对 \(t\) 求导得 \(\hat s^T(\hat s-\nabla f^*)=0\)。又 \(N\) 凸,对任意 \(s\in N\),\(\hat s+\theta(s-\hat s)\)(\(\theta\in[0,1]\))不比 \(\hat s\) 更近,展开取 \(\theta\downarrow0\) 得 \((s-\hat s)^T(\hat s-\nabla f^*)\ge0\),结合上式:

\[ s^T(\hat s-\nabla f^*)\ge0,\qquad\forall s\in N.\tag{12.50} \]

令 \(d=\hat s-\nabla f^*\ne0\)。则 \(d^T\nabla f^*=d^T(\hat s-d)=-\|d\|^2<0\),是下降方向;把 \(s=\pm\nabla c_i^*\)(\(i\in\mathcal E\))和 \(s=\nabla c_i^*\)(\(i\in\mathcal A\cap\mathcal I\))代入 (12.50),得 \(d\in F_1\)。这与假设矛盾。证毕。

(\(N\) 的闭性:LICQ 下若 \(s_k=A^T\lambda_k\in N\)、\(s_k\to s^*\),则 \(\lambda_k=(AA^T)^{-1}As_k\to\lambda^*\),且 \(\lambda^*\) 满足符号条件,\(s^*=A^T\lambda^*\in N\)。一般情形见原书注释引用的 Mangasarian–Schumaker。)

定理 12.1 的证明:由定理 12.2,所有极限方向满足 \(d^T\nabla f^*\ge0\);由引理 12.3(LICQ),极限方向集合恰是 \(F_1\) 中的单位向量;由引理 12.4,存在满足 (12.46) 的 \(\lambda\)。令活跃约束的 \(\lambda_i^*=\lambda_i\)、非活跃约束的 \(\lambda_i^*=0\),逐条验证 (12.30a)–(12.30e) 即可。证毕。

证明链总结:局部最优 ⟹ 可行方向都不下降 ⟹(LICQ)线性化可行方向都不下降 ⟹(Farkas)\(\nabla f\) 落在活跃法向张成的锥中 ⟹ KKT 乘子存在。

金融直觉:Farkas 引理是"二选一"定理:要么存在一个可行的下降方向 \(d\),要么存在一组符号正确的乘子 \(\lambda\),两者恰有一个成立。你在 CFA 衍生品里见过它的孪生兄弟——资产定价基本定理:要么市场存在套利组合,要么存在一组正的状态价格(风险中性概率)给所有资产定价,两者恰有一个成立。数学上二者都是 Farkas 引理。对应关系是:可行下降方向 ↔ 套利组合,KKT 乘子 ↔ 状态价格。最优点"找不到改进方向",正如无套利市场"找不到免费午餐",而它们的"证书"分别是乘子和状态价格。 证明里的锥(cone)指对正数乘法封闭的集合:\(s\) 在里面,\(2s\)、\(0.5s\) 也在。\(N\) 由活跃约束法向的非负组合构成,像一把从原点张开的扇子。"⇐"部分的构造是:若 \(\nabla f\) 不在扇子里,就找扇子中离它最近的点,二者之差 \(d\) 给出一个"把 \(\nabla f\) 与扇子分开"的方向,它恰好是可行的下降方向。


12.6 二阶条件

12.6.1 临界锥

KKT 条件成立时,沿 \(F_1\) 中任意方向 \(w\),一阶近似要么增加(\(w^T\nabla f>0\)),要么不变(\(w^T\nabla f=0\))。对后一类"未决"方向,需要二阶信息来"决胜"(tiebreaking)——考察 Lagrange 函数(而不是 \(f\))的曲率。

临界锥 \(F_2(\lambda^*)\):

\[ w\in F_2(\lambda^*)\iff \begin{cases} \nabla c_i(x^*)^Tw=0, & i\in\mathcal E,\\ \nabla c_i(x^*)^Tw=0, & i\in\mathcal A(x^*)\cap\mathcal I,\ \lambda_i^*>0,\\ \nabla c_i(x^*)^Tw\ge0, & i\in\mathcal A(x^*)\cap\mathcal I,\ \lambda_i^*=0. \end{cases}\tag{12.52} \]

即"贴住"等式约束和强活跃不等式约束、对弱活跃约束只要求不出界的方向。由此 \(\lambda_i^*\nabla c_i^Tw=0\) 对所有 \(i\) 成立,再由平稳性,\(w^T\nabla f(x^*)=0\)——正是一阶信息无法判断增减的方向。

12.6.2 必要条件与充分条件

定理 12.5(二阶必要条件):\(x^*\) 为局部解,LICQ 成立,\(\lambda^*\) 为 KKT 乘子,则

\[ w^T\nabla_{xx}^2\mathcal L(x^*,\lambda^*)\,w\ge0,\qquad\forall w\in F_2(\lambda^*).\tag{12.55} \]

证明要点:对 \(w\in F_2\),用引理 12.3 的构造得到极限方向为 \(w/\|w\|\) 的可行序列 \(z_k\),且活跃约束满足 \(c_i(z_k)=\frac{t_k}{\|w\|}\nabla c_i^Tw\)。由 \(\lambda_i^*\nabla c_i^Tw=0\) 得 \(\mathcal L(z_k,\lambda^*)=f(z_k)\)。另一方面在 \(x^*\) 处 Taylor 展开 \(\mathcal L\),利用 \(\mathcal L(x^*,\lambda^*)=f(x^*)\)(互补性)和 \(\nabla_x\mathcal L=0\):

\[ f(z_k)=\mathcal L(z_k,\lambda^*)=f(x^*)+\tfrac12(t_k/\|w\|)^2\,w^T\nabla^2_{xx}\mathcal L\,w+o(t_k^2). \]

若 \(w^T\nabla^2_{xx}\mathcal Lw<0\),则 \(f(z_k)<f(x^*)\),矛盾。

定理 12.6(二阶充分条件):可行点 \(x^*\) 处存在 KKT 乘子 \(\lambda^*\),且

\[ w^T\nabla^2_{xx}\mathcal L(x^*,\lambda^*)\,w>0,\qquad\forall w\in F_2(\lambda^*),\ w\ne0,\tag{12.63} \]

则 \(x^*\) 是严格局部解。注意:充分条件不需要约束规范。

证明要点:任取可行序列及其极限方向 \(d\in F_1\)。注意 \(\mathcal L(z_k,\lambda^*)=f(z_k)-\sum\lambda_i^*c_i(z_k)\le f(z_k)\)(可行点处 \(\lambda_i^*c_i\ge0\))。分两种情况:若 \(d\notin F_2\),存在强活跃约束 \(j\) 使 \(\lambda_j^*\nabla c_j^Td>0\),这一项给出一阶增长 \(f(z_k)\ge f(x^*)+\|z_k-x^*\|\lambda_j^*\nabla c_j^Td+o(\cdot)>f(x^*)\);若 \(d\in F_2\),二阶项给出 \(f(z_k)\ge f(x^*)+\tfrac12\|z_k-x^*\|^2d^T\nabla^2_{xx}\mathcal Ld+o(\cdot)>f(x^*)\)。

例 12.7:例 12.2 中 \(\nabla^2_{xx}\mathcal L=\operatorname{diag}(2\lambda_1^*,2\lambda_1^*)=I\) 正定,\(x^*=(-1,-1)\) 是严格局部解(这是凸规划,因而是全局解)。

例 12.8(非凸):

\[ \min\ -0.1(x_1-4)^2+x_2^2\quad\text{s.t.}\quad x_1^2+x_2^2-1\ge0.\tag{12.68} \]

在单位圆外部极小化非凸函数。沿 \(x_1\to\infty\) 目标趋于 \(-\infty\),没有全局解,但边界上可能有严格局部解。

\[ \nabla_x\mathcal L=\begin{bmatrix}-0.2(x_1-4)-2\lambda x_1\\2x_2-2\lambda x_2\end{bmatrix},\qquad \nabla^2_{xx}\mathcal L=\begin{bmatrix}-0.2-2\lambda&0\\0&2-2\lambda\end{bmatrix}.\tag{12.69} \]

\(x^*=(1,0)\) 处 \(0.6-2\lambda=0\),\(\lambda_1^*=0.3>0\)。\(\nabla c_1(x^*)=(2,0)^T\),临界锥 \(F_2=\{(0,w_2)^T\}\)。\(\nabla^2_{xx}\mathcal L=\operatorname{diag}(-0.8,1.4)\) 本身不定,但在临界锥上 \(w^T\nabla^2_{xx}\mathcal Lw=1.4w_2^2>0\),所以 \((1,0)\) 是严格局部解。(精读笔记记录原书此处矩阵左上元印为 \(-0.4\),按 (12.69) 应为 \(-0.2-0.6=-0.8\),不影响结论。)要点:只需 Lagrange 函数的 Hessian 在临界锥上正定,不需要整体正定。

推导拆解:为什么二阶条件看 \(\mathcal L\) 的 Hessian 而不是 \(f\) 的?因为可行点只能沿弯曲的边界走,边界的弯曲本身也会改变目标值。用例 12.8 直接算一遍:在单位圆上 \(x_1=\sqrt{1-x_2^2}\approx1-\tfrac12x_2^2\)(对 \(\sqrt{1-u}\) 做一阶泰勒展开)。代入目标:\(x_1-4\approx-3-\tfrac12x_2^2\),平方后 \((x_1-4)^2\approx9+3x_2^2\)(丢掉 \(x_2^4\)),于是 \(f\approx-0.9-0.3x_2^2+x_2^2=-0.9+0.7x_2^2\)。 两项来源不同:\(+x_2^2\) 是 \(f\) 自身在 \(x_2\) 方向的曲率;\(-0.3x_2^2\) 是"圆弧迫使 \(x_1\) 往回缩"带来的损失,大小正是乘子 \(0.3\) 乘以约束的曲率。合起来 \(0.7x_2^2=\tfrac12\cdot1.4\,x_2^2\),与投影 Hessian 的特征值 1.4 完全一致。\(\nabla^2_{xx}\mathcal L=\nabla^2f-\lambda\nabla^2c\) 中的 \(-\lambda\nabla^2c\) 就是专门记账"边界弯曲"这一项的。 金融类比:评估一个对冲后的组合,要看的是"组合 + 对冲"整体的凸性,而不是裸头寸的凸性;约束在这里扮演对冲工具的角色,乘子是对冲比例。

12.6.3 投影 Hessian:可计算的形式

最常见的情形:乘子唯一(如 LICQ 成立)且严格互补成立。这时临界锥就是活跃约束梯度的零空间 \(F_2=\operatorname{Null}(A)\)。取列满秩矩阵 \(Z\) 张成该零空间,\(w=Zu\),则

\[ \text{必要条件:}Z^T\nabla^2_{xx}\mathcal LZ\succeq0;\qquad\text{充分条件:}Z^T\nabla^2_{xx}\mathcal LZ\succ0. \]

\(Z^T\nabla^2_{xx}\mathcal LZ\) 叫投影 Hessian(或约化 Hessian),可以构造出来求特征值直接检验。计算 \(Z\) 的标准方法是对 \(A^T\) 做 QR 分解:\(A^T=Q\begin{bmatrix}R\\0\end{bmatrix}=[Q_1\ Q_2]\begin{bmatrix}R\\0\end{bmatrix}\),取 \(Z=Q_2\)。

严格互补不成立时,\(F_2\) 是子空间与半空间的交,不再是子空间。可以用两个子空间夹住它:\(\underline F_2\)(所有活跃约束梯度的零空间)\(\subset F_2\subset\overline F_2\)(只含等式和强活跃约束梯度的零空间)。在 \(\underline F_2\) 的基上投影 Hessian 半正定是必要条件,在 \(\overline F_2\) 的基上正定是充分条件。


12.7 凸规划

凸规划:\(f\) 凸、可行集 \(\Omega\) 凸。所有局部解都是全局解,全局解的集合是凸集(原书习题 12.3)。

定理 12.7:若等式约束 \(c_i\)(\(i\in\mathcal E\))都是线性函数,不等式约束 \(c_i\)(\(i\in\mathcal I\))都是凹函数(即 \(-c_i\) 凸),则 \(\Omega\) 是凸集。

证明:对可行点 \(x_0,x_1\) 和 \(x_\tau=(1-\tau)x_0+\tau x_1\),线性等式约束显然仍为零;由凹性 \(c_i(x_\tau)\ge(1-\tau)c_i(x_0)+\tau c_i(x_1)\ge0\)。证毕。

线性规划是凸规划的特例。例 12.2、12.3、12.4 是凸规划;例 12.1 不是(可行域是圆周);例 12.8 也不是(目标非凸)。

凸规划中 KKT 条件是充分的(本册补充,原书在后续章节使用这一事实):设 \(f\) 凸、等式约束线性、不等式约束凹,\((x^*,\lambda^*)\) 满足 KKT。由于 \(\lambda_i^*\ge0\)(\(i\in\mathcal I\)),\(\mathcal L(\cdot,\lambda^*)=f-\sum\lambda_i^*c_i\) 是凸函数(\(-\lambda_i^*c_i\) 对不等式约束是凸的,对线性等式约束是线性的),而 \(\nabla_x\mathcal L(x^*,\lambda^*)=0\),所以 \(x^*\) 是 \(\mathcal L(\cdot,\lambda^*)\) 在 \(\mathbb R^n\) 上的全局极小点。于是对任意可行 \(x\):

\[ f(x)\ge f(x)-\sum_i\lambda_i^*c_i(x)=\mathcal L(x,\lambda^*)\ge\mathcal L(x^*,\lambda^*)=f(x^*), \]

第一个不等号用了可行性与乘子符号,最后一个等号用了互补松弛。**结论:凸规划中,KKT 点就是全局解,而且不需要任何约束规范。**这是"判断问题是不是凸的"为什么如此重要的根本原因:一旦是凸的,求解器给出的 KKT 点就可以放心使用。

推导拆解:这条不等式链逐步看。 第一个 \(\ge\):可行点处不等式约束 \(c_i(x)\ge0\)、乘子 \(\lambda_i^*\ge0\),所以 \(\sum\lambda_i^*c_i(x)\ge0\)(等式约束 \(c_i(x)=0\),贡献为零),减去一个非负数,值不会变大。 中间的 \(=\):就是 \(\mathcal L\) 的定义。 第二个 \(\ge\):凸函数的"切线在下方"性质,\(\mathcal L(x)\ge\mathcal L(x^*)+\nabla_x\mathcal L(x^*)^T(x-x^*)\),而平稳性让梯度项为零。 最后的 \(=\):互补松弛 \(\lambda_i^*c_i(x^*)=0\),所以 \(\mathcal L(x^*,\lambda^*)=f(x^*)\)。 直观地说:乘子把约束"定价"后并入目标,变成一个无约束的凸问题;在凸问题里,梯度为零的点就是全局最低点。这就是把约束"定价化"的威力。


12.8 其他约束规范

约束规范的作用是保证线性化锥 \(F_1\) 正确反映可行集在 \(x^*\) 附近的几何。

失败的例子:\(x_2\le x_1^3\)、\(x_2\ge0\)(图示为原点处的尖角),在 \(x^*=(0,0)\) 两个约束都活跃,梯度 \((0,-1)\) 与 \((0,1)\) 线性相关,LICQ 不成立。\(F_1=\{d:d_2=0\}\) 包含 \((-1,0)\),但真实可行集在原点左侧根本没有点,唯一可能的极限方向是 \((1,0)\)——线性近似歪曲了几何。

引理 12.8(线性约束规范):若所有活跃约束都是线性函数,则 \(w\in F_1\) 当且仅当 \(w/\|w\|\) 是某可行序列的极限方向。(证明:沿直线 \(z_k=x^*+(T/k)w\) 走即可。)所以"活跃约束全为线性"本身就是一个约束规范,它与 LICQ 互不蕴含。这对量化非常重要:预算、权重上下限、行业/因子暴露、换手率(改写为线性后)等组合约束全是线性的,因此组合优化问题的 KKT 条件无需额外验证 LICQ 就成立——即使约束冗余(比如行业权重之和与预算约束重复)导致 LICQ 失效。

定义 12.5(MFCQ,Mangasarian–Fromovitz):存在 \(w\) 使 \(\nabla c_i(x^*)^Tw>0\)(所有活跃不等式,严格不等号)、\(\nabla c_i(x^*)^Tw=0\)(所有等式),且等式约束梯度线性无关。

MFCQ 弱于 LICQ(LICQ 下取 \(w\) 满足 \(\nabla c_i^Tw=1\) 即可;"弱于"指要求更宽松、适用面更广)。定理 12.1 在 MFCQ 下仍成立,并且 MFCQ 等价于 KKT 乘子集合有界(LICQ 下乘子唯一,自然有界)。约束规范是线性化充分的充分条件而非必要条件:例如 \(x_2\ge-x_1^2\)、\(x_2\le x_1^2\) 在原点处上述规范都不满足,但 \(F_1=\{w:w_2=0\}\) 准确反映了可行集的几何。


12.9 几何观点

一阶条件也可以写成只依赖可行集几何、不依赖约束代数表示的形式。把问题写成 \(\min f(x)\) s.t. \(x\in\Omega\),用切锥 \(T_\Omega(x^*)\)(所有"可行趋近方向"的集合)和法锥 \(N_\Omega(x^*)=\{g:g^Td\le0,\ \forall d\in T_\Omega(x^*)\}\)。

定理 12.9:若 \(x^*\) 是 \(f\) 在 \(\Omega\) 上的局部极小点,则

\[ -\nabla f(x^*)\in N_\Omega(x^*).\tag{12.74} \]

(证明:对任意切方向 \(d\),有 \(x^*+t_jd_j\in\Omega\),\(d_j\to d\),\(t_j\downarrow0\);局部最优与 Taylor 展开给出 \(\nabla f^Td\ge0\)。)

引理 12.10:LICQ 成立时,\(T_\Omega(x^*)=F_1\),\(N_\Omega(x^*)=-N\)(\(N\) 是 12.5.3 节的锥)。

所以 KKT 条件 \(\nabla f^*=A^T\lambda\)(\(\lambda_{\mathcal I}\ge0\))正是几何条件"\(-\nabla f\) 位于法锥中"的代数表达:最优点处,最速下降方向指向可行集之外。这一观点在投影梯度法、近端算法中直接使用:\(x^*\) 最优当且仅当 \(x^*=P_\Omega(x^*-\alpha\nabla f(x^*))\)(凸集情形)。


12.10 均值–方差组合优化的 KKT 分析

本节把前面的理论用在量化最核心的问题上。记 \(n\) 个资产的期望收益 \(\mu\)、协方差 \(\Sigma\succ0\)、权重 \(w\),\(\mathbf 1\) 为全 1 向量。所有约束都是线性的(引理 12.8),目标是凸二次函数,所以这些问题都是凸规划:KKT 条件既必要又充分。

12.10.1 最小方差组合:只有预算约束

\[ \min_w\ \tfrac12w^T\Sigma w\quad\text{s.t.}\quad\mathbf 1^Tw=1. \]

Lagrange 函数 \(\mathcal L=\tfrac12w^T\Sigma w-\nu(\mathbf 1^Tw-1)\),KKT 条件是一个线性方程组:

\[ \begin{bmatrix}\Sigma&-\mathbf 1\\\mathbf 1^T&0\end{bmatrix}\begin{bmatrix}w\\\nu\end{bmatrix}=\begin{bmatrix}0\\1\end{bmatrix} \quad\Longrightarrow\quad w^*=\frac{\Sigma^{-1}\mathbf 1}{\mathbf 1^T\Sigma^{-1}\mathbf 1},\qquad\nu^*=\frac1{\mathbf 1^T\Sigma^{-1}\mathbf 1}. \]

解读:

  • 平稳性 \(\Sigma w^*=\nu^*\mathbf 1\) 说的是:每个资产与最优组合收益的协方差 \((\Sigma w^*)_i\) 都相等。若某资产的协方差更高,把权重从它挪到协方差低的资产上,组合方差会一阶下降——所以最优处边际贡献必须相等。
  • 两边左乘 \(w^{*T}\):\(w^{*T}\Sigma w^*=\nu^*\mathbf 1^Tw^*=\nu^*\),即乘子就是最小方差本身。所有资产相对最小方差组合的 beta 都等于 1。
  • 敏感性:若预算改为 \(\mathbf 1^Tw=B\),最优值 \(f^*(B)=\tfrac12B^2/(\mathbf 1^T\Sigma^{-1}\mathbf 1)\),\(df^*/dB|_{B=1}=\nu^*\),与 12.4 节一致。

推导拆解:闭式解的三步。(1) 对 \(\mathcal L\) 求梯度:\(\nabla_w(\tfrac12w^T\Sigma w)=\Sigma w\)(\(\Sigma\) 对称时的标准结果,类比一元的 \(\frac{d}{dx}\tfrac12ax^2=ax\)),\(\nabla_w(\nu\mathbf 1^Tw)=\nu\mathbf 1\),所以平稳性是 \(\Sigma w-\nu\mathbf 1=0\)。(2) 解出 \(w=\nu\Sigma^{-1}\mathbf 1\)(\(\Sigma\succ0\) 保证可逆)。(3) 代入预算 \(\mathbf 1^Tw=\nu\,\mathbf 1^T\Sigma^{-1}\mathbf 1=1\),得 \(\nu=1/C\),回代即得 \(w^*\)。 "beta 都等于 1"的含义:资产 \(i\) 相对组合 \(p\) 的 beta 是 \(\operatorname{Cov}(r_i,r_p)/\sigma_p^2=(\Sigma w^*)_i/(w^{*T}\Sigma w^*)=\nu/\nu=1\)。这与 CAPM 里"市场组合中所有资产 beta 的加权平均为 1"不同,这里是每一个都等于 1,是最小方差组合独有的性质。

12.10.2 有效前沿与两基金分离

加上目标收益约束:

\[ \min_w\ \tfrac12w^T\Sigma w\quad\text{s.t.}\quad\mu^Tw=m,\quad\mathbf 1^Tw=1. \]

平稳性 \(\Sigma w=\lambda_\mu\mu+\lambda_1\mathbf 1\) 给出 \(w^*=\Sigma^{-1}(\lambda_\mu\mu+\lambda_1\mathbf 1)\)。记 \(A=\mathbf 1^T\Sigma^{-1}\mu\),\(B=\mu^T\Sigma^{-1}\mu\),\(C=\mathbf 1^T\Sigma^{-1}\mathbf 1\),\(D=BC-A^2>0\),代入两个约束解出

\[ \lambda_\mu=\frac{Cm-A}{D},\qquad\lambda_1=\frac{B-Am}{D},\qquad\sigma^2(m)=w^{*T}\Sigma w^*=\frac{Cm^2-2Am+B}{D}. \]

解读:

  • 两基金分离:\(w^*=\lambda_\mu\Sigma^{-1}\mu+\lambda_1\Sigma^{-1}\mathbf 1\) 对 \(m\) 是仿射的,所以前沿上任意组合都是两个固定组合(例如最小方差组合 \(\Sigma^{-1}\mathbf 1/C\) 与 \(\Sigma^{-1}\mu/A\))的线性组合。这是 KKT 平稳性条件的直接推论。
  • 乘子 = 前沿斜率:\(\lambda_\mu=\frac{d}{dm}\big(\tfrac12\sigma^2(m)\big)\),即"多要 1 单位期望收益,要多付出多少(半)方差"。在最小方差点 \(m=A/C\) 处 \(\lambda_\mu=0\):收益约束恰好不绑定。
  • 切点组合:引入无风险利率 \(r_f\)、去掉预算约束而要求 \((\mu-r_f\mathbf 1)^Tw=1\),平稳性给出 \(w\propto\Sigma^{-1}(\mu-r_f\mathbf 1)\),归一化即最大 Sharpe 比组合。

12.10.3 只做多、带权重上限:等边际原则

实际组合几乎总有不等式约束。考虑风险厌恶形式

\[ \min_w\ \tfrac12w^T\Sigma w-\tau\mu^Tw\quad\text{s.t.}\quad\mathbf 1^Tw=1,\quad w_i\ge0,\quad u-w_i\ge0, \]

\(\tau>0\) 为风险容忍度,\(u\) 为单资产上限。按原书约定,乘子分别记为 \(\nu\)(预算,无符号限制)、\(\lambda_i\ge0\)(\(w_i\ge0\))、\(\kappa_i\ge0\)(\(u-w_i\ge0\))。约束梯度分别是 \(\mathbf 1\)、\(e_i\)、\(-e_i\),平稳性为

\[ \Sigma w-\tau\mu=\nu\mathbf 1+\lambda-\kappa. \]

记 \(g_i=(\Sigma w)_i-\tau\mu_i\),它是"在资产 \(i\) 上多放一点权重"对目标的边际影响(边际风险减去边际收益)。结合互补松弛,KKT 条件逐资产地说:

资产状态 互补松弛给出 KKT 条件 含义
内部 \(0<w_i<u\) \(\lambda_i=\kappa_i=0\) \(g_i=\nu\) 所有内部资产的边际"风险减收益"相等
为零 \(w_i=0\) \(\kappa_i=0\) \(g_i=\nu+\lambda_i\ge\nu\) 加仓的边际代价更高,不值得买
顶上限 \(w_i=u\) \(\lambda_i=0\) \(g_i=\nu-\kappa_i\le\nu\) 还想加仓,被上限挡住

这就是组合优化中的等边际原则:最优组合中,所有"自由"持仓的边际风险调整收益相等,等于预算的影子价格 \(\nu\);没买的资产边际不够好,顶格的资产边际更好。这张表也告诉你如何用 KKT 条件诊断一个求解器给出的组合是否真的最优:算出 \(g\),检查上面三条是否成立。

影子价格:由 (12.33)(这些约束的梯度范数都是 1),

  • \(\kappa_i=-\dfrac{df^*}{du_i}\):把资产 \(i\) 的上限提高 1 单位,目标下降 \(\kappa_i\);
  • \(\lambda_i\):若允许 \(w_i\ge-\epsilon\)(少量做空),目标下降速率是 \(\lambda_i\);
  • \(\nu=\dfrac{df^*}{dB}\):预算放大的边际影响。

目标的单位是"方差 − \(\tau\) × 收益",除以 \(\tau\) 就换算成"期望收益的等价值"。组合经理和风控讨论"这条上限值多少钱"时,用的就是这些数。

金融直觉:把这张表和前面的资本预算例子并排看,结构完全相同。 资本预算里,钱是稀缺资源,每个项目的边际 NPV 要么等于预算影子价格(部分投资的项目),要么高于它(全额投资、被"项目规模上限"挡住),要么低于它(不投)。组合里,"1 单位权重"是稀缺资源,\(-g_i=\tau\mu_i-(\Sigma w)_i\) 是资产 \(i\) 的边际"收益减风险",\(-\nu\) 就是权重预算的门槛价:内部资产恰好等于门槛,顶格资产超过门槛(超出部分就是 \(\kappa_i\)),零权重资产达不到门槛(差额就是 \(\lambda_i\))。 所以 \(\kappa_i\) 可以直接读成"这条上限每年让你少赚多少"(除以 \(\tau\) 后),\(\lambda_i\) 读成"这只股票离被买入还差多少边际吸引力"。一个实用含义是:如果投委会想放宽某条上限,就先看它的 \(\kappa_i\);\(\kappa_i\) 接近零的上限,放宽了也几乎没有收益,不值得争取。 注意 \(g_i\) 里的边际风险 \((\Sigma w)_i\) 取决于整个组合,而不是资产 \(i\) 自己的波动率。这正是 CFA 组合理论里"资产对组合风险的贡献看协方差,不看自身方差"在最优化里的体现。

二阶条件与唯一性:\(\nabla^2_{xx}\mathcal L=\Sigma\)。若 \(\Sigma\succ0\),投影 Hessian 自然正定,解是严格(且唯一的)全局解。但若 \(\Sigma\) 只是半正定——比如用 \(T<n\) 天的数据估计 \(n\) 只股票的样本协方差,秩至多 \(T-1\)——则 \(Z^T\Sigma Z\) 可能奇异,最优解不唯一,目标沿某些方向完全平坦,求解器给出的解对数据和初值极度敏感。这是在大截面上使用样本协方差的数值根源之一,也是使用因子模型或收缩估计(第 03、06 册)的理由之一。

12.10.4 凸与非凸约束

由定理 12.7:

  • 凸的:线性等式(预算、中性化、因子暴露目标);线性不等式(权重上下限、行业偏离、换手率经 12.1.2 节改写后);凹的不等式 \(c(w)=\sigma_{\max}^2-w^T\Sigma w\ge0\)(波动率或跟踪误差上限)。
  • 非凸的:"持仓数不超过 \(K\)"(基数约束)、"最小交易单位/整手"、"要么不买要么至少买 1%"(半连续变量)、\(\|w\|=1\) 型等式(例 12.1 那样的球面)。

非凸约束会带来例 12.1、12.8 那样的伪 KKT 点和大量局部解,求解器给出的 KKT 点只是局部解。实务中常用整数规划求解器、或先解凸松弛再启发式修正。


12.11 量化实战

12.11.1 代码一:数值验证原书例题的 KKT 点

用 SLSQP 求解('ineq' 约束即 \(c(x)\ge0\),与原书一致),找出活跃集,用最小二乘解 (12.31) 反求乘子,并检查 LICQ;对例 12.8 构造投影 Hessian。

import numpy as np
from scipy.optimize import minimize

def kkt_check(name, f, gf, cons, x0, H_L=None):
    """cons: [(类型 'eq'/'ineq', c(x), ∇c(x))],约定 c(x)=0 或 c(x)>=0(与原书一致)"""
    res = minimize(f, x0, jac=gf, method='SLSQP', options={'ftol': 1e-14, 'maxiter': 500},
                   constraints=[{'type': t, 'fun': c, 'jac': g} for t, c, g in cons])
    x = res.x
    act = [i for i, (t, c, g) in enumerate(cons) if t == 'eq' or abs(c(x)) < 1e-7]
    A = np.array([cons[i][2](x) for i in act])                 # 活跃约束梯度(行)
    lam = np.linalg.lstsq(A.T, gf(x), rcond=None)[0]           # 解 ∇f = A^T λ  (12.31)
    print(f"{name}: x* = {np.round(x, 6) + 0.0}, 活跃集 = {[i+1 for i in act]}, λ* = {np.round(lam, 6)}")
    print(f"   ||∇_x L|| = {np.linalg.norm(gf(x) - A.T @ lam):.1e}, rank(A) = {np.linalg.matrix_rank(A)} (LICQ)")
    if H_L is not None:                                        # 投影 Hessian Z^T ∇²L Z
        Q, _ = np.linalg.qr(A.T, mode='complete'); Z = Q[:, len(act):]
        HL = H_L(x, lam)
        print(f"   ∇²L 的特征值 {np.round(np.linalg.eigvalsh(HL), 4)}, Z^T∇²L Z 的特征值 {np.round(np.linalg.eigvalsh(Z.T @ HL @ Z), 4)}")
    return x, lam

# 例 12.3:min x1+x2  s.t. 2-x1²-x2² >= 0, x2 >= 0
kkt_check("例 12.3", lambda x: x[0]+x[1], lambda x: np.array([1.0, 1.0]),
          [('ineq', lambda x: 2-x[0]**2-x[1]**2, lambda x: np.array([-2*x[0], -2*x[1]])),
           ('ineq', lambda x: x[1], lambda x: np.array([0.0, 1.0]))], np.array([0.5, 0.5]))

# 例 12.4(目标第二项取 (x2-1/2)^4,与原书给出的 ∇f(x*)=(-1,-1/2) 一致)
f4 = lambda x: (x[0]-1.5)**2 + (x[1]-0.5)**4
g4 = lambda x: np.array([2*(x[0]-1.5), 4*(x[1]-0.5)**3])
lin = lambda a, b: ('ineq', lambda x: 1 + a*x[0] + b*x[1], lambda x: np.array([a, b], float))
kkt_check("例 12.4", f4, g4, [lin(-1, -1), lin(-1, 1), lin(1, -1), lin(1, 1)], np.zeros(2))

# 例 12.8:min -0.1(x1-4)² + x2²  s.t. x1²+x2²-1 >= 0(非凸)
kkt_check("例 12.8", lambda x: -0.1*(x[0]-4)**2 + x[1]**2,
          lambda x: np.array([-0.2*(x[0]-4), 2*x[1]]),
          [('ineq', lambda x: x[0]**2+x[1]**2-1, lambda x: np.array([2*x[0], 2*x[1]]))],
          np.array([1.5, 0.3]),
          H_L=lambda x, lam: np.diag([-0.2, 2.0]) - lam[0]*np.diag([2.0, 2.0]))

输出:

例 12.3: x* = [-1.414214  0.      ], 活跃集 = [1, 2], λ* = [0.353553 1.      ]
   ||∇_x L|| = 0.0e+00, rank(A) = 2 (LICQ)
例 12.4: x* = [1. 0.], 活跃集 = [1, 2], λ* = [0.75 0.25]
   ||∇_x L|| = 3.1e-16, rank(A) = 2 (LICQ)
例 12.8: x* = [1. 0.], 活跃集 = [1], λ* = [0.3]
   ||∇_x L|| = 3.3e-14, rank(A) = 1 (LICQ)
   ∇²L 的特征值 [-0.8  1.4], Z^T∇²L Z 的特征值 [1.4]

三个例子的乘子都与原书一致:例 12.3 的 \(\lambda^*=(1/(2\sqrt2),1)=(0.3536,1)\);例 12.4(按 \((x_2-\tfrac12)^4\))的 \(\lambda^*=(\tfrac34,\tfrac14)\);例 12.8 的 \(\lambda^*=0.3\),\(\nabla^2_{xx}\mathcal L\) 的特征值为 \(-0.8\) 与 \(1.4\)(不定),但投影到临界锥 \(\{(0,w_2)\}\) 后只剩 1.4 > 0,二阶充分条件成立。

12.11.2 代码二:均值–方差组合的 KKT 全面检验

8 个行业资产,依次完成:(1) 最小方差组合的 KKT 线性方程组;(2) 有效前沿上乘子与 \(df^*/dm\) 的对照;(3) 只做多、上限 25% 的均值–方差问题——先用 SLSQP 识别活跃集,再在该活跃集上解等式约束的 KKT 线性方程组"精修"出精确解和乘子,逐资产列出等边际原则;(4) 放松约束后重新求解,检验影子价格;(5) 投影 Hessian。

import numpy as np, pandas as pd
from scipy.optimize import minimize
pd.set_option('display.width', 120)

rng = np.random.default_rng(2024)
names = ['银行', '保险', '白酒', '医药', '电子', '新能源', '军工', '公用']
n = len(names)
vol = np.array([0.18, 0.22, 0.28, 0.26, 0.34, 0.38, 0.32, 0.15])
C = 0.35 + 0.35*np.eye(n) + 0.30*np.corrcoef(rng.standard_normal((n, 40)))   # 正定相关矩阵
C = C / np.sqrt(np.outer(np.diag(C), np.diag(C)))
Sigma = C * np.outer(vol, vol)                                   # 年化协方差
mu = np.array([0.06, 0.07, 0.12, 0.10, 0.11, 0.13, 0.08, 0.05])  # 年化期望收益
one = np.ones(n)
Si = np.linalg.inv(Sigma)

# ---------- (1) 只有预算约束的最小方差组合:KKT 是线性方程组 ----------
# min ½w'Σw  s.t. 1'w = 1  →  Σw - ν·1 = 0, 1'w = 1
K = np.block([[Sigma, -one[:, None]], [one[None, :], np.zeros((1, 1))]])
sol = np.linalg.solve(K, np.r_[np.zeros(n), 1.0]); w_mv, nu = sol[:n], sol[n]
print("(1) 最小方差组合: ν = %.6f, w'Σw = %.6f, 解析式 1/(1'Σ⁻¹1) = %.6f" % (nu, w_mv @ Sigma @ w_mv, 1/(one @ Si @ one)))
print("    各资产与组合的协方差 (Σw)_i 全部等于 ν:", np.allclose(Sigma @ w_mv, nu))

# ---------- (2) 有效前沿:min ½w'Σw s.t. μ'w = m, 1'w = 1 ----------
A_, B_, C_ = one @ Si @ mu, mu @ Si @ mu, one @ Si @ one; D_ = B_*C_ - A_**2
def frontier(m):
    l1, l2 = (C_*m - A_)/D_, (B_ - A_*m)/D_              # 两个乘子
    return Si @ (l1*mu + l2*one), l1, l2
m, eps = 0.10, 1e-6
w, l1, l2 = frontier(m)
fm = lambda m: 0.5*frontier(m)[0] @ Sigma @ frontier(m)[0]
print("(2) 目标收益 10%%: σ = %.4f;乘子 λ_μ = %.6f,数值导数 df*/dm = %.6f" % (np.sqrt(2*fm(m)), l1, (fm(m+eps)-fm(m-eps))/(2*eps)))

# ---------- (3) 只做多 + 单资产上限 25% 的均值–方差:min ½w'Σw - τμ'w ----------
tau, ub = 0.15, 0.25
f  = lambda w: 0.5*w @ Sigma @ w - tau*mu @ w
gf = lambda w: Sigma @ w - tau*mu
res = minimize(f, one/n, jac=gf, method='SLSQP', bounds=[(0, ub)]*n,
               constraints=[{'type': 'eq', 'fun': lambda w: w.sum() - 1, 'jac': lambda w: one}],
               options={'ftol': 1e-15, 'maxiter': 1000})
w = res.x
lo, hi = w < 1e-7, w > ub - 1e-7                         # 识别活跃集
free = ~(lo | hi)
# 在识别出的活跃集上"精修":解等式约束 KKT 线性方程组(自由变量 + 预算约束)
w = np.where(hi, ub, 0.0)
idx = np.where(free)[0]; nf = len(idx)
Kf = np.block([[Sigma[np.ix_(idx, idx)], -np.ones((nf, 1))], [np.ones((1, nf)), np.zeros((1, 1))]])
rhs = np.r_[tau*mu[idx] - Sigma[np.ix_(idx, ~free)] @ w[~free], 1 - w[~free].sum()]
z = np.linalg.solve(Kf, rhs); w[idx] = z[:nf]; nu = z[nf]
g = gf(w)                                                # 边际"风险减收益" g_i = (Σw)_i - τμ_i
lam   = np.where(lo, g - nu, 0.0)                        # w_i >= 0 的乘子:g_i = ν + λ_i
kappa = np.where(hi, nu - g, 0.0)                        # ub - w_i >= 0 的乘子:g_i = ν - κ_i
tab = pd.DataFrame({'μ': mu, 'w*': w.round(4), 'g_i': g.round(5),
                    '状态': np.where(hi, '顶上限', np.where(lo, '为零', '内部')),
                    'λ_i(下界)': lam.round(5), 'κ_i(上界)': kappa.round(5)}, index=names)
print("(3) ν = %.5f;KKT 检查:||∇L|| = %.1e, min λ = %.1e, min κ = %.1e, 互补 max|λw|+|κ(u-w)| = %.1e" %
      (nu, np.linalg.norm(g - nu*one - lam + kappa), lam.min(), kappa.min(),
       np.max(np.abs(lam*w) + np.abs(kappa*(ub - w)))))
print(tab)

# ---------- (4) 乘子 = 影子价格:放松约束后重新求解,对比 (12.33) ----------
def solve(ub_vec, budget=1.0):
    r = minimize(f, one/n, jac=gf, method='SLSQP', bounds=list(zip(np.zeros(n), ub_vec)),
                 constraints=[{'type': 'eq', 'fun': lambda w: w.sum() - budget, 'jac': lambda w: one}],
                 options={'ftol': 1e-15, 'maxiter': 1000})
    return r.fun
f0, e = f(w), 1e-4
j = int(np.argmax(kappa))
print("(4) 放松 %s 的上限 %.0e:Δf/ε = %.5f,预测 -κ = %.5f" % (names[j], e, (solve(np.where(np.arange(n)==j, ub+e, ub))-f0)/e, -kappa[j]))
print("    预算由 1 增至 1+ε:     Δf/ε = %.5f,预测  ν = %.5f" % ((solve(np.full(n, ub), 1+e)-f0)/e, nu))

# ---------- (5) 二阶条件:临界锥上的投影 Hessian ----------
Aact = np.vstack([one] + [np.eye(n)[i] for i in np.where(~free)[0]])   # 活跃约束梯度
Q, _ = np.linalg.qr(Aact.T, mode='complete'); Z = Q[:, Aact.shape[0]:]
print("(5) 活跃约束数 %d,Z 的维数 %d,Z'ΣZ 的特征值:" % (Aact.shape[0], Z.shape[1]), np.round(np.linalg.eigvalsh(Z.T @ Sigma @ Z), 5))

输出:

(1) 最小方差组合: ν = 0.015950, w'Σw = 0.015950, 解析式 1/(1'Σ⁻¹1) = 0.015950
    各资产与组合的协方差 (Σw)_i 全部等于 ν: True
(2) 目标收益 10%: σ = 0.1803;乘子 λ_μ = 0.356552,数值导数 df*/dm = 0.356552
(3) ν = 0.00950;KKT 检查:||∇L|| = 3.9e-18, min λ = 0.0e+00, min κ = 0.0e+00, 互补 max|λw|+|κ(u-w)| = 0.0e+00
        μ      w*      g_i   状态  λ_i(下界)  κ_i(上界)
银行   0.06  0.2500  0.00907  顶上限  0.00000  0.00043
保险   0.07  0.1490  0.00950   内部  0.00000  0.00000
白酒   0.12  0.1539  0.00950   内部  0.00000  0.00000
医药   0.10  0.1709  0.00950   内部  0.00000  0.00000
电子   0.11  0.0043  0.00950   内部  0.00000  0.00000
新能源  0.13  0.0219  0.00950   内部  0.00000  0.00000
军工   0.08  0.0000  0.01017   为零  0.00068  0.00000
公用   0.05  0.2500  0.00698  顶上限  0.00000  0.00252
(4) 放松 公用 的上限 1e-04:Δf/ε = -0.00251,预测 -κ = -0.00252
    预算由 1 增至 1+ε:     Δf/ε = 0.00950,预测  ν = 0.00950
(5) 活跃约束数 4,Z 的维数 4,Z'ΣZ 的特征值: [0.03658 0.05165 0.07254 0.08857]

逐项解读:

  1. 最小方差组合:KKT 线性方程组的解与闭式公式一致,\(\nu=w^T\Sigma w=1/(\mathbf 1^T\Sigma^{-1}\mathbf 1)\),且每个资产与组合的协方差都等于 \(\nu\)——12.10.1 节的结论被逐字验证。
  2. 有效前沿:目标收益 10% 时前沿波动率 18.0%;收益约束的乘子 \(\lambda_\mu=0.3566\) 与数值导数 \(df^*/dm\) 完全吻合,即 (12.33) 对等式约束的版本。
  3. 等边际原则:五个内部资产(保险、白酒、医药、电子、新能源)的 \(g_i\) 全等于 \(\nu=0.00950\);军工 \(g_i=0.01017>\nu\),所以不买,下界乘子 \(\lambda=0.00068\);银行和公用这两个低波动资产 \(g_i<\nu\),想多买但被 25% 上限挡住,上界乘子分别为 0.00043 和 0.00252。所有乘子非负、互补松弛精确成立——这是一个经过 KKT 验证的全局最优解。注意新能源期望收益最高(13%),但因波动大、与其他资产相关,只分到 2.2% 的权重;"边际"比"单独看"重要。
  4. 影子价格:把公用事业的上限提高 \(10^{-4}\),目标的变化率为 \(-0.00251\),KKT 预测 \(-\kappa=-0.00252\);预算的变化率 0.00950 与 \(\nu\) 一致。换算成收益等价值:\(\kappa/\tau=0.0168\),即公用事业上限每放宽 1 个百分点,组合效用相当于提高约 1.7bp 的期望收益——这就是"这条约束的成本"。
  5. 二阶条件:4 个活跃约束(预算 + 3 个边界),自由维数 4,投影 Hessian \(Z^T\Sigma Z\) 的特征值全为正,严格局部解(又因为凸,是唯一全局解)。

这里"先用一般求解器识别活跃集、再解 KKT 线性方程组"的做法,正是原书第 16 章二次规划有效集方法(active-set method,本册第 16a 章 16.5 节)的核心思想:猜一个活跃集,解对应的等式约束问题,检查乘子符号和可行性,不满足就调整活跃集。


本章小结

约束优化的一阶必要条件是 KKT 条件:在约束规范(LICQ、MFCQ 或活跃约束全线性)下,局部解处目标梯度是活跃约束梯度的组合,不等式约束的系数非负,且非活跃约束的乘子为零。它的证明链是:局部最优 ⇒ 可行序列的极限方向不下降 ⇒(LICQ,隐函数定理)线性化可行方向不下降 ⇒(Farkas 引理,向闭凸锥投影)乘子存在。乘子是影子价格,\(df^*/d\epsilon=-\lambda_i^*\|\nabla c_i\|\)。二阶条件在临界锥上检查 Lagrange 函数的 Hessian,实用形式是投影 Hessian \(Z^T\nabla^2_{xx}\mathcal LZ\);充分条件不需要约束规范。凸规划(等式线性、不等式凹、目标凸)中 KKT 点就是全局解。均值–方差组合优化是凸规划,KKT 条件给出最小方差组合的等协方差性质、有效前沿与两基金分离、只做多问题的等边际原则,以及每条约束的影子价格。

概念 公式 / 要点
Lagrange 函数 \(\mathcal L(x,\lambda)=f(x)-\sum_i\lambda_ic_i(x)\)(原书约定 \(c_i\ge0\))
KKT 条件 \(\nabla f=\sum_{\mathcal A}\lambda_i\nabla c_i\);可行;\(\lambda_{\mathcal I}\ge0\);\(\lambda_ic_i=0\)
LICQ 活跃约束梯度线性无关 ⇒ 乘子唯一
MFCQ 存在 \(w\):活跃不等式 \(\nabla c_i^Tw>0\),等式 \(\nabla c_i^Tw=0\) 且梯度无关;⇔ 乘子集有界
线性约束规范 活跃约束全线性即可,组合约束天然满足
敏感性 \(df^*/d\epsilon=-\lambda_i^*|\nabla c_i|\);乘子 = 影子价格
Farkas 引理 无 \(d\in F_1\) 使 \(\nabla f^Td<0\) ⇔ \(\nabla f=A^T\lambda\),\(\lambda_{\mathcal I}\ge0\)
临界锥 等式与强活跃约束 \(\nabla c_i^Tw=0\),弱活跃 \(\ge0\)
二阶条件 必要 \(w^T\nabla^2_{xx}\mathcal Lw\ge0\);充分 \(>0\)(\(w\in F_2\setminus\{0\}\))
投影 Hessian \(Z^T\nabla^2_{xx}\mathcal LZ\),\(Z=Q_2\) 来自 \(A^T\) 的 QR
凸规划 等式线性 + 不等式凹 + 目标凸;KKT ⇔ 全局最优
几何形式 \(-\nabla f(x^*)\in N_\Omega(x^*)\)
最小方差组合 \(w=\Sigma^{-1}\mathbf 1/C\),\(\Sigma w=\nu\mathbf 1\),\(\nu=\sigma^2_{\min}\)
有效前沿 \(w=\Sigma^{-1}(\lambda_\mu\mu+\lambda_1\mathbf 1)\),\(\sigma^2(m)=(Cm^2-2Am+B)/D\)
等边际原则 内部 \(g_i=\nu\);为零 \(g_i\ge\nu\);顶格 \(g_i\le\nu\),\(g=\Sigma w-\tau\mu\)

练习

基础

  1. 求 \(\min x_1x_2\) s.t. \(x_1^2+x_2^2=1\) 的所有 KKT 点,判断哪些是局部极小、哪些是局部极大。(原书习题 12.20) 提示:\(x_2=2\lambda x_1\),\(x_1=2\lambda x_2\),得 \(\lambda=\pm\tfrac12\);极小点 \(\pm(\tfrac1{\sqrt2},-\tfrac1{\sqrt2})\),用投影 Hessian 判断。
  2. 求半空间 \(\{x:a^Tx+\alpha\ge0\}\) 中欧氏范数最小的点,即 \(\min\tfrac12\|x\|^2\) s.t. \(a^Tx+\alpha\ge0\)(向半空间的投影公式)。(原书习题 12.15) 提示:若 \(\alpha\ge0\),答案是 0;否则 \(x^*=-\frac{\alpha}{\|a\|^2}a\),乘子 \(\lambda^*=-\alpha/\|a\|^2\)。
  3. 把 \(\min_x\|v(x)\|_\infty\) 和 \(\min_x\max_iv_i(x)\) 改写为光滑约束问题。(原书习题 12.4)
  4. 证明 KKT 点处若 LICQ 成立,乘子唯一。(原书习题 12.17)
  5. 推导最小方差组合的闭式解,并证明组合中每个资产相对于该组合的 beta 都等于 1。
  6. 在 12.11.2 的代码中把 \(\tau\) 从 0.15 依次改为 0.05、0.3、0.6,观察活跃集如何变化。\(\tau\to0\) 和 \(\tau\to\infty\) 时分别趋向什么组合?

进阶

  1. 证明 (12.72) 型约束 \(x_2\le x_1^3\)、\(x_2\ge0\) 在原点处 LICQ 与 MFCQ 都不成立;再验证 \((x_1-1)^2+(x_2-1)^2\le2\)、\((x_1-1)^2+(x_2+1)^2\le2\)、\(x_1\ge0\) 在原点处 MFCQ 成立而 LICQ 不成立。(原书习题 12.10、12.13)
  2. 抛物线 \(y=\tfrac15(x-1)^2\) 上求离点 \((1,2)\) 最近的点:写出 KKT 条件,判断 LICQ,找出所有 KKT 点并判断哪些是解。再把约束代入目标消去 \(x\),说明所得无约束问题的解为什么不是原问题的解(消元陷阱)。(原书习题 12.18)
  3. 对 12.10.2 节的有效前沿,证明 \(\lambda_\mu=\frac{d}{dm}\big(\tfrac12\sigma^2(m)\big)\),并说明 \(m<A/C\) 时 \(\lambda_\mu<0\) 的经济含义(前沿下半支是无效的)。
  4. 在只做多均值–方差问题中加入跟踪误差约束 \(\sigma_{TE}^2-(w-w_b)^T\Sigma(w-w_b)\ge0\)。证明问题仍是凸规划,写出 KKT 条件,并说明这条约束的乘子与 \(\tau\) 的关系(跟踪误差约束绑定时,等价于把风险厌恶调高到某个水平)。
  5. 用 12.11.2 的思路实现一个简单的二次规划有效集方法:从"全部内部"出发,解等式约束 KKT 方程组;若有权重越界,就把它固定到边界(加入活跃集);若某个活跃约束的乘子为负,就把它移出活跃集;重复直到 KKT 全部满足。用 SLSQP 的结果对照。(完整实现见第 16a 章 16.7.1 节的 active_set_qp,可在做完后对照。)

原书推荐习题:12.4(非光滑 → 光滑约束重写,直接用于 minimax/CVaR 建模)、12.10、12.13(LICQ 与 MFCQ 的区别)、12.15(向半空间投影,投影类算法的基本构件)、12.17(乘子唯一性)、12.18(消元陷阱)。原书第 12 章共有 12.1–12.21 题。


原书对照

本章内容 原书位置 PDF 页码
12.1 问题形式、局部解、光滑化 第 12 章引言,式 (12.1)–(12.8),图 12.1–12.2 PDF p.333–338
12.2 例 12.1–12.3 §12.1 Examples,式 (12.9)–(12.27) PDF p.338–346
12.3 KKT 条件、LICQ、定理 12.1、例 12.4 §12.2 First-Order Optimality Conditions,式 (12.28)–(12.32) PDF p.346–348
12.4 敏感性 §12.2 Sensitivity,式 (12.33),定义 12.3 PDF p.348–350
12.5 KKT 的证明:定理 12.2、引理 12.3–12.4 §12.3 Derivation of the First-Order Conditions,式 (12.34)–(12.51) PDF p.350–360
12.6 二阶条件:定理 12.5–12.6、例 12.7–12.8、投影 Hessian §12.4 Second-Order Conditions,式 (12.52)–(12.71) PDF p.361–368
12.7 凸规划、定理 12.7 §12.4 Convex Programs PDF p.368–369
12.8 其他约束规范:引理 12.8、MFCQ §12.5 Other Constraint Qualifications PDF p.369–372
12.9 几何观点:定理 12.9、引理 12.10 §12.6 A Geometric Viewpoint,式 (12.73)–(12.77) PDF p.372–375
注释与参考(\(N\) 的闭性、KKT 的历史) Notes and References PDF p.375–376
习题 12.1–12.21 Exercises PDF p.376–378
12.10–12.11 均值–方差组合的 KKT 分析与代码 本册补充(原书第 1 章将组合设计列为典型应用;二次规划算法见原书第 16 章) —

页码换算:本章原书正文页码 = PDF 页码减 19(已用 PDF 页眉核对;第 3–11 章减 20,第 17 章起减 18)。§12.2、§12.4 内部小节的 PDF 页码为按篇幅估计的大致位置。