You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CPLEX OPL中单货运最多服务2个客户的约束编码方法

OPL实现单班次收货客户数不超过2个的约束方案

核心逻辑:由于约束统计的是去重后的客户ID数量,而非订单数量,因此不能直接通过订单分配变量计数,需要引入辅助0-1变量标记「某客户是否有订单被分配到对应班次」,再对单班次的标记值做上限约束。


具体编码步骤

1. 补充集合与辅助变量定义

在原有决策变量Assignment的定义段后,新增全量客户集合、客户-班次使用标记变量:

// 提取所有订单涉及的不重复客户ID集合
{string} AllClients = {o.ClientId | o in Orders};

// 辅助0-1变量:ClientUse[c][f] = 1 代表客户c有订单分配到班次f,为0则代表无
dvar boolean ClientUse[AllClients][FreightTypes];

2. 在约束块新增对应规则

在subject to块中补充两组约束,替换原有未写完的c2注释即可:

subject to{

  //c1: 所有订单必须全部分配完成履约
  forall(o in Orders)
    sum(f in FreightTypes) Assignment[o][f]==1;
    
  //c2: 关联订单分配变量与客户使用标记:客户只要有1个订单分到该班次,标记必须置1
  forall(c in AllClients, f in FreightTypes)
    sum(o in Orders: o.ClientId == c) Assignment[o][f] <= ClientUse[c][f] * count(o in Orders: o.ClientId == c);

  //c3: 单个货运班次承载的不同收货ClientId数量不得超过2个
  forall(f in FreightTypes)
    sum(c in AllClients) ClientUse[c][f] <= 2;
   
}

约束逻辑说明

  • c2约束的不等式左侧是「客户c在班次f上分配到的订单总数」,右侧是客户标记值乘以该客户的总订单数:
    • 只要左侧≥1(即客户有订单分到该班次),ClientUse[c][f]必须取1才能满足不等式,否则右侧值为0,会小于左侧正数导致约束不成立
    • 如果左侧=0(客户无订单分到该班次),ClientUse[c][f]取0即可满足约束,且由于c3限制了单班次客户数上限,求解器为了拿到最低成本,不会无故将标记置1占用名额,无需额外添加反向约束。

示例数据求解效果

新增约束前,求解器会选择成本最低的30000元DURHAM班次承运全部3个订单;新增约束后,由于3个订单分属3个不同ClientId,该班次最多只能承载2个订单,剩余1个订单需要分配到其他40000元的班次,最终最低总成本为70000元,符合业务规则要求。

内容的提问来源于stack exchange,提问作者william007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:03:25