How to use PWL and MultiObjectives together
AnsweredHi,
I'm using gurobipy and I want to model two optimization steps. In the first step I just have a linear objective and in the second step I want to use some piecewise linear objectives.
Is there any way I can use setPWLObj() and setObjectiveN() together? I don't know how to set the priority on PWL objectives.
Related question: Is there a way I can remove PWL objectives after I added them? The remove() function does not seem to support this (according to the docs).
Thanks in advance!
Hans

Hi Hans,
There is no way to use piecewise linear objectives with setObjectiveN(). However, you can add piecewise linear constraints (see here), and then set the multiple objectives to be the variables representing the "y" values of those piecewise linear functions.
To clear a piecewise linear objective, you can set the variable's Obj attribute to 0 (x.Obj = 0). Don't forget to update the model afterwards if you want to immediately verify that the piecewise linear objective was removed (e.g., with model.getPWLObj(x)).
I hope this helps. Thanks!
1 
Thanks for quick answer!
Ok, I've tried to replace setPWLObj with a custom implementation based on the article you suggested. So I'm mapping all the "x"values to "y"values with lambdavariables and SOS2constraints. Then, I'm summing up the "y"values for the linear objective. This should be mathematically the same thing. Unfortunately, there seems to be a significant performance difference between the two in practice.
I ran the same model twice for 30 minutes, once with the builtin PWL and once with my custom PWL implementation:
 setPWLObj: Objective went down from 3627 to 2921 (difference = 706)
 custom PWL: Objective went down from 3627 to 3623 (difference = 4)
So, I guess Gurobi does something special with PWL internally?!
For my second question: To reset the Objective and remove PWL objectives on all variables I can do the following?
m.setObjective(0, GRB.MINIMIZE)
0 
Hi Hans,
Are any of the piecewise linear functions convex (assuming you're minimizing)? If so, you can instead use a more efficient linear formulation to model the piecewise linear function. This is done by adding constraints that y lies in each of the n1 halfspaces that together define the epigraph of the piecewise linear function. In other words, if you have n points defining the convex piecewise linear function, the reformulation includes n1 inequalities of the form y >= ax + b, where y = ax + b coincides with one of the line segments of the piecewise linear function. Then, you minimize y in the objective function.
For your second question  to reset the model objective and remove all piecewise linear functions from the variables, you can do the following:
# Remove PWL objectives from variables
for v in m.getVars():
if len(m.getPWLObj(v)) > 0:
v.Obj = 0
# Reset model objective
m.setObjective(0, GRB.MINIMIZE)Thanks!
Eli
1 
Yes, I'm minimizing and they are always convex! I implemented this and it performs great, even a bit better than setPWLObj. I ran model again for 30 minutes and the objective went down from 3897 to 3125 (difference: 772). It's a bit strange that there seems to be an offset now but that's probably a bug in my implementation. Nevertheless, a big thanks for that! When thinking about the Simplex, it's also clear to me why this is the better implementation.
Resetting the PWLs with your code works great as well.
0 
I found my mistake: My piecewiselinear function was actually not convex (although just very slightly). Because of that the objective values were a bit off.
That means that setPWLObj() can work with nonconvex functions but is still as fast as the implementation based on the epigraph (which only works for convex functions).
0
Please sign in to leave a comment.
Comments
5 comments