Deleting and removing modeling objects

Describes the effects of deleting modeling objects in the C++ API.

A special type of modification is that of deleting a modeling object by calling its end method. Consider, for example, the deletion of a variable. What happens if the variable you delete has been used in constraints or in the objective function, or has been extracted to CPLEX? If you call its end method, Concert Technology carefully removes the deleted variable from all other modeling objects and algorithms that may keep a reference to the variable in question. This convention applies to any modeling object to be removed. However, user-defined handles to the removed variable are not managed by Concert Technology. Instead, it is up to the user to make sure that these handles are not used after the deletion of the modeling object. The only operation allowed then is the assignment operator.

Concert Technology also provides a way to remove a modeling object from all other modeling objects and algorithms exactly the same way as when deleting it, yet without deleting the modeling object: call the method IloExtractable::removeFromAll. This method may be helpful to temporarily remove a variable (or even an array of objects) from your model while keeping the option to add it back later.

Tip: The method removeFromAll is inherited by classes derived from the class IloExtractable, such classes as IloObjective, IloConstraint, or IloModel and others.

It is important to understand the difference between calling end and calling model.remove(obj) for an object obj. In the case of a call to remove, obj is not necessarily removed from the problem that CPLEX maintains. Whether or not anything appears to happen depends on whether the removed object is referenced by yet another extracted modeling object. For example, when you add a modeling object, such as a ranged constraint, to a model, all the variables used by that modeling object implicitly become part of the model as well. However, when you remove that modeling object (for example, that ranged constraint), those variables are not implicitly removed because they may be referenced by other elements (such as the objective function or a basis, for example). In other words, model.add(rngct) followed later by model.remove(rngct) does not leave the model unchanged: the model still contains the variables in rngct, even if they do not actually appear in other constraints. CPLEX does not check whether they appear in other constraints or not when it applies remove. For that reason, variables can be explicitly removed from a model only by a call to its end member function.

Usually when a constraint is removed from the extracted model, the constraint is also removed from CPLEX as well, unless it was added to the model more than once.

Consider the case where a variable is removed from CPLEX after one of the end or remove operations. If the cplex object contains a simplex basis, by default the status for that variable is removed from the basis as well. If the variable happens to be basic, the operation corrupts the basis. If this is not what you want, CPLEX provides a delete mode that first pivots the variable out of the basis before removing it. The resulting basis is not guaranteed to be feasible or optimal, but it will still constitute a valid basis. To select this mode, call the method:

setDeleteMode(IloCplex::FixBasis);

Similarly, when removing a constraint with the FixBasis delete mode, CPLEX will pivot the corresponding slack or artificial variable into the basis before removing it, to make sure of maintaining a valid basis. In either case, if no valid basis was available in the first place, no pivot operation is performed. To set the delete mode back to its default setting, call:

setDeleteMode (IloCplex::LeaveBasis);