非线性约束转线性约束后CPLEX代码报错,求解决方案
CPLEX约束定义错误分析与解决方法
问题描述
将非线性表达式转换为线性约束11、12和13后,运行CPLEX代码时出现以下错误:
constraint labeling not supported for dimensions with variable size, use named constraints insteadCPLEX cannot extract expressionElement "cons12" not definedInvalid initialization expression for element "cons12"
原代码
using CPLEX; //Total nodes number. range Nodes = 1..9; //{int} Nodes = {1,2,3,4,5,6,7,8,9}; //................................................................................ //Total links number //two_directed tuple edge{ int node_out; int node_in; }; {edge} L with node_out, node_in in Nodes = {<1,3>, <3,1>, <2,3>, <3,2>, <3,4>, <4,3>, <3,5>, <5,3>, <3,6>, <6,3>, <4,5>, <5,4>, <4,6>, <6,4>, <4,8>, <8,4>, <5,6>, <6,5>, <6,7>, <7,6>, <6,9>, <9,6>}; {edge} Lout[Nodes] = [{<1,3>},//node1 {<2,3>},//node2 {<3,1>, <3,2>, <3,4>, <3,5>, <3,6>},//node3 {<4,3>, <4,5>, <4,6>, <4,8>},//node4 {<5,3>, <5,4>, <5,6>},//node5 {<6,3>, <6,4>, <6,5>, <6,7>, <6,9>},//node6 {<7,6>},//node7 {<8,4>},//node8 {<9,6>}];//node9 //Flows tuple cflow{ int origin; int destination; } {cflow} F with origin,destination in Nodes = {<1,2>, <1,3>, <1,4>, <1,5>, <1,6>, <1,7>, <1,8>, <1,9>, <2,1>, <2,3>, <2,4>, <2,5>, <2,6>, <2,7>, <2,8>, <2,9>, <3,1>, <3,2>, <3,4>, <3,5>, <3,6>, <3,7>, <3,8>, <3,9>, <4,1>, <4,2>, <4,3>, <4,5>, <4,6>, <4,7>, <4,8>, <4,9>, <5,1>, <5,2>, <5,3>, <5,4>, <5,6>, <5,7>, <5,8>, <5,9>, <6,1>, <6,2>, <6,3>, <6,4>, <6,5>, <6,7>, <6,8>, <6,9>, <7,1>, <7,2>}; float landa_f[f in F]=[0.86, 0.3, 0.75, 0.23, 0.32, 0.4, 0.5, 0.6, 0.22, 0.14, 0.23, 0.42, 0.33, 0.5, 0.62, 0.36, 0.42, 0.35, 0.2, 0.16, 0.33, 0.9, 0.41, 0.51, 0.61, 0.33, 0.42, 0.51, 0.87, 0.96, 0.31, 0.55, 0.91, 0.36, 0.32, 0.72, 0.76, 0.32, 0.45, 0.64, 0.38, 0.71, 0.43, 0.55, 0.53, 0.9, 0.58, 0.97, 0.5, 0.33 ]; {string} V = {"IDS", "DPI", "NAT", "Proxy", "Firewall"}; //MAIN DECISION VARIABLES dvar int I[v in V][n in Nodes][f in F][j in 1..2] in 0..1; //denotes that an NF instance v hosted at node n is used by the j-th service on the service chain of flow f. dvar int IL[l in L][f in F][j in 1..2][n in Nodes] in 0..1;//denotes that link l is used by flow f to route from the j-th to (j + 1)-th NF service, hosted at node nj and nj+1. dvar int Y[v in V][n in Nodes]; //Decision variables related with non linear equations dvar int z[l in L][f in F][j in 1..2][n in Nodes][v in V] in 0..1; subject to{ //convert non_linear_equations to new linear constraints forall (f in F, j in 1..2, v in V) cons11: sum( l in Lout[item(Routes[f],j-1)] ) z[l][f][j][item(Routes[f],j-1)][v] == 1; forall (f in F, j in 1..2, l in Lout[item(Routes[f],j-1)], v in V) { cons12: 3 * z[l][f][j][item(Routes[f],j-1)][v] <= ( IL[l][f][j][item(Routes[f],j-1)] + I[v][item(Routes[f],j-1)][f][j] ); cons13: z[l][f][j][item(Routes[f],j-1)][v] >= ( IL[l][f][j][item(Routes[f],j-1)] + I[v][item(Routes[f],j-1)][f][j] ) - 2; } }
错误原因分析
- 约束标签语法错误:在包含动态大小集合(如
Lout[item(Routes[f],j-1)])的forall循环中,直接使用cons11:这类标签的方式不被CPLEX支持,因为动态集合的维度无法提前确定,导致约束标签无法正确绑定。 - 未定义
Routes对象:代码中多次引用item(Routes[f],j-1),但未定义Routes集合或数组,CPLEX无法解析该表达式,导致提取失败。 - 嵌套循环中的约束标签重复定义:在嵌套
forall的代码块内定义cons12和cons13标签,OPL不允许在循环块内重复声明同名约束,引发未定义和初始化错误。
解决方法
1. 调整约束标签定义方式
要么直接移除约束标签(OPL会自动生成约束),要么使用约束数组的方式命名约束,确保维度匹配:
subject to { // 提前定义约束数组,覆盖所有循环变量维度 con cons11[F, 1..2, V]; con cons12[F, 1..2, L, V]; con cons13[F, 1..2, L, V]; forall (f in F, j in 1..2, v in V) cons11[f,j,v]: sum( l in Lout[item(Routes[f],j-1)] ) z[l][f][j][item(Routes[f],j-1)][v] == 1; forall (f in F, j in 1..2, l in Lout[item(Routes[f],j-1)], v in V) { cons12[f,j,l,v]: 3 * z[l][f][j][item(Routes[f],j-1)][v] <= ( IL[l][f][j][item(Routes[f],j-1)] + I[v][item(Routes[f],j-1)][f][j] ); cons13[f,j,l,v]: z[l][f][j][item(Routes[f],j-1)][v] >= ( IL[l][f][j][item(Routes[f],j-1)] + I[v][item(Routes[f],j-1)][f][j] ) - 2; } }
2. 补充Routes定义
必须添加Routes的定义,示例如下(根据实际业务逻辑调整):
// 示例:定义每个流对应的路径节点数组,j的范围需匹配代码中的1..2 int Routes[F][1..2] = [ // 为每个流f填充对应的路径节点,比如<1,2>流的路径节点为[1,3] [1,3], [1,3], ... // 按F集合的顺序依次填充 ];
3. 简化约束定义(无标签方式)
如果不需要命名约束,直接移除所有约束标签,OPL会自动处理:
subject to{ //convert non_linear_equations to new linear constraints forall (f in F, j in 1..2, v in V) sum( l in Lout[item(Routes[f],j-1)] ) z[l][f][j][item(Routes[f],j-1)][v] == 1; forall (f in F, j in 1..2, l in Lout[item(Routes[f],j-1)], v in V) { 3 * z[l][f][j][item(Routes[f],j-1)][v] <= ( IL[l][f][j][item(Routes[f],j-1)] + I[v][item(Routes[f],j-1)][f][j] ); z[l][f][j][item(Routes[f],j-1)][v] >= ( IL[l][f][j][item(Routes[f],j-1)] + I[v][item(Routes[f],j-1)][f][j] ) - 2; } }
内容的提问来源于stack exchange,提问作者Mahsa
相关产品推荐
相关产品推荐

