1

(注意:这个问题与IBM 的 ILOG CPLEX C++ API、2007 年前后通过 HTTP 的 pdf 格式的文档有关,以及可通过 IBM 的 FTP获得的“版本 12”的当前材料)

我有一个矩阵变量,我想将它们的值传递给矩阵参数。这就是我所做的:

typedef IloArray<IloNumArray> NumMatrix;
typedef IloArray<IloBoolVarArray> BoolVarMatrix;

NumMatrix ystar(env,I);
for(IloInt i = 0; i < I; i++){
    ystar[i] = IloNumArray(env, T);
}

BoolVarMatrix y(env,I);
for(IloInt i = 0; i < I; i++){
    y[i] = IloBoolVarArray(env, T);
}

for(IloInt i = 0; i < I; i++)
    cplex_master.getValues(ystar[i],y[i]);

但显然getValues()只适用于IloNumVarArray. 我怎样才能解决这个问题?

4

2 回答 2

1

猜猜比赛时间!:-) 我只是猜测那cplex_master是 type IloCplex

您有两个新初始化的二维矩阵,一个是“布尔变量”,另一个是“非可变浮点数”。看起来您想要求解中的布尔变量y并将结果表示为 中的浮点数ystar

  1. 我不确定将空白矩阵相互解决会完成什么,所以我会假装它们在您的实际代码中不是空白的

  2. 我不知道您的方案是将布尔矩阵逐行转换为浮点数,但也许这在某种程度上是合法的

无论如何,IloCplex提供了四个变体getValues(),所有这些变体似乎都在它命名为varval的两个参数上运行:

public void getValues(const IloIntVarArray var, IloNumArray val) const
public void getValues(IloNumArray val, const IloIntVarArray var) const
public void getValues(const IloNumVarArray var, IloNumArray val) const
public void getValues(IloNumArray val, const IloNumVarArray var) const

他们都有类似的文档,其效果是:

此方法将数组 var 指定的整数变量的解值放入数组 val 中。数组 val 被调整为与数组 var 相同的大小,并且 val[i] 将包含变量 var[i] 的解值。

有一个不寻常的设计选择,因为val正在被修改,尽管它是按值传递的。这是非常非 C++ 风格的。例如,如果您正在处理整数,并编写如下代码:

void myCopy(const int source, int destination) {
    /* what could go here? */
}

void someFunction() {
   int a = 10;
   int b;
   myCopy(a, b);
}

...无法myCopy()使用该原型编写例程。目的地是按值传递的,因此myCopy()无法返回并更改b调用者中的值。正确的 C++ 将通过使用指针或引用(通过&)来做到这一点:

void myCopy(const int source, int& destination) {
    destination = source;
}

所以这个 CPLEX C++ 事情在后台使用了某种技巧,我假设通过那个神秘的env参数......以另一种方式做事。当人们编写奇怪的语言包装器并且不知道习语时,它会遭受典型情况的困扰。另一个帖子在这里非常重要:

只是我还是 Cplex Concert API 可以使用一些改进?

您的问题可能是为什么IloCplex不将IloBoolVarArraya 作为varIloNumArray valIloIntVarArray ,而将 a作为varIloNumArray val会很高兴。毕竟IloBoolVarArray继承自IloIntVarArray……不应该可以在同一个slot中使用吗?

但是该方法的这些按值传递语义getValue()抑制了本来可以起作用的自然继承。通过指针或引用传递时,您只能传递派生类来代替基类。所以不要继续这个。

如果您真的想使用 anIloBoolVarArray而不是 an IloIntVarArray,那么我猜您必须经过一个中间环节:

typedef IloArray<IloNumArray> NumMatrix;
typedef IloArray<IloBoolVarArray> BoolVarMatrix;
typedef IloArray<IloIntVarArray> IntVarMatrix;

NumMatrix ystar(env,I);
for(IloInt i = 0; i < I; i++){
    ystar[i] = IloNumArray(env, T);
}

BoolVarMatrix y(env,I);
for(IloInt i = 0; i < I; i++){
    y[i] = IloBoolVarArray(env, T);
}

IntVarMatrix yint(env,I);
for(IloInt i = 0; i < I; i++){
    for(IloInt t = 0; t < T; t++) {
        yint[i][t] = y[i][t];
    }
}

for(IloInt i = 0; i < I; i++)
    cplex_master.getValues(ystar[i],yint[i]);

真正的问题可能是使用IloBoolvs.IloInt是否真的值得。这看起来像是事后的想法:

此类型定义表示 Concert Technology 中的布尔值。这些值是 IloTrue 和 IloFalse。事实上,布尔值是 IloInt 类型的整数。IloFalse 为 0(零),IloTrue 为 1(一)。此类型预期为标准 C++ 建议的内置 bool 类型。通过使用这种类型,您可以确保应用程序的 Concert Technology 组件将在这方面进行移植,而无需跨不同硬件平台更改源代码。

数组似乎在求解器中没有一流的处理,但单个变量可以:

IloBoolVar 的实例由 IloSolver 提取(在 ILOG Solver Reference Manual 中记录)作为 IlcBoolVar 类的实例(也在 ILOG Solver Reference Manual 中记录)。

IloBoolVar 的一个实例由 IloCplex 提取(记录在 ILOG CPLEX 参考手册中)作为表示 Bool 类型的数值变量的列,其边界由 IloBoolVar 指定

我想完全避免它是最好的答案。

于 2012-04-26T00:19:53.997 回答
1

IloCplex::getValue 可用于任何 IloNumVar。返回值只是一个双精度值,因此您不受 Concert 数据结构的限制。表达式 y[i][t] 为您提供 IloNumVar。

   for(IloInt i = 0; i < I; i++)
        for (IloInt t = 0; t < T; ++t)
        ystar[i][t] = cplex_master.getValue(y[i][t]);
于 2012-04-26T03:20:37.837 回答