CPLEX模型运行报错:表达式提取失败及数组索引越界求助
CPLEX OPL模型运行错误排查与解决
问题概述
刚接触CPLEX,为大学项目从零学习使用,用论文给定数据验证模型时,第一个约束出现以下错误:
-CPLEX cannot extract expression: forall... -Index out of bound for array "y#0#0":0 -OPL cannot extract expression: forall... -OPL cannot extract expression: sum...
原MOD文件
int n=...; //set of terminals range N=1..n; int t=...; //set of time periods range T=1..t; int v=...; //set of vehicles range V=1..v; range Np=1..n; range Vp=1..v; float p[Vp][Np][Np] =...; range Nc=1..n; range Vc=1..v; float c[Vc][Nc][Nc] =...; range Nd=1..n; range Td=1..t; float d[Td][Nd][Nd] =...; range Nm=1..n; range Tm=1..t; range Vm=1..v; int m[Vm][Nm][Tm] =...; range NA=1..n; range VA=1..v; int A[VA][NA][NA] =...; range Ntau=1..n;; int tau[Ntau][Ntau] =...; dvar boolean x[N][N][T][V]; dvar boolean y[N][N][T][V]; dexpr float f=sum(i in N,j in N:i!=j,t in T, v in V)(p[v][i][j]*x[i][j][t][v] - c[v][i][j]*y[i][j][t][v]); maximize f; subject to { forall(i in N, t in T, v in V)sum(j in N)(x[i][j][t][v] + y[i][j][t][v])- sum(k in N: k != i, t_ in T: t_ > tau[k][i])(x[k][i][t_-tau[k][i]][v] + y[k][i][t_-tau[k][i]][v])- y[i][i][t-1][v] == m[v][i][t]; forall(i in N, j in N, t in T) sum(v in V) x[i][j][t][v] <= d[t][i][j]; forall(i in N, j in N, t in T, v in V) A[v][i][j] == 0 => x[i][j][t][v] == 0 && y[i][j][t][v] == 0; forall(i in N, j in N, t in T, v in V) x[i][j][t][v] >= 0 && x[i][j][t][v] <= 1 && y[i][j][t][v] >= 0 && y[i][j][t][v] <= 1; }
原DAT文件
n = 6; t = 6; v = 2; c = [[ [0 1 2 2 2 2] [1 0 2 2 2 2] [2 2 0 2 1 1] [2 2 2 0 1 1] [2 2 1 1 0 1] [2 2 1 1 1 0]] [ [0 3 3 2 2 2] [3 0 3 3 2 2] [3 3 0 1 2 2] [2 3 1 0 3 3] [2 2 2 3 0 3] [2 2 2 3 3 0]] ]; p = [[ [0 1.8 3.6 3.6 3.6 3.6] [1.8 0 3.6 3.6 3.6 3.6] [3.6 3.6 0 3.6 1.8 1.8] [3.6 3.6 3.6 0 3.6 3.6] [3.6 3.6 1.8 3.6 0 1.8] [3.6 3.6 1.8 3.6 1.8 0]] [ [0 4.2 4.2 3.6 3.6 3.6] [4.2 0 4.2 4.2 3.6 3.6] [4.2 4.2 0 4.5 3.6 3.6] [3.6 4.2 4.5 0 4.2 4.2] [3.6 3.6 3.6 4.2 0 4.2] [3.6 3.6 3.6 4.2 4.2 0]] ]; //d_ijt d = [[[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 3 0 0 0 0] [0 0 0 0 0 1] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 3 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [2 0 0 0 0 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] ]; m = [[ [0 0 0 0 0 0] //m_itv [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [1 0 0 0 0 0]] [ [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 1 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] ]; A = [[ [1 0 1 1 1 1] //A_ijv [0 1 1 1 1 1] [1 1 1 1 1 1] [1 1 1 1 1 1] [1 1 1 1 1 1] [1 1 1 1 1 1]] [[1 0 1 1 1 1] [0 1 1 1 1 1] [1 1 1 1 1 1] [1 1 1 1 1 1] [1 1 1 1 1 1] [1 1 1 1 1 1]] ]; tau = [[1 2 1 1 1 2] //tau_ij [2 1 2 1 2 3] [1 2 1 1 3 2] [1 1 1 1 1 3] [1 2 3 1 1 1] [2 3 2 3 1 1]];
错误原因分析
- 索引越界:第一个约束中的
y[i][i][t-1][v],当t=1时,t-1=0,超出了时间范围T=1..t,导致数组索引越界,这是报错的核心原因。 - 无效的时间范围:第二个求和项
sum(k in N: k != i, t_ in T: t_ > tau[k][i])中,t_-tau[k][i]可能小于1,导致x[k][i][t_-tau[k][i]][v]和y[k][i][t_-tau[k][i]][v]的时间索引超出有效范围,OPL无法提取该表达式。
修正方案
- 针对
t=1的情况,添加条件判断:当t>1时取y[i][i][t-1][v],否则该项为0。 - 修正第二个求和的时间范围,确保
t_-tau[k][i]落在有效时间区间内,将t_ in T: t_ > tau[k][i]改为t_ in tau[k][i]+1..t,这样t_-tau[k][i]的最小值为1,最大值为t-tau[k][i],均在T范围内。
修正后的MOD文件
int n=...; //set of terminals range N=1..n; int t=...; //set of time periods range T=1..t; int v=...; //set of vehicles range V=1..v; range Np=1..n; range Vp=1..v; float p[Vp][Np][Np] =...; range Nc=1..n; range Vc=1..v; float c[Vc][Nc][Nc] =...; range Nd=1..n; range Td=1..t; float d[Td][Nd][Nd] =...; range Nm=1..n; range Tm=1..t; range Vm=1..v; int m[Vm][Nm][Tm] =...; range NA=1..n; range VA=1..v; int A[VA][NA][NA] =...; range Ntau=1..n; int tau[Ntau][Ntau] =...; dvar boolean x[N][N][T][V]; dvar boolean y[N][N][T][V]; dexpr float f=sum(i in N,j in N:i!=j,t in T, v in V)(p[v][i][j]*x[i][j][t][v] - c[v][i][j]*y[i][j][t][v]); maximize f; subject to { // 修正后的第一个约束 forall(i in N, t in T, v in V) sum(j in N)(x[i][j][t][v] + y[i][j][t][v]) - sum(k in N: k != i, t_ in tau[k][i]+1..t)(x[k][i][t_-tau[k][i]][v] + y[k][i][t_-tau[k][i]][v]) - (if t>1 then y[i][i][t-1][v] else 0) == m[v][i][t]; forall(i in N, j in N, t in T) sum(v in V) x[i][j][t][v] <= d[t][i][j]; forall(i in N, j in N, t in T, v in V) A[v][i][j] == 0 => x[i][j][t][v] == 0 && y[i][j][t][v] == 0; // boolean变量默认0/1,此约束可省略,保留也不影响 forall(i in N, j in N, t in T, v in V) x[i][j][t][v] >= 0 && x[i][j][t][v] <= 1 && y[i][j][t][v] >= 0 && y[i][j][t][v] <= 1; }
内容的提问来源于stack exchange,提问作者tomasb21
相关产品推荐
相关产品推荐

