我正在尝试实现本书第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”最多也将为非零。您会看到权重是自动生成的。

09-25 22:04