如何在OPL中打印特定实例的约束评估结果?
如何在CP Optimizer的OPL模型中打印特定约束的评估结果
我有一个基于CP Optimizer的调度问题OPL模型(.mod文件),代码如下:
using CP; int nbJobs = ...; int nbMchs = ...; range Jobs = 0..nbJobs-1; range Mchs = 0..nbMchs-1; int OpDurations[j in Jobs][m in Mchs] = ...; dvar interval itvs[j in Jobs][m in Mchs] size OpDurations[j][m]; dvar sequence mchs[m in Mchs] in all(j in Jobs) itvs[j][m]; execute { cp.param.FailLimit = 10000; } minimize max(j in Jobs) endOf(itvs[j][nbMchs-1]); subject to { forall (m in Mchs) noOverlap(mchs[m]); forall (j in Jobs, o in 0..nbMchs-2) endBeforeStart(itvs[j][o], itvs[j][o+1]); }
我希望针对特定实例(.dat文件),打印出不同m值对应的noOverlap(mchs[m])约束的评估结果,请问是否可以实现?
可以实现,以下是两种常用方案:
方法一:通过约束句柄直接评估
为每个noOverlap约束创建句柄,在求解后的execute块中调用内置方法评估约束是否满足,这是最直接高效的方式。
修改后的完整模型代码:
using CP; int nbJobs = ...; int nbMchs = ...; range Jobs = 0..nbJobs-1; range Mchs = 0..nbMchs-1; int OpDurations[j in Jobs][m in Mchs] = ...; dvar interval itvs[j in Jobs][m in Mchs] size OpDurations[j][m]; dvar sequence mchs[m in Mchs] in all(j in Jobs) itvs[j][m]; // 定义约束句柄数组,存储每台机器的noOverlap约束 constraint noOverlapConstr[m in Mchs] = noOverlap(mchs[m]); execute { cp.param.FailLimit = 10000; } minimize max(j in Jobs) endOf(itvs[j][nbMchs-1]); subject to { forall (m in Mchs) noOverlapConstr[m]; forall (j in Jobs, o in 0..nbMchs-2) endBeforeStart(itvs[j][o], itvs[j][o+1]); } // 求解完成后打印约束评估结果 execute after solve { writeln("=== 各机器noOverlap约束评估结果 ==="); for (var m in Mchs) { var isSat = noOverlapConstr[m].isSatisfied(); writeln("机器", m, ": ", isSat ? "满足约束" : "不满足约束"); } }
方法二:手动检查序列间隔是否重叠
如果需要自定义检查逻辑(比如定位具体重叠任务),可以在求解后遍历机器序列,手动验证任务间隔是否存在重叠:
// 求解后手动检查约束情况,可添加到原模型末尾 execute after solve { writeln("=== 各机器任务间隔重叠检查结果 ==="); for (var m in Mchs) { var overlapFound = false; // 收集当前机器所有任务的时间区间 var taskTimes = []; for (var j in Jobs) { taskTimes.push({ start: startOf(itvs[j][m]), end: endOf(itvs[j][m]) }); } // 按开始时间排序,便于检查相邻任务 taskTimes.sort(function(a,b) { return a.start - b.start; }); // 遍历检查是否有重叠 for (var i=0; i<taskTimes.length-1; i++) { if (taskTimes[i].end > taskTimes[i+1].start) { overlapFound = true; break; } } writeln("机器", m, ": ", overlapFound ? "存在任务重叠(不满足约束)" : "无任务重叠(满足约束)"); } }
内容的提问来源于stack exchange,提问作者Fco.Jav.Y
相关产品推荐
相关产品推荐

