如何将Excel中存储的4维数组数据转换为OPL CPLEX可读取格式
CPLEX 读取 Excel 四维数组操作方案
你遇到的IBM ILOG Concert: excel: range size is not the size of tupleSet.报错,核心原因是Excel读取区域的总单元格数、维度映射顺序,和你OPL中定义的四维数组不匹配。你的数组总元素数为1*20*40*100=80000,只要保证读取区域总单元格数和该值一致、维度顺序对应即可解决问题。
操作步骤
1. 整理Excel端数据
因为rangeA只有1个取值,可以直接把第一维压平,数据按维度优先级从高到低排序:rangeB → rangeC → rangeD,所有数据存储为单列80000行或者单行80000列即可,优先用单列存储不容易出错。
示例排序逻辑:
- 第1-100行:对应rangeB=1、rangeC=1的全部rangeD取值
- 第101-200行:对应rangeB=1、rangeC=2的全部rangeD取值
- 按规则依次填充,直到填满全部80000行
2. 配置OPL端映射规则
首先确认.mod文件中的维度定义正确:
range rangeA = 1..1; range rangeB = 1..20; range rangeC = 1..40; range rangeD = 1..100; float Array4D[rangeA][rangeB][rangeC][rangeD];
之后在.dat文件中配置Excel连接和读取规则即可:
SheetConnection sheet("替换为你的Excel文件实际路径.xlsx"); Array4D from SheetRead(sheet, "替换为你的工作表名!A1:A80000");
如果你的数据是按单行存储,把读取区域改为对应1行80000列的范围即可,总单元格数匹配就行。
分Sheet存储的适配方案
如果你需要按rangeB或者rangeC分Sheet存储数据,可以先定义中间低维数组分别读取,再赋值给四维数组,示例逻辑如下:.mod文件新增中间变量:
float temp[rangeB][rangeC][rangeD];
.dat文件按Sheet循环读取:
SheetConnection sheet("替换为你的Excel文件实际路径.xlsx"); for(b in rangeB) { // 每个rangeB对应一个Sheet,每个Sheet存40行100列的rangeC、rangeD二维数据 temp[b] from SheetRead(sheet, "Sheet" + b + "!A1:CV40"); }
通过执行块给四维数组赋值:
execute { for(var b=1; b<=20; b++) { for(var c=1; c<=40; c++) { for(var d=1; d<=100; d++) { Array4D[1][b][c][d] = temp[b][c][d]; } } } }
排错注意事项
- 提前手动核算数组总元素数,和Excel读取区域的单元格数做校验,必须完全相等
- Excel数据的存储顺序要和OPL数组的维度顺序严格对应,不要写反维度
- 数据区域不要留空单元格、非数值内容,否则也会触发大小不匹配报错
内容的提问来源于stack exchange,提问作者Prateek
相关产品推荐
相关产品推荐

