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.