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

如何在CPLEX Studio的OPL中实现WFP优先级约束?

WFP优化问题:OPL中紧急等级分发约束的实现

我正在处理世界粮食计划署(WFP)的优化问题:一组分属不同区域的国家,每个国家对应R、L2或L3(严重程度递增)的紧急等级。已完成大部分约束建模,现需实现以下核心约束:仅当所有紧邻的更高紧急等级国家的粮食需求至少满足60%时,才能向更低紧急等级国家分发食品包。需要在OPL语言中实现该约束以在CPLEX Studio中求解,现有代码如下:

{string} Countries = ...;
{string} Regions = ...;
int Emergency_levels[Regions][Countries] = ...;
int Needs[Regions][Countries] = ...;
int MAX_BASKETS = ...;
int Container_Cost_Transport[Regions] = ...;
int Container_Capacity = ...;
float LG[Regions][Countries] = ...;
float LA[Regions][Countries] = ...;
float DG[Regions][Countries] = ...;
float DA[Regions][Countries] = ...;
float CG[Regions][Countries] = ...; 
float CA[Regions][Countries] = ...;
int MAX_BUDGET = ...;
float Threshold = ...;

// Decision variables
dvar int Region_Containers[Regions];//number of containers to send to region
dvar int GX[Regions][Countries]; // number of baskets transported by ground from region i to country j
dvar int AX[Regions][Countries]; // number of baskets transported by air from region i to country j
dvar int Threshold_Respected[]

maximize sum(i in Regions, j in Countries) ((GX[i][j]*(1-LG[i][j])*DG[i][j]) + (AX[i][j]*(1-LA[i][j])*DA[i][j]));

subject to{
  //Check that total number of baskets is respected
  sum(i in Regions, j in Countries) (GX[i][j] + AX[i][j]) <= MAX_BASKETS;
  //cant send more baskets than the needs
  forall(i in Regions, j in Countries)
    GX[i][j] + AX[i][j] <= Needs[i][j];
  
  //Ensures full container loads
  forall(i in Regions)
    sum(j in Countries) (GX[i][j] + AX[i][j]) == Region_Containers[i]*150;
  //Ensure budget is respect
  (   sum(i in Regions) Container_Cost_Transport[i]*Region_Containers[i] + sum(i in Regions,j in Countries) (GX[i][j]*CG[i][j] + AX[i][j]*CA[i][j])   )  <= MAX_BUDGET;
  // TODO: Constraint for emergency level threshold
}

实现步骤说明

  1. 补充邻接关系定义:需明确国家间的“紧邻”业务/地理关系,添加集合存储每个国家的邻国列表。
  2. 紧急等级数值化:将R、L2、L3转换为可比较的数值(如R=1,L2=2,L3=3),方便判断等级高低。
  3. 线性化约束逻辑:用大M法处理“仅当...才...”的逻辑,避免除法运算,将需求满足率要求转换为线性不等式。

修改后的完整OPL代码

{string} Countries = ...;
{string} Regions = ...;
// 补充:定义每个国家的紧邻国家列表,需根据实际业务填充
{string} AdjacentCountries[Countries] = ...;

// 紧急等级数值化:R=1,L2=2,L3=3(严重程度递增)
int Emergency_levels[Regions][Countries] = ...;
int Needs[Regions][Countries] = ...;
int MAX_BASKETS = ...;
int Container_Cost_Transport[Regions] = ...;
int Container_Capacity = ...;
float LG[Regions][Countries] = ...;
float LA[Regions][Countries] = ...;
float DG[Regions][Countries] = ...;
float DA[Regions][Countries] = ...;
float CG[Regions][Countries] = ...; 
float CA[Regions][Countries] = ...;
int MAX_BUDGET = ...;
// 定义需求满足阈值:60%
float Threshold = 0.6;
// 大M常数:取单个国家最大需求值,确保约束逻辑生效
int M = max(i in Regions, j in Countries) Needs[i][j];

// Decision variables
dvar int Region_Containers[Regions];//number of containers to send to region
dvar int GX[Regions][Countries]; // number of baskets transported by ground from region i to country j
dvar int AX[Regions][Countries]; // number of baskets transported by air from region i to country j
// 0-1变量:标记是否向国家j分发了食品包,简化约束逻辑
dvar boolean IsDistributed[Regions][Countries];

maximize sum(i in Regions, j in Countries) ((GX[i][j]*(1-LG[i][j])*DG[i][j]) + (AX[i][j]*(1-LA[i][j])*DA[i][j]));

subject to{
  //Check that total number of baskets is respected
  sum(i in Regions, j in Countries) (GX[i][j] + AX[i][j]) <= MAX_BASKETS;
  //cant send more baskets than the needs
  forall(i in Regions, j in Countries)
    GX[i][j] + AX[i][j] <= Needs[i][j];
  
  //Ensures full container loads
  forall(i in Regions)
    sum(j in Countries) (GX[i][j] + AX[i][j]) == Region_Containers[i]*150;
  //Ensure budget is respected
  (sum(i in Regions) Container_Cost_Transport[i]*Region_Containers[i] + 
   sum(i in Regions,j in Countries) (GX[i][j]*CG[i][j] + AX[i][j]*CA[i][j])) <= MAX_BUDGET;

  // 关联分发数量与IsDistributed变量
  forall(i in Regions, j in Countries) {
    // 如果分发了食品包,IsDistributed必须为1
    GX[i][j] + AX[i][j] <= M * IsDistributed[i][j];
    // 如果IsDistributed为1,至少分发1个食品包(适配整数变量特性)
    GX[i][j] + AX[i][j] >= 1 * IsDistributed[i][j];
  }

  // 核心约束:仅当所有紧邻更高等级国家需求满足≥60%时,才能向低等级国家分发
  forall(i in Regions, j in Countries) {
    forall(k in AdjacentCountries[j]) {
      // 仅当j的紧急等级低于k,且k有需求时应用约束
      if (Emergency_levels[i][j] < Emergency_levels[i][k] && Needs[i][k] > 0) {
        // 若向j分发,则k的需求必须满足至少60%;否则约束自动失效
        GX[i][k] + AX[i][k] >= Threshold * Needs[i][k] - M * (1 - IsDistributed[i][j]);
      }
    }
  }
}

关键约束解释

  • 邻接关系:AdjacentCountries需根据实际地理或业务规则填充,例如AdjacentCountries["Kenya"] = {"Uganda", "Tanzania"}。
  • 大M法逻辑:当IsDistributed[i][j]=1(向j分发)时,右侧惩罚项为0,强制GX[i][k]+AX[i][k]≥0.6*Needs[i][k];当IsDistributed[i][j]=0时,约束自动放松,不限制对k的分发情况。
  • 等级数值化:确保Emergency_levels的数值与紧急程度正相关,通过Emergency_levels[i][j] < Emergency_levels[i][k]快速判断j为更低等级国家。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:34:58