基于差分的约束系统(Difference Constraints System)求解算法
问题描述
差分约束系统是一类特殊的线性不等式组,包含 \(n\) 个变量 \(x_1, x_2, \dots, x_n\) 和 \(m\) 个形如:
\[x_j - x_i \le c_k \]
的约束,其中 \(c_k\) 是常数(可为负数)。
我们的目标是:判断是否存在一组实数解(或整数解)满足所有约束,若存在则找出一组可行解。
为什么图论可以解决它?
每个不等式 \(x_j - x_i \le c\) 可以改写为:
\[x_j \le x_i + c \]
这类似于最短路径问题中的 三角不等式:
设 \(\text{dist}[i]\) 表示从某个起点到节点 \(i\) 的最短距离,则对于边 \(i \to j\) 权值为 \(c\),有:
\[\text{dist}[j] \le \text{dist}[i] + c \]
因此,我们可以把每个变量 \(x_i\) 看作图中的一个节点,每个约束 \(x_j - x_i \le c\) 对应一条从 \(i\) 到 \(j\)、权值为 \(c\) 的有向边。
如果图中存在 负权环,则约束系统无解;否则,从虚拟起点到各节点的最短距离就是一组可行解。
建模步骤
- 建立 \(n\) 个节点,编号 \(1\) 到 \(n\),对应变量 \(x_1, \dots, x_n\)。
- 对于每个约束 \(x_j - x_i \le c\),添加一条有向边 \(i \to j\) 权值为 \(c\)。
- 为了能够从单一源点到达所有节点,添加一个 超级源点 \(0\),并添加 \(n\) 条边 \(0 \to i\) 权值为 \(0\)(即约束 \(x_i - x_0 \le 0\),相当于 \(x_i \le x_0\),因为 \(x_0\) 可设为任意值,这不会影响相对关系)。
- 运行 Bellman-Ford 算法(因为权值可为负)从节点 \(0\) 求最短路径。
- 若发现负权环 → 约束系统无解。
- 若无负权环 → 设 \(d[i]\) 为从 \(0\) 到 \(i\) 的最短距离,则 \(x_i = d[i]\) 就是一组可行解。
为什么超级源点权值为 0 是合理的?
添加 \(0 \to i\) 权 \(0\) 后,约束为 \(x_i \le x_0\)。由于 \(x_0\) 是自由变量,我们可以令 \(x_0 = 0\),则得到 \(x_i \le 0\),这看起来会限制解的范围,但实际上差分约束系统的解在 平移 下保持不变(所有变量加同一个常数仍满足不等式)。
因此我们求出的解 \(x_i = d[i]\) 可能满足 \(x_i \le 0\),但如果想要非负解,可以整体加上一个足够大的常数。
算法流程
- 输入:
- \(n\):变量个数
- \(m\):约束个数
- 每个约束:\(i, j, c\) 表示 \(x_j - x_i \le c\)
- 建图:
- 节点数 = \(n+1\)(0 为超级源点)
- 对每个约束加边
i → j权值c - 对所有
i = 1..n加边0 → i权值0
- 运行 Bellman-Ford 从源点 0 计算最短距离数组
dist[0..n]:- 迭代 \(n\) 轮松弛所有边
- 再进行一轮松弛,如果还能更新距离 → 存在负权环 → 输出 无解
- 否则输出
dist[1..n]作为一组可行解。
举例说明
假设约束系统为:
\[\begin{cases} x_2 - x_1 \le 3 \\ x_3 - x_2 \le -2 \\ x_1 - x_3 \le -1 \end{cases} \]
建图(节点 1,2,3 对应 \(x_1,x_2,x_3\)):
- 约束 1:边 \(1 \to 2\) 权 3
- 约束 2:边 \(2 \to 3\) 权 -2
- 约束 3:边 \(3 \to 1\) 权 -1
- 加超级源点 0 到 1,2,3 权 0。
Bellman-Ford 从 0 开始:
初始化 dist[0]=0,dist[1..3]=∞。
松弛过程略(手动验证可知最终得到最短路径值)。
检查是否有负环:
沿着环 \(1 \to 2 \to 3 \to 1\) 权值和 = 3 + (-2) + (-1) = 0,不是负环,所以有解。
一组解:
设 dist[0]=0,则 dist[1]=0,dist[2]=3,dist[3]=1 是一组可行解(验证所有不等式成立)。
复杂度
- 节点数 \(n+1\),边数 \(m+n\)
- Bellman-Ford 复杂度 \(O((n+1)(m+n))\)
- 通常 \(m \sim O(n^2)\),所以复杂度 \(O(n^3)\),适合 \(n \le 10^3\) 规模。
应用场景
差分约束常见于:
- 任务调度中的前后时间限制
- 图形布局中的相对位置约束
- 资源分配中的差值限制
理解这一算法有助于将线性不等式问题转化为图论问题,利用已有的最短路径工具求解。