How to use PWL and Multi-Objectives together
回答済みHi,
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
-
正式なコメント
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
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 lambda-variables and SOS2-constraints. 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 built-in 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 n-1 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 n-1 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 piecewise-linear 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 non-convex functions but is still as fast as the implementation based on the epigraph (which only works for convex functions).
0
投稿コメントは受け付けていません。
コメント
6件のコメント