1
votes

I am optimizing a bi-objective problem using IBM CPLEX v12. CPLEX has a property to blend two objective functions when they are given same priority. The blended objective is then solved based on the weights that are set for the two objectives initially.

I provide some initial weights, however, i want to update them during the optimization process based on the found incumbent values and bounds for the two objectives. I am using callbacks provided by CPLEX for this. My problem is that i am able extract the weights that were initally set and display them. I use the getWeight() function of IloObjective. But, I do not know how to update the weights as i could not find any similar setWeight() function.

The callback implementation looks as follows:

class weightUpdateCallack: public IloCplex::Callback::Function
{
public:
    // Constructor with data
    weightUpdateCallack(IloCplex cplex) : obj(cplex.getEnv())
    {
        obj = cplex.getObjective();
    }

    void updateWeights(const IloCplex::Callback::Context& context)
    {
        qDebug() << "-----------------Callback--------------";
        qDebug() << "Name: " << obj.getName();
        qDebug() << "weight 1: " << obj.getWeight(1);
        qDebug() << "constant: " << obj.getConst();
    }

    virtual void invoke (const IloCplex::Callback::Context& context);

private:
    IloObjective obj;
};

void weightUpdateCallack::invoke(const IloCplex::Callback::Context &context)
{
    if(context.inCandidate())
        updateWeights(context);
}

The callback is invoked when a candidate solution is found, as follows:

// Use a callback function to update weights
weightUpdateCallack weightsUpdate(cplex);
cplex.use(&weightsUpdate, IloCplex::Callback::Context::Id::Candidate);

I use the IloStaticLex function to pass the bi-objective expression array along with arrays for weights and tolerances.

1

1 Answers

0
votes

It's not a coincidence that you did not figure out how to do this. As of CPLEX 12.9, updating the weights of the objectives in a multiobjective model during a solve is not supported. Furthermore, with the object-oriented APIs (i.e., C++, Java, .NET), it is not possible to modify one of the objectives after they have been created. In order to change the attributes of a multiobjective model in those APIs, you'll need to first remove the original objective, and then add a new multiobjective definition (using IloStaticLex as you did before).

See the section on Generic Callbacks in the CPLEX User's Manual to read about everything that is possible with this functionality.