如何在Cplex的.mod/.dat文件定义4维元组及读取Excel中4维MILP数据
Cplex中4维参数的定义、Excel读取与约束应用
1. .mod与.dat文件中定义4维参数的元组
.mod文件定义
首先在.mod文件中声明四个维度的索引集合,再定义包含4维索引和参数值的元组,最后声明元组集合和对应的4维参数数组:
// 定义四个维度的索引集合 {int} dim1Set = ...; {int} dim2Set = ...; {int} dim3Set = ...; {int} dim4Set = ...; // 定义4维参数的元组结构 tuple FourDimParam { int dim1; // 第一维度索引 int dim2; // 第二维度索引 int dim3; // 第三维度索引 int dim4; // 第四维度索引 float value; // 对应维度组合的参数值 } // 声明元组集合和4维参数数组 {FourDimParam} fourDimParamSet = ...; float param[dim1Set][dim2Set][dim3Set][dim4Set];
.dat文件赋值
在.dat文件中为维度集合和元组集合赋值,再通过execute块将元组数据映射到4维数组(方便模型直接调用):
// 为维度集合赋值 dim1Set = {1,2,3}; dim2Set = {1,2}; dim3Set = {1,2,3}; dim4Set = {1}; // 为4维参数元组集合赋值,格式为<dim1, dim2, dim3, dim4, value> fourDimParamSet = { <1,1,1,1, 10.5>, <1,1,2,1, 20.3>, <2,2,3,1, 15.0>, // 补充更多4维参数条目 }; // 将元组数据转换为4维数组 execute { // 先初始化数组为默认值(如0),避免未赋值的维度组合出现空值 for(var i in dim1Set) for(var j in dim2Set) for(var k in dim3Set) for(var l in dim4Set) { param[i][j][k][l] = 0; } // 遍历元组集合,为对应维度组合赋值 for(var p in fourDimParamSet) { param[p.dim1][p.dim2][p.dim3][p.dim4] = p.value; } }
2. 从Excel文件读取4维数据
利用Cplex的SheetConnection工具连接Excel文件,直接读取维度集合和4维参数数据:
// 连接目标Excel文件(替换为你的文件路径) SheetConnection excelConn("four_dim_data.xlsx"); // 从Excel读取维度集合(假设维度列表在"Dimensions"工作表的对应列) dim1Set from SheetRead(excelConn, "Dimensions!A2:A100"); // 读取第一维度索引(从第2行开始跳过表头) dim2Set from SheetRead(excelConn, "Dimensions!B2:B50"); dim3Set from SheetRead(excelConn, "Dimensions!C2:C80"); dim4Set from SheetRead(excelConn, "Dimensions!D2:D20"); // 读取4维参数数据(假设参数在"Params"工作表,列顺序为dim1、dim2、dim3、dim4、value) fourDimParamSet from SheetRead(excelConn, "Params!A2:E1000"); // 同样将元组数据转换为4维数组 execute { for(var i in dim1Set) for(var j in dim2Set) for(var k in dim3Set) for(var l in dim4Set) { param[i][j][k][l] = 0; } for(var p in fourDimParamSet) { param[p.dim1][p.dim2][p.dim3][p.dim4] = p.value; } }
注意:Excel文件中"Params"工作表需保持列顺序与元组结构一致,即A列存dim1、B列存dim2、C列存dim3、D列存dim4、E列存参数值,表头放在第一行,数据从第二行开始。
3. 参数定义方式与约束中的应用
参数定义方式
有两种常用方式:
- 元组集合:适合存储稀疏的4维数据(即不是所有维度组合都有值),节省存储空间。
- 4维数组:适合存储密集型数据,模型中调用更直接,无需额外条件判断。
约束中的应用示例
假设已定义4维决策变量x[dim1Set][dim2Set][dim3Set][dim4Set],以下是两种参数方式的约束写法:
用4维数组写约束
dvar float+ x[dim1Set][dim2Set][dim3Set][dim4Set]; // 非负决策变量 subject to { // 示例约束:对每个dim1和dim2,所有dim3、dim4对应的参数乘变量之和不超过100 forall(i in dim1Set, j in dim2Set) { sum(k in dim3Set, l in dim4Set) param[i][j][k][l] * x[i][j][k][l] <= 100; } }
用元组集合写约束
dvar float+ x[dim1Set][dim2Set][dim3Set][dim4Set]; subject to { // 筛选出对应dim1和dim2的元组,计算参数乘变量之和 forall(i in dim1Set, j in dim2Set) { sum(p in fourDimParamSet: p.dim1 == i && p.dim2 == j) p.value * x[p.dim1][p.dim2][p.dim3][p.dim4] <= 100; } }
内容的提问来源于stack exchange,提问作者H Bagheri
相关产品推荐
相关产品推荐

