2. 约束系统建模基础
在优化问题中,我们最终要回答的其实是一个很朴素的问题:在所有“允许的方案”里,哪一个“最好”。约束系统建模就是把这句话翻译成数学语言的过程。它由三块拼成:决策变量回答“我在调整什么”,约束条件回答“什么方案是允许的”,目标函数回答“什么叫好”。三者缺一不可,而冲突诊断的全部线索,几乎都藏在这三块之间的相互关系中。
决策变量:把“可调的东西”写成符号
决策变量是模型里真正由求解器去选择的量。例如一个生产计划问题,设 x₁ 为产品 A 的产量、x₂ 为产品 B 的产量,单位统一为“件/天”。变量一旦定义,就要同时明确三件事:含义、单位、取值范围。取值范围本身就是最基础的约束,比如 x₁ ≥ 0、x₂ ≥ 0,若产量必须是整数,还要加上 x₁, x₂ ∈ ℤ。很多“看起来无解”的模型,根源其实是变量定义域写错了——例如把本应非负的变量漏掉了下界,或把连续量误设为整数。
需要区分两类量:决策变量是求解器可以自由选择的;参数是建模时给定的常数,如单位利润、原料单耗、可用工时。诊断冲突时,先分清“哪个是变量、哪个是参数”非常关键,因为冲突往往表现为“参数给定的上限”与“变量必须满足的下限”之间无法调和。
约束条件:把“允许”写成等式与不等式
约束条件通常分为三类。第一类是资源约束,形如 2x₁ + 3x₂ ≤ 120,表示两种产品对某原料的单耗乘以产量之和不超过库存。第二类是需求约束,形如 x₁ + x₂ ≥ 50,表示总产量必须达到订单量。第三类是逻辑/工艺约束,如 x₁ ≤ 0.6(x₁ + x₂),表示产品 A 占比不超过 60%。等式约束(如配料比例 x₁ - 2x₂ = 0)比不等式更“硬”,它直接把解限制在一个低维平面上,也更容易引发冲突。
写约束时有两个易错点值得强调。其一是方向与符号:≤ 与 ≥ 一旦写反,可行域会从“一小块”变成“一大片”,模型可能从无解变成有解但答案荒谬。其二是量纲一致:约束两端必须同单位,否则系数含义混乱,后续诊断时无法判断哪条约束真正卡住了可行域。
目标函数:把“好”写成一个可比较的数
目标函数把方案映射为一个实数,常见形式是线性的 max z = 5x₁ + 4x₂(利润最大化)或 min c = 3x₁ + 2x₂(成本最小化)。目标函数本身不决定可行性——它只在可行域内挑最优点。这一点在冲突诊断中极其重要:如果模型无解,问题一定出在约束系统,而不是目标函数。因此排障时应先把目标函数“放一边”,专注检查约束之间是否自相矛盾。
可行域:约束系统的几何像
把每个约束看成平面(或高维空间)中的一个半空间,所有约束的交集就是可行域。二维情形下,它通常是多边形;三维是多面体;更高维则是多面体在高维空间中的推广。线性规划的一个基本结论是:若可行域非空且有界,最优解必在可行域的某个顶点取得。这解释了为什么单纯形法只需在顶点间移动。
下面的图用一个二维示例把“约束—可行域—冲突”三者放在同一张图上:两条资源约束与两条需求约束围出一块可行域,目标函数的等值线从原点向外平移,最后与可行域相切于一个顶点;而右侧另一组约束则因为上下界方向相反,交集为空,形成典型的不可行情形。
左图中,四条约束围出的绿色多边形就是可行域,红色虚线是目标函数的等值线,它向外平移直到与可行域相切于顶点 (x₁, x₂) = (30, 20)(示例数值,用于说明几何关系)。右图则展示了另一种情形:x₁ ≥ 80 与 x₁ ≤ 50 两个约束方向相反,它们的半空间没有公共部分,可行域为空集,模型必然无解。
冲突与不可行性的关系
需要明确一个关键区分:不可行是结果,冲突是原因。不可行性指可行域为空,即不存在同时满足所有约束的解;而冲突指约束之间存在无法同时满足的矛盾。一个模型不可行,必然存在至少一组约束构成冲突;但反过来,单个约束本身“很紧”并不等于冲突——只有当它与另一条约束的要求方向相反、且无法同时满足时,才构成冲突。
冲突可以进一步分为两类。直接冲突是两条约束在同一变量上给出矛盾区间,如上面的 x₁ ≥ 80 与 x₁ ≤ 50,一眼可辨。间接冲突则更隐蔽:单看每条约束都合理,但组合起来无解。例如 x₁ + x₂ ≤ 10、x₁ ≥ 6、x₂ ≥ 6,三条约束各自都成立,但前两条推出 x₂ ≤ 4,与第三条矛盾。这类冲突往往需要借助求解器的不可行性分析(如 IIS,不可约不可行子系统)来定位。