CPLEX OPL模型中货运物料兼容性约束的编码实现方法
OPL货运配载物料类别兼容约束实现方案
实现思路
要实现「仅物料类别互相兼容的订单可配载至同一货运班次」的规则,核心是先显式定义物料兼容关系,再对每个班次增加同载订单的类别校验逻辑,避免不兼容类别的订单被分配到同一班次。
代码修改方案
1. 修改.mod模型文件
首先在元组和集合定义段,新增物料兼容关系的结构与集合声明,再补全c2约束的具体逻辑,完整修改后的相关代码段如下:
tuple TFreightTypes { key string Destination; key string VehicleType; int TotalWeight; key string Company; int Cost; }; tuple TOrders { key int OrderNumber; float Weight; string ClientId; string Destination; string MaterialCategory; int CategoryPriority; }; // 新增:物料类别兼容元组,存储所有允许共同配载的类别对 tuple TCategoryCompat { key string CatA; key string CatB; }; {TFreightTypes} FreightTypes = ...; {TOrders} Orders = ...; // 新增:物料兼容规则集合,从数据文件读取 {TCategoryCompat} CategoryCompat = ...; dvar boolean Assignment[Orders][FreightTypes]; dexpr float objective = sum(o in Orders, f in FreightTypes) Assignment[o][f] * f.Cost; // 选择总成本最低的货运组合 minimize objective; subject to{ // 可选补充基础约束:订单仅能配载到目的地一致的班次,避免跨目的地错配 forall(o in Orders, f in FreightTypes) { o.Destination != f.Destination => Assignment[o][f] == 0; } //c1: 所有订单必须完成履约 forall(o in Orders) sum(f in FreightTypes) Assignment[o][f]==1; //c2: 同班次配载的订单物料类别必须互相兼容 // 遍历所有班次、所有订单对,通过订单号大小判断避免重复校验 forall(f in FreightTypes, o1 in Orders, o2 in Orders: o1.OrderNumber < o2.OrderNumber) { // 若两个订单都分配到当前班次,则二者类别必须在兼容集合内 (Assignment[o1][f] == 1 && Assignment[o2][f] == 1) => (<o1.MaterialCategory, o2.MaterialCategory> in CategoryCompat); } }
说明:约束中使用
o1.OrderNumber < o2.OrderNumber做筛选,是为了避免同一对订单被重复校验两次,可有效减少约束总数,提升求解效率;=>是OPL内置的蕴含运算符,左侧条件成立时右侧条件必须满足。
2. 修改.dat数据文件
在数据文件中补充物料兼容规则的具体取值,按照业务规则(A、B类可兼容共配,C类与A、B类均不兼容、同类物料可共配),新增如下配置段:
FreightTypes = { <"LONDON","Type1",20000,"SP TRANSPORTS",40000>, <"LONDON","Type2",20000,"SP TRANSPORTS",40000>, <"DURHAM","Type3",10000,"SP TRANSPORTS",30000>, }; Orders = { <1,5000,"Client1","LONDON","A",0>, <2,1000,"Client2","DURHAM","B",1>, <3,2000,"Client3","LONDON","C",1>, }; // 新增:物料兼容规则配置 CategoryCompat = { <"A","A">, <"A","B">, <"B","A">, <"B","B">, <"C","C"> };
效果验证
添加上述约束后,求解器不会再将C类订单与A、B类订单分配到同一班次,自然不会出现「成本最低的第3个班次承载所有订单」的不符合规则的解,符合业务要求。
内容的提问来源于stack exchange,提问作者william007
相关产品推荐
相关产品推荐

