我正在尝试实现本书第179页上的示例9.8:link
我在C++接口(interface)上使用Cplex。
我无法正确初始化SOS2。这是我初始化SOS2的代码片段:
IloNumArray Cval(env, S);
IloNumVarArray C(env,S);
for (int s = 0; s < S; s++)
{
for (int k = 0; k < K; k++)
{
C[s] = IloNumVar(env, 0, 1);
C[s] += lamda[s][k];
}
Cval[s] = s;
}
model.add(IloSOS2(env, C, Cvals));
IloNumArray Bval(env, K);
IloNumVarArray B(env,K);
for (int k = 0; k < K; k++)
{
for (int s = 0; s < S; s++)
{
B[s] = IloNumVar(env, 0, 1);
B[k] += lamda[s][k];
}
Bval[k] = k;
}
model.add(IloSOS2(env, B, Bval));enter code here
我收到以下错误:
SOS2Test.cpp: In function ‘int main()’:
SOS2Test.cpp:74:16: error: no match for ‘operator+=’ (operand types
are ‘IloNumVar’ and ‘IloNumVar’)
sosvars[s] += lamda[s][k];
^
SOS2Test.cpp:87:16: error: no match for ‘operator+=’ (operand types
are ‘IloNumVar’ and ‘IloNumVar’)
sosvark[k] += lamda[s][k];
^
当然,如果很清楚的话。没有为该类型实现运算符'+ ='。但是,我想不出其他任何方式,而且我很确定那确实是我想要做的。
有人可以帮助我或为我指明正确的方向吗?
提前致谢!
编辑:
这是我正在尝试做的事情:
我试图近似两个变量z = f(x,y)的非线性函数。我定义了一个值(x,y)的网格以及与每个点相关的非负权重(即lamda [s] [k])。然后,如果将网格点处的(x,y)值表示为(X [s],Y [s]),则可以通过以下关系来近似该函数:
x = Sum_s Sum_k X[s] * lamda[s][k]
y = Sum_s Sum_k Y[k] * lamda[s][k]
z = Sum_s Sum_k Z[s][k] * lamda[s][k]
1 = Sum_s Sum_k Z[s][k] lamda[s][k]
哪里
s = rows
k = columns
然后,为了使用紧密相关的点,我们需要强加四个相邻的lamda [s] [k]可以为非零。这可以由以下约束来施加:
C[s] = sum_k lamda[s][k] for all s
B[k] = sum_k lamda[s][k] for all k
其中C {C_1,C_2,.. C_s}和B {B_1,B_2,.. B_k}被当作SOS2。这意味着最多两个相邻行和两个相邻列可以为非零。
我提供的代码是针对最后两个约束的,我想做的是例如将C [s](C的第s个实例)设置为等于s和k(行和柱)。换句话说,对于网格的每一行,第1行中变量的总和应进入C [1],第2行中变量的总和应进入C [2],依此类推。对于每一列,第1列中变量的总和应放入B [1]等。
因此,在CPLEX术语中。我想总结一组IloNumVars并将其设置为等于IloNumVarArray中的位置,然后将该IloNumVarArray用作SOS2
我希望这可以澄清一下。
最佳答案
我认为您需要为lamda
的每一行和每一列设置一个SOS2约束,如下所示:
for (int s = 0; s < S; s++) {
model.add(IloSOS2(env, lamda[s]));
}
IloNumVarArray B[K];
for (int k = 0; k < K; k++) {
B[k] = IloNumVarArray(env, S);
for (int s = 0; s < S; s++) {
B[k][s] = lamda[s][k];
}
model.add(IloSOS2(env, B[k]));
}
例如,使用4x4矩阵将产生LP格式的以下SOS2约束:
SOS
s1: S2 :: x_0_0 : 1 x_0_1 : 2 x_0_2 : 3 x_0_3 : 4
s2: S2 :: x_1_0 : 1 x_1_1 : 2 x_1_2 : 3 x_1_3 : 4
s3: S2 :: x_2_0 : 1 x_2_1 : 2 x_2_2 : 3 x_2_3 : 4
s4: S2 :: x_3_0 : 1 x_3_1 : 2 x_3_2 : 3 x_3_3 : 4
s5: S2 :: x_0_0 : 1 x_1_0 : 2 x_2_0 : 3 x_3_0 : 4
s6: S2 :: x_0_1 : 1 x_1_1 : 2 x_2_1 : 3 x_3_1 : 4
s7: S2 :: x_0_2 : 1 x_1_2 : 2 x_2_2 : 3 x_3_2 : 4
s8: S2 :: x_0_3 : 1 x_1_3 : 2 x_2_3 : 3 x_3_3 : 4
因此,如果“x_0_0”为非零,则“x_0_1”,“x_1_0”和“x_1_1”最多也将为非零。您会看到权重是自动生成的。