如何访问矩阵形式的所有变量的解值

how to access the solution values for all variables which are in a matrix form?

本文关键字:变量 访问矩阵      更新时间:2023-10-16

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

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

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.我该如何解决这个问题?

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]);

猜游戏时间! :-) 我只是猜测cplex_masterIloCplex型.

您有两个新初始化的二维矩阵,一个是"布尔变量",另一个是"非可变浮点数"。 您似乎想求解 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 的大小与数组 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不将IloBoolVarArray作为 varIloNumArray val,而当它很乐意将 IloIntVarArray 作为 var 和 IloNumArrayval 时。 毕竟,IloBoolVarArray继承自IloIntVarArray...它不应该可以在同一个插槽中使用吗?

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

如果你真的想使用IloBoolVarArray而不是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]);

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

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

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

IloBoolVar 的一个实例由 IloSolver 提取(记录在 ILOG 中) 求解器参考手册)作为类 IlcBoolVar 的实例(也记录了 在 ILOG 求解器参考手册中)。

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

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