在CPLEX中添加两个具有权重的目标函数

问题描述

在我的数学模型中,我有两个目标函数,根据其重要性,我想为其分配权重并将它们加在一起作为一个目标函数。 这是我的两个目标加上重量:

IloExpr objExpression(env);
for (cc = 0; cc < NumberOfCourses; cc++)
    for (ww = 0; ww < AvailableWeeks; ww++) {
        objExpression += Weight * Diff[cc][ww]; // objective a
    }

for (cc = 0; cc < NumberOfCourses; cc++) {
    objExpression += (1 - Weight) * (M[cc] * Students[cc]); // objective b
}
IloObjective theObjective(env,objExpression,IloObjective::Minimize);
mod.add(theObjective);
objExpression.end();

我将参数和变量设置如下:

const int NumberOfCourses = 15;
const int AvailableWeeks = 8;
const float Weight = 0.5;
double Students[NumberOfCourses];

IloNumVararray2 Diff(env,NumberOfCourses);
for (cc = 0; cc < NumberOfCourses; cc++)
    Diff[cc] = IloNumVararray(env,AvailableWeeks,0.0,8);

IloNumVararray M(env,NumberOfCourses);

当我运行代码时,它冻结并将断点设置在第二个目标行。 另外,如果我想有两个单独的目标并分别获得两个目标的输出,该怎么办?

解决方法

检查IloNumVarArray(env,IloInt)构造函数的参考文档。它说

此构造函数在其中创建n个数字变量的可扩展数组 环境最初,n个元素是空句柄。

换句话说,新创建的数组中的所有元素都将为NULL(请注意,这与创建所有元素都是新变量的数组的IloBoolVarArray构造函数不同)。因此,M是您所用的空句柄数组。

为了修复代码,您必须一一初始化数组的元素,或者使用初始化变量的构造函数,例如

IloNumVarArray M(env,NumberOfCourses,IloInfinity);

此外,我建议您在调试模式下编译代码,而不定义NDEBUG。如果不使用NDEBUG进行编译,那么在使用空句柄时,Concert中的许多函数都会引发异常。

如果您要有单独的目标,那么您的问题将成为多目标问题。您可能需要阅读用户手册中的相应章节,并参考CPLEX附带的ilodiet.cpp示例。