CPLEX OPL中高优先级订单同车分组软目标的编码方法
OPL 高优先级订单集中分配软目标实现方案
要实现CategoryPriority=1高优先级订单占用货运班次最少的软优化目标,核心逻辑是新增班次使用标记变量,统计承载高优先级订单的班次总数作为最小化目标,具体实现步骤如下:
实现逻辑
- 先筛选出所有高优先级订单构成子集
- 为每个货运班次新增0-1标记变量,标识该班次是否承载了至少1个高优先级订单
- 增加约束建立标记变量和原有分配变量
Assignment的逻辑关联 - 将所有标记变量的求和值作为
objective1,该值直接等于高优先级订单占用的班次总数,最小化该值即可实现需求
修改后完整.mod代码
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; }; {TFreightTypes} FreightTypes = ...; {TOrders} Orders = ...; // 筛选高优先级订单子集 {TOrders} HighPriOrders = {o | o in Orders : o.CategoryPriority == 1}; dvar boolean Assignment[Orders][FreightTypes]; // 新增标记变量:1代表对应班次承载了高优先级订单,0代表未承载 dvar boolean TruckUsedForHighPri[FreightTypes]; // 总成本最小化核心目标 dexpr float objective = sum(o in Orders, f in FreightTypes) Assignment[o][f] * f.Cost; // 高优先级订单占用班次总数最小化软目标 dexpr float objective1 = sum(f in FreightTypes) TruckUsedForHighPri[f]; minimize 0.95*objective+0.05*objective1; subject to{ //c1: 所有订单必须全部分配 forall(o in Orders) sum(f in FreightTypes) Assignment[o][f]==1; //c2: 标记变量关联约束:只要班次上有任意高优先级订单,标记必须置为1 forall(f in FreightTypes) sum(o in HighPriOrders) Assignment[o][f] <= card(HighPriOrders) * TruckUsedForHighPri[f]; /* 原有模型缺少的基础业务约束,建议补充避免无效解: 1. 目的地匹配约束:订单只能分配到目的地一致的班次 forall(o in Orders, f in FreightTypes: o.Destination != f.Destination) Assignment[o][f] == 0; 2. 班次载重约束:每个班次分配的订单总重量不能超过班次限重 forall(f in FreightTypes) sum(o in Orders) Assignment[o][f] * o.Weight <= f.TotalWeight; */ }
注意事项
- 你提供的示例dat中,现有货运班次目的地分别为伦敦、杜伦,没有同时覆盖两个目的地的班次,如果要实现订单2(杜伦)、订单3(伦敦)同车的最优结果,需要在
FreightTypes中补充支持多目的地配送/对应路线的班次数据,否则受目的地匹配约束限制无法实现同车。 - 目标权重可以根据业务优先级调整:如果要优先保证高优先级订单集中,再考虑成本,可以适当提高
objective1的权重,只要保证objective1的权重乘以最大可能班次数量,小于单次货运的最小成本,求解器就会优先满足高优先级订单集中的要求,再优化总成本。
内容的提问来源于stack exchange,提问作者william007
相关产品推荐
相关产品推荐

