CPLEX OPL目标函数及周期平衡约束报错问题咨询
错误原因与修复方案
两个报错的直接原因
cannot use type range for int:你在目标函数里将范围对象T(你定义的1..Time)直接作为数组下标使用,T是范围类型不是整数,不能用于索引数组。operator not available for range - int:你在约束里写T-1,范围类型和整数不能直接做减法运算,且你混淆了范围T和循环迭代变量t。
修复步骤
步骤1:修正范围定义,支持初始周期索引
你原来的T从1开始,无法访问t=0的初始库存、初始仓库容量,需要新增包含初始周期的范围:
int Time = ...; range T = 1..Time; range T0 = 0..Time; // 新增包含初始期0的范围,用于存储t=0的初始状态
步骤2:修正决策变量索引范围与拼写
原来的变量索引仅覆盖1..Time,无法存储初始值,且注意OPL大小写敏感,不要混用大小写变量名:
// Parameters int d [T] = ...; // demand in period t int K [T] = ...; // fixed order cost in period t,注意和数据文件的参数名大小写匹配 int h [T] = ...; // unit holding cost in period t int p [T] = ...; // fixed cost of increasing WH size in period t int q [T] = ...; // fixed cost of decreasing WH size in period t(原注释写错了,q是缩容固定成本) int e [T] = ...; // variable cost of increasing WH size in period t int c [T] = ...; // variable cost of decreasing WH size in period t int r [T] = ...; // WH rental cost per unit in period t dvar int+ x[T]; //order size in period t dvar int+ i[T0]; //inventory lvl at the end of period t,i[0]为初始库存 dvar int+ w[T0]; // warehouse size at the end of period t,w[0]为初始仓库容量 dvar int+ u[T]; // warehouse size expansion at beginning of period t dvar int+ v[T]; // warehouse size contraction at beginning of period t dvar boolean y[T]; // binary variable for ordering in period t dvar boolean z1[T]; // binary variable for WH expansion in period t dvar boolean z2[T]; // binary variable for WH contraction in period t
步骤3:修正目标函数
原目标函数误用大写T作为下标,且出现了未定义的i1、w1变量,修正后如下:
dexpr int Cost = sum(t in T)(K[t]*y[t] + h[t]*i[t] + p[t]*z1[t] + e[t]*u[t] + q[t]*z2[t] + c[t]*v[t] + r[t]*w[t]); minimize Cost;
步骤4:修正平衡约束
初始值约束不能放在forall循环内,且下标要改用迭代变量t:
subject to { // 初始状态单独定义,不要放在循环中 i[0] == 0; // 初始库存为0,可按需修改 w[0] == 0; // 初始仓库容量为0,可按需修改 forall(t in T) { // 库存平衡约束 i[t-1] + x[t] - d[t] == i[t]; // 仓库容量平衡约束 w[t-1] + u[t] - v[t] == w[t]; // 库存不超过仓库容量 i[t] <= w[t]; // 订货二进制约束 x[t] <= sum(tt in t..Time) d[tt] * y[t]; // 这里用后续周期总需求作为上限更合理,也可保留你原来的d[t] // 扩容二进制约束 u[t] <= 10000*z1[t]; // 不要用d[t]作为扩容上限,换成足够大的整数即可 // 缩容二进制约束 v[t] <= 10000*z2[t]; // 新增约束:同一周期不能同时扩容和缩容,避免无意义解 z1[t] + z2[t] <= 1; } }
其他注意事项
- 数据文件里的参数名要和模型里的大小写完全匹配,比如数据里的小写
k要和模型里的K对应,否则会报数据匹配错误 - 不要混用大小写变量名,比如你原来代码里写的大写
I和你定义的小写i是两个完全不同的变量
内容的提问来源于stack exchange,提问作者Willem B
相关产品推荐
相关产品推荐

