OPL代码报错:名称'tavail'不存在,求排查与解决方法
OPL代码报错“名称'tavail'不存在”的排查与解决
错误信息
| 描述 | 资源 | 路径 | 位置 | 类型 |
|---|---|---|---|---|
| 名称"tavail"不存在。 | soclevel.mod | /socvariation | 12:10-16 | OPL大纲问题标记 |
对应的OPL代码
int t=24; int n=20; range t=1..tavail; range number =1..n; float soc[1][number]=[0.6,0.3,0.2,0.7,0.8,0.9,0.3,0.6,0.5,0.9,0.5]; //预测负载(时段0..4) float pl[tavail]=[10000000,7000000,9000000,6000000,12000000,6000000,4000000,15000000,9000000,12000000,6000000,8000000,10000000,7000000,9000000,6000000,12000000,6000000,4000000,15000000,9000000,12000000,6000000,8000000]; //目标负载(时段0..11) float pt[tavail]=[10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000]; //母线电压(时段0..11) float v[tavail]=[240,232,229,233,230,235,228,234,227,229,231,230,226,232,233,230,236,233,231,232,232,233,233,230]; //目标母线电压(时段0..11) float vt[tavail]=[230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230]; //决策变量:电动汽车充电功率 dvar float pevch[tavail][number] in 0..100000; //决策变量:电动汽车放电功率 dvar float pevdis[tavail][number] in 0..100000; dvar float soc[tavail][number] in 0..100000; //目标函数 minimize sum(i in tavail)((pt[i]-pl[i])+sum(j in number)-pevch[i][j]+sum(j in number)pevdis[i][j]); subject to forall(i in tavail,j in number) if(pt[i]-pl[i]<0 && 0.7<soc[j][i]<0.9&& v[i]<vt[i]) pevdis[i][j]==soc[j][i]*100000; soc[j][i+1]==0.8*soc[j][i];} else {pevdis[i][j]==0 ; soc[j][i+1]==soc[j][i];} forall(i in tavail,j in number) if(pt[i]-pl[i]>0 && 0.3<= soc[j][i]<=0.7 && v[i]>vt[i]) {pevch[i][j]==soc[j][i]*800000; soc[j][i+1]==1.1*soc[j][i];} else {pevch[i][j]==0; soc[i][j]==soc[i][j];} }
报错原因
- 未定义
tavail变量:代码开头仅定义了int t=24;,但后续所有引用tavail的位置都没有提前声明该变量,OPL无法识别未定义的标识符。 - 范围定义冲突:第三行
range t=1..tavail;重复使用了已作为整数变量定义的t,同时还引用了未定义的tavail,属于双重错误。
解决方法
步骤1:定义tavail变量
把开头的int t=24;修改为int tavail=24;,或者保留t的同时新增一行int tavail=t;,确保tavail有明确的数值定义。
步骤2:修正范围定义
第三行的range t=1..tavail;需要修改变量名,避免和整数变量t冲突,建议改成有意义的名称,比如range time =1..tavail;,后续所有用到时段范围的地方统一使用这个新名称。
步骤3:全局修正引用
将代码中所有使用tavail作为范围的地方(数组下标、循环变量范围)替换为修正后的range名称(比如time),确保所有范围引用合法。
修正后的代码示例
int tavail=24; int n=20; range time =1..tavail; range number =1..n; float init_soc[number]=[0.6,0.3,0.2,0.7,0.8,0.9,0.3,0.6,0.5,0.9,0.5]; //预测负载 float pl[time]=[10000000,7000000,9000000,6000000,12000000,6000000,4000000,15000000,9000000,12000000,6000000,8000000,10000000,7000000,9000000,6000000,12000000,6000000,4000000,15000000,9000000,12000000,6000000,8000000]; //目标负载 float pt[time]=[10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000,10000000]; //母线电压 float v[time]=[240,232,229,233,230,235,228,234,227,229,231,230,226,232,233,230,236,233,231,232,232,233,233,230]; //目标母线电压 float vt[time]=[230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230]; //决策变量:电动汽车充电功率 dvar float pevch[time][number] in 0..100000; //决策变量:电动汽车放电功率 dvar float pevdis[time][number] in 0..100000; dvar float soc[time][number] in 0..1; // SOC通常为0-1的比例,修正范围 //目标函数 minimize sum(i in time)((pt[i]-pl[i]) + sum(j in number)(pevdis[i][j] - pevch[i][j])); subject to // 初始SOC约束 forall(j in number) soc[1][j] == init_soc[j]; forall(i in time, j in number) if(i < tavail) { // 避免i+1超出范围 if(pt[i]-pl[i]<0 && 0.7<soc[i][j]<0.9 && v[i]<vt[i]) { pevdis[i][j] == soc[i][j]*100000; soc[i+1][j] == 0.8*soc[i][j]; } else { pevdis[i][j] == 0; soc[i+1][j] == soc[i][j]; } if(pt[i]-pl[i]>0 && 0.3<= soc[i][j]<=0.7 && v[i]>vt[i]) { pevch[i][j] == soc[i][j]*800000; soc[i+1][j] == 1.1*soc[i][j]; } else { pevch[i][j] == 0; } }
注:修正后的代码还修复了原代码中的其他问题,比如SOC数组重定义、数组下标顺序错误、循环越界、目标函数语法错误等,确保代码能正常运行。
内容的提问来源于stack exchange,提问作者Haripriya M R
相关产品推荐
相关产品推荐

