我学过线性代数,当时比较熟悉怎么算。最近遇到凸包,看到“所有凸组合构成凸包”这句话,又有些拿不准。橡皮筋围住一堆点,这个画面不难想象,可一写成求和公式,就有好几步想追问。
两个点之间的线段为什么能写成加权和?证明里新的权重为什么仍然加起来等于 1?几何上那个最小的凸区域,为什么恰好等于这些代数组合?
这篇把这些步骤补完整。只讨论欧氏空间中的点,主要用二维例子。先选定坐标原点,将一个点的坐标写成向量。后面提到向量之间的线段,指的就是这些坐标所对应的点之间的线段。
基本概念:从线段到凸包
先把一条线段写出来
给定两个点 \(u\) 和 \(v\),从 \(u\) 指向 \(v\) 的位移是 \(v-u\)。从 \(u\) 出发,沿这个位移走比例 \(t\),到达的位置就是
\[p(t)=u+t(v-u)=(1-t)u+tv. \label{eq:segment}\]当 \(t=0\),位置在 \(u\);当 \(t=1\),位置在 \(v\)。中间的取值沿同一方向走过一部分距离,恰好得到两个端点之间的整条线段。若允许 \(t\) 小于 0 或大于 1,就会走到线段的延长线上。
例如,取 \(u=(2,0)\)、\(v=(0,2)\),则
\[p(t)=(2-2t,\,2t). \label{eq:segment-example}\]| \(t\) | \(p(t)\) | 所在位置 |
|---|---|---|
| 0 | \((2,0)\) | 第一个端点 |
| 0.25 | \((1.5,0.5)\) | 走过四分之一 |
| 0.5 | \((1,1)\) | 中点 |
| 1 | \((0,2)\) | 第二个端点 |
式 \(\eqref{eq:segment}\) 给出了线段公式。它来自位移的加法,还没有用到凸集合的任何性质,因此后面用它证明凸性不会形成循环论证。
“凸”是一条检查规则
一个集合是凸的,意思是从中任取两个点,连接它们的整条线段都留在集合里。写成公式就是
\[u,v\in K,\quad 0\leq t\leq1 \quad\Longrightarrow\quad (1-t)u+tv\in K. \label{eq:convex-set}\]圆盘和实心矩形都满足这个条件。只有圆周的集合就不满足,取直径的两个端点,它们之间的线段穿过圆内部,而圆内部没有被包含在这个集合里。
带凹口的区域也可能不满足。只要找到两个点,它们之间的线段有一部分穿出区域,就足以证明它非凸。证明凸则需要对任意两点成立。
因此,“凸”并不要求边界弯曲。线段本身也是凸集合,单独一个点同样是。面对一个集合,通常区分凸与非凸;“凹集合”并不是这里给所有非凸集合使用的统一名称。
凸组合是受到限制的线性组合
若干向量分别乘上系数,再相加,便得到线性组合。凸组合额外要求每个系数非负,而且所有系数加起来等于 1。
给定 \(p_1,\ldots,p_n\),一次凸组合写成
\[p=\sum_{i=1}^{n}\lambda_i p_i, \qquad \lambda_i\geq0, \qquad \sum_{i=1}^{n}\lambda_i=1. \label{eq:convex-combination}\]这可以理解成加权平均位置。两个点的权重写成 \(1-t\) 和 \(t\),就回到了式 \(\eqref{eq:segment}\) 的线段公式。
两个条件各有作用。对于 \(u=(2,0)\) 和 \(v=(0,2)\),取系数 2 和 -1,虽然总和为 1,却得到 \(2u-v=(4,-2)\),已经到了线段外。取系数 1 和 1,虽然都非负,却得到 \(u+v=(2,2)\),也不在线段上。
一次凸组合只给出一个点。让所有满足条件的权重都取遍,才会得到一个集合。
凸包究竟把什么包起来了
给定一组点,它们的凸包就是包含这些点的最小凸集合。这里的“最小”按集合包含关系理解。任何包含原始点的凸集合,都必须包含这个凸包。
二维里,可以想象把钉子钉在各点上,再将一根绷紧的橡皮筋套在外围。橡皮筋表示凸包的边界,连同里面的区域,才是完整的凸包。
如果四个点在正方形四角,第五个点在中央,凸包就是整个实心正方形。中央点不会改变外围边界。用笔按外围顺序连接正确的外侧顶点,也能画出同一条边界。
为什么不沿点与点之间的空隙往里凹,围得更小一点?因为还必须满足凸性。删掉某个凹口后,如果两点间的线段穿过这个凹口,集合就不再是凸的。“包含原始点”和“保持凸性”必须同时成立。
现在,几何上的定义清楚了。接下来要证明它恰好等于所有凸组合组成的集合。
证明:所有凸组合构成凸包
设原始点集为 \(S=\{p_1,\ldots,p_n\}\),用 \(C\) 表示它们所有凸组合组成的集合。证明分成三个步骤,每一步解决一个不同的问题。
原始点都在 C 中
想得到 \(p_k\),只需令 \(\lambda_k=1\),其余系数为 0。这满足凸组合的条件,因此 \(S\subseteq C\)。
C 自身是凸的
从 \(C\) 中任取两点 \(u,v\)。由于它们属于 \(C\),各自都能写成原始点的凸组合
\[u=\sum_i a_i p_i, \qquad v=\sum_i b_i p_i, \label{eq:two-combinations}\]其中 \(a_i,b_i\geq0\),并且 \(\sum_i a_i=\sum_i b_i=1\)。
我们要检查 \(u,v\) 之间整条线段是否还在 \(C\)。使用前面从位移关系得到的式 \(\eqref{eq:segment}\),令 \(0\leq t\leq1\),得到
\[\begin{aligned} (1-t)u+tv &=(1-t)\sum_i a_i p_i+t\sum_i b_i p_i\\ &=\sum_i\bigl((1-t)a_i+tb_i\bigr)p_i. \end{aligned} \label{eq:combined-weights}\]每个新权重是 \(c_i=(1-t)a_i+tb_i\)。各项都非负,所以 \(c_i\geq0\)。再看总和,\(t\) 对每个 \(i\) 都一样,可以移到求和符号外
\[\begin{aligned} \sum_i c_i &=(1-t)\sum_i a_i+t\sum_i b_i\\ &=(1-t)\cdot1+t\cdot1\\ &=1. \end{aligned} \label{eq:weight-sum}\]式 \(\eqref{eq:weight-sum}\) 说明所有新权重的总和为 1,每个新权重本身可以有不同的值。第一组原本是一整份,取它的 \(1-t\) 份;第二组也是一整份,取它的 \(t\) 份,总量仍是一整份。
新点仍然是原始点的凸组合,因此属于 \(C\)。线段上的任意点都如此,\(C\) 就是凸集合。
任何包含 S 的凸集合,都必须包含 C
设 \(K\) 是任意一个包含全部原始点的凸集合。根据凸性的定义,\(K\) 包含任意两个原始点的所有凸组合。多个点的组合也可以分步归结为两个点的组合。
以三个点为例,设 \(\lambda_1+\lambda_2+\lambda_3=1\),各系数非负。若 \(\lambda_3<1\),先组合前两个点
\[q= \frac{\lambda_1}{1-\lambda_3}p_1 +\frac{\lambda_2}{1-\lambda_3}p_2. \label{eq:normalized-pair}\]这两个新系数非负,和为 1,所以 \(q\in K\)。再将 \(q\) 与 \(p_3\) 组合
\[(1-\lambda_3)q+\lambda_3p_3 =\lambda_1p_1+\lambda_2p_2+\lambda_3p_3\in K. \label{eq:three-point-combination}\]若 \(\lambda_3=1\),结果直接就是 \(p_3\),同样属于 \(K\)。更多点可以照此归纳,将前面的点先合成一个点,再与最后一个点组合。
因此 \(K\) 包含所有凸组合,也就是 \(C\subseteq K\)。结合前两步,\(C\) 包含原始点、自身是凸的,并且包含在任何其他符合要求的凸集合中。它恰好就是凸包。
这个证明针对有限点集。对任意点集,凸包同样等于其中所有有限凸组合的集合;“有限”指每一次组合只使用有限个点。
例子:用三个点把结论算一遍
取 \(A=(0,0)\)、\(B=(2,0)\)、\(D=(0,2)\)。它们的凸组合为
\[\lambda_A A+\lambda_B B+\lambda_D D =(2\lambda_B,\,2\lambda_D). \label{eq:triangle-point}\]记结果为 \((x,y)\)。由权重非负、总和为 1,可得
\[x\geq0,\qquad y\geq0,\qquad x+y\leq2. \label{eq:triangle-region}\]式 \(\eqref{eq:triangle-region}\) 描述的正是第一象限内,由两条坐标轴和直线 \(x+y=2\) 围成的实心三角形,包含边界。
反过来,三角形内任何一点也都能还原出合法权重
\[\lambda_B=\frac{x}{2},\qquad \lambda_D=\frac{y}{2},\qquad \lambda_A=1-\frac{x+y}{2}. \label{eq:triangle-weights}\]代入式 \(\eqref{eq:triangle-weights}\),\((0.5,0.5)\) 对应的权重是 \(\lambda_A=0.5\)、\(\lambda_B=\lambda_D=0.25\)。而 \((1.5,1.5)\) 会让 \(\lambda_A=-0.5\),违反非负条件,因此落在凸包之外。几何边界和代数约束在这里给出了完全相同的判断。
为什么还要引入凸包?
到这里可能会觉得,凸集合、凸组合、凸包都在描述“不要出现凹口”,概念似乎有些重复。凸包真正增加的东西,是把一组离散点变成一个有明确边界的、最小的凸区域。它回答的不只是“这些点是不是凸的”,还回答“如果必须用一个凸区域把它们一起装下,最省的区域是什么”。
这在几何计算中很有用。给定一组点后,只保留凸包边界,就能快速得到它们的外围形状,并进一步计算面积、周长、相交关系或碰撞范围。许多点可能落在凸包内部,对外围边界没有贡献,因此凸包也提供了一种压缩点集的方式。
凸包在优化里同样自然。若一个目标函数是线性的,那么它在有限点集所有凸组合上的最大值或最小值,可以在原始点中寻找。也就是说,凸包把“若干候选点”扩展成一个连续区域,同时保留线性目标最关心的边界结构。这正是线性规划和许多凸优化模型喜欢使用凸集合的原因之一。
不过,凸包是一个外包络。原始点之间的空隙会被填上,凸包中的点不一定真的来自某个可实现过程。若这些点代表机器人的可达位置、样本的真实分布或物理系统的安全状态,就要记住:凸包适合做保守近似和几何推理,不能自动替代原集合本身。