3. 冲突诊断的数据准备

约束冲突诊断的结论是否可信,很大程度上不取决于求解器有多强,而取决于喂给它的数据有多干净。一个常见的误区是:模型出现"不可行"就立刻去改约束、放松右端项,结果发现真正的问题是一条单位写错的产能约束,或者某个系数在复制粘贴时多了一个零。因此,在启动任何冲突识别算法(如 IIS 极小不可行子集、弹性松弛、冲突约束对定位)之前,必须先完成三件事:模型数据清洗、约束系数与右端项核查、量纲与单位一致性检查,并把整个过程固化为可复现的数据集。

一、数据清洗:先让数据"可被信任"

清洗的目标不是把数据改漂亮,而是消除那些会让诊断结果失真的噪声。典型噪声有四类:缺失值、重复记录、异常值与逻辑矛盾。以某工厂产能分配模型为例,原始数据来自三张表:产品需求表、产线能力表、工艺消耗表。清洗时应逐项处理:

  • 缺失值:需求表中某产品某月需求为空。不能简单填 0,因为 0 会人为制造"需求已满足"的假象,掩盖真实冲突。应区分"确认为零"与"未知",未知项标记为待确认,并在诊断数据集中保留来源标记。
  • 重复记录:同一产线同一产品出现两条能力记录,若直接求和会高估产能,导致冲突被掩盖。应按主键去重并记录去重前后的条数差异。
  • 异常值:某产品单件工时记录为 480 小时,而同类产品均在 2~5 小时,明显是单位或小数点错误。异常值需回溯原始单据,不可直接截断。
  • 逻辑矛盾:最小批量大于最大批量、下界大于上界。这类矛盾本身就是冲突源,应在清洗阶段单独列出,而不是留给求解器报错。

清洗的产出应是一份带版本号的数据快照,例如 demand_clean_v3.csv,并附一份变更日志,记录每条被修改记录的原值、新值、修改依据和责任人。没有变更日志的清洗等于不可复现。

二、约束系数与右端项核查:抓住"数量级"和"符号"

系数与右端项是约束的骨架,错误往往集中在两处:数量级错位和符号方向错误。核查时建议采用"逐约束回读"的方法:把每条约束按业务语义翻译成一句自然语言,再与系数对照。例如约束 2x_A + 3x_B ≤ 1200,回读为"产品 A 每件耗 2 单位资源、B 每件耗 3 单位,总资源不超过 1200",若业务上 A 的消耗应高于 B,则系数顺序可能写反。

数量级核查可用"量级比值"快速筛查:对同一类约束,计算右端项与系数之和的比值,若某条约束的比值偏离同类中位数一个数量级以上,标记为可疑。符号核查则关注不等式方向:产能类约束通常为"≤",需求满足类约束通常为"≥",若出现方向颠倒,求解器会直接报不可行,但根因是建模笔误而非真实冲突。

建议在诊断数据集中为每条约束保留四个字段:约束名、业务含义、系数向量、右端项,并额外增加"核查状态"字段(待查/已核/存疑)。这样在后续定位冲突时,可以优先怀疑"存疑"约束,缩小排查范围。

三、量纲与单位一致性:冲突的隐形来源

量纲不一致是最隐蔽的冲突源。同一模型中,时间可能混用"小时"与"分钟",重量可能混用"吨"与"千克",金额可能混用"元"与"万元"。这类错误不会让模型语法报错,却会让约束在数值上互相矛盾。检查方法是建立单位登记表:为每个变量、每个参数标注单位,然后逐条约束做量纲运算,要求等式或不等式两侧单位一致。

例如约束"总工时 ≤ 可用工时",若总工时以分钟计、可用工时以小时计,则右端项需乘以 60,否则约束被人为收紧 60 倍,极易触发假冲突。实操中可先在数据字典中统一基准单位(如时间统一为小时、重量统一为千克),再在导入环节做一次强制换算,换算规则写入脚本而非手工修改,保证可复现。

冲突诊断数据集的三道数据关卡 原始数据 需求表 / 能力表 工艺消耗表 ① 数据清洗 缺失值 · 重复记录 异常值 · 逻辑矛盾 产出:带版本快照+变更日志 ② 系数与右端项核查 逐约束回读业务语义 量级比值筛查 · 符号方向 产出:核查状态字段 ③ 量纲一致性 单位登记表 约束两侧量纲运算 产出:统一基准单位 可复现冲突诊断数据集 数据快照 + 变更日志 + 约束核查表 + 单位登记表 冲突识别:IIS / 弹性松弛 / 冲突对定位 结论可追溯至具体数据版本与核查记录 任一关卡缺失,冲突诊断都可能把"数据错误"误判为"模型冲突"

四、把流程固化为可复现的数据集

三道关卡完成后,需要把结果组织成一个可复现的诊断数据集。所谓"可复现",指任何人拿到这个数据集,都能得到相同的冲突诊断结论。为此,数据集至少应包含四部分:清洗后的数据快照(固定版本号)、变更日志(记录每处修改的依据)、约束核查表(每条约束的业务含义与核查状态)、单位登记表(变量与参数的单位及换算规则)。

下面给出一个约束核查表的示例结构,字段直接对应诊断需要:

约束名业务含义系数向量右端项单位核查状态
cap_line1产线1月度可用工时上限[2, 3]1200小时已核
demand_A产品A需求满足[1]500件已核
cap_line2产线2月度可用工时上限[1.5, 2.5]90小时存疑(量级偏低)
min_batch_B产品B最小批量[1]800件存疑(与最大批量矛盾)

表中 cap_line2 的右端项 90 小时相对同类约束明显偏低,min_batch_B 与最大批量存在逻辑矛盾,这两条被标记为"存疑"。在后续冲突诊断中,应优先检查这两条约束,而不是盲目放松所有约束。这正是数据准备的价值:把诊断的搜索空间从"全部约束"缩小到"可疑约束"。

常见陷阱:清洗时"顺手"把可疑数据改成合理值,却不留记录。这样虽然模型能跑通,但真实冲突被掩盖,诊断结论失去意义。正确做法是保留原值、标注疑点、单独列出,让冲突诊断过程显式地处理它们。

最后需要强调一致性原则:全文及图示中,不等式方向统一按"资源受限用 ≤、需求满足用 ≥"表述,单位统一以小时、件、千克为基准。若原始数据使用其他单位,换算规则必须写入脚本并在数据集中注明,避免不同人用不同基准导致结论不可比。完成以上准备后,冲突诊断才真正建立在可信数据之上,后续的 IIS 定位与修复建议才有可追溯的依据。