Multi Objective Function
AnsweredHi,
I am tryring to solve a multi objective function problem. This is code for setting up the objective function:
# set objective function
Obj1 = (gp.quicksum((t_g[p,i,j]*y_kg[p,i,j,k] + t_a[p,i,j]*y_ka[p,i,j,k]) for p in P for i in I for j in J for k in K ), GRB.MINIMIZE)
Obj2 = (gp.quicksum(u_d[p,j,k] for p in P for j in J for k in K),GRB.MINIMIZE)
m.setObjectiveN(Obj1, index = 0, priority = 1, name = "Obj1")
m.setObjectiveN(Obj2, index = 1, priority = 2, name = "Obj2")
There seem to be no syntax error but python is throwing this error for using the setObjectiveN function : GurobiError: Unable to convert argument to an expression.
Can you please let me know why is this error occurring ?
-
Hi,
The error occurs because the setObjectiveN method does not accept tuples as its first argument. You should try
# set objective function
Obj1 = gp.quicksum((t_g[p,i,j]*y_kg[p,i,j,k] + t_a[p,i,j]*y_ka[p,i,j,k]) for p in P for i in I for j in J for k in K )
Obj2 = gp.quicksum(u_d[p,j,k] for p in P for j in J for k in K)
m.setObjectiveN(Obj1, index = 0, priority = 1, name = "Obj1")
m.setObjectiveN(Obj2, index = 1, priority = 2, name = "Obj2")Please note that each objective is minimized by default in a multi-objective situation. If you want to maximize one of the objectives, then you have to provide a negative weight to the particular objective, cf., 6th paragraph of Specifying Multiple Objectives.
Best regards,
Jaromił0 -
Hi Jaromil,
Thank you for response. With the above changes my code is working fine. I wanted to solve this bi-objective function with a hierarchical or lexicographic approach and I had the following questions.
1.) I wanted to understand what is the difference between weight and priority in an objective function . How does both of it make a difference in finding the optimal solution?
2.) This is the solution my python code gives me currently. How can I know all the solution which Gurobi has to offer. It says there are 10 solution counts (highlighted in black). How can I see all of it ?
Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (win64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 667 rows, 461 columns and 2200 nonzeros
Model fingerprint: 0x111a7f81
Variable types: 54 continuous, 407 integer (182 binary)
Coefficient statistics:
Matrix range [2e-03, 1e+07]
Objective range [1e+00, 1e+02]
Bounds range [1e+00, 1e+00]
RHS range [1e-01, 8e+07]
---------------------------------------------------------------------------
Multi-objectives: starting optimization with 2 objectives ...
---------------------------------------------------------------------------
Multi-objectives: applying initial presolve ...
---------------------------------------------------------------------------
Presolve removed 98 rows and 45 columns
Presolve time: 0.02s
Presolved: 569 rows and 416 columns
---------------------------------------------------------------------------
Multi-objectives: optimize objective 1 (Obj1) ...
---------------------------------------------------------------------------
Found heuristic solution: objective 3610.0000000
Presolve removed 180 rows and 47 columns
Presolve time: 0.00s
Presolved: 389 rows, 369 columns, 1314 nonzeros
Variable types: 8 continuous, 361 integer (135 binary)
Root relaxation: objective 1.860613e+03, 381 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 1860.61298 0 132 3610.00000 1860.61298 48.5% - 0s
H 0 0 3000.0000000 1860.61298 38.0% - 0s
H 0 0 2880.0000000 1860.61298 35.4% - 0s
0 0 2439.45705 0 109 2880.00000 2439.45705 15.3% - 0s
H 0 0 2750.0000000 2439.45705 11.3% - 0s
0 0 2564.66789 0 55 2750.00000 2564.66789 6.74% - 0s
0 0 2568.40301 0 59 2750.00000 2568.40301 6.60% - 0s
H 0 0 2730.0000000 2612.22222 4.31% - 0s
0 0 2612.22222 0 23 2730.00000 2612.22222 4.31% - 0s
H 0 0 2690.0000000 2626.28205 2.37% - 0s
0 0 2626.28205 0 35 2690.00000 2626.28205 2.37% - 0s
0 0 2626.28205 0 43 2690.00000 2626.28205 2.37% - 0s
0 0 2626.28205 0 42 2690.00000 2626.28205 2.37% - 0s
0 0 2626.28205 0 30 2690.00000 2626.28205 2.37% - 0s
0 0 2626.28205 0 32 2690.00000 2626.28205 2.37% - 0s
0 0 2626.28205 0 36 2690.00000 2626.28205 2.37% - 0s
0 0 2626.28205 0 27 2690.00000 2626.28205 2.37% - 0s
H 0 0 2650.0000000 2626.28205 0.90% - 0s
0 0 2626.28205 0 19 2650.00000 2626.28205 0.90% - 0s
0 0 2626.28205 0 19 2650.00000 2626.28205 0.90% - 0s
0 0 2626.28205 0 19 2650.00000 2626.28205 0.90% - 0s
0 0 2626.28205 0 27 2650.00000 2626.28205 0.90% - 0s
0 0 2626.40351 0 24 2650.00000 2626.40351 0.89% - 0s
0 0 2630.72917 0 23 2650.00000 2630.72917 0.73% - 0s
Cutting planes:
Gomory: 1
MIR: 19
Flow cover: 13
RLT: 1
Relax-and-lift: 2
Explored 1 nodes (988 simplex iterations) in 0.23 seconds (0.05 work units)
Thread count was 8 (of 8 available processors)
Solution count 7: 2650 2690 2730 ... 3610
Optimal solution found (tolerance 1.00e-04)
Best objective 2.650000000000e+03, best bound 2.650000000000e+03, gap 0.0000%
---------------------------------------------------------------------------
Multi-objectives: optimize objective 2 (Obj2) ...
---------------------------------------------------------------------------
Loaded user MIP start with objective 5019
Presolve removed 180 rows and 47 columns
Presolve time: 0.00s
Presolved: 390 rows, 369 columns, 1449 nonzeros
Variable types: 8 continuous, 361 integer (135 binary)
Found heuristic solution: objective 4911.0000000
Root relaxation: objective 1.432000e+03, 271 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 1432.00000 0 81 4911.00000 1432.00000 70.8% - 0s
H 0 0 4854.0000000 1432.00000 70.5% - 0s
H 0 0 4779.0000000 1432.00000 70.0% - 0s
H 0 0 4723.0000000 1432.00000 69.7% - 0s
0 0 1432.00000 0 137 4723.00000 1432.00000 69.7% - 0s
H 0 0 4685.0000000 1432.00000 69.4% - 0s
0 0 1432.00000 0 106 4685.00000 1432.00000 69.4% - 0s
H 0 0 4302.0000000 1432.00000 66.7% - 0s
H 0 0 4152.0000000 1432.00000 65.5% - 0s
0 0 1432.00000 0 53 4152.00000 1432.00000 65.5% - 0s
H 0 0 4121.0000000 1432.00000 65.3% - 0s
H 0 0 4065.0000000 1432.00000 64.8% - 0s
0 0 1432.00000 0 51 4065.00000 1432.00000 64.8% - 0s
0 0 1432.00000 0 64 4065.00000 1432.00000 64.8% - 0s
H 0 0 4044.0000000 1432.00000 64.6% - 0s
H 0 0 3992.0000000 1432.00000 64.1% - 0s
0 0 1432.00000 0 79 3992.00000 1432.00000 64.1% - 0s
0 0 1432.00000 0 54 3992.00000 1432.00000 64.1% - 0s
0 0 1432.00000 0 54 3992.00000 1432.00000 64.1% - 0s
H 0 0 3812.0000000 1432.00000 62.4% - 0s
0 2 1432.00000 0 46 3812.00000 1432.00000 62.4% - 0s
H 31 60 3785.0000000 1432.00000 62.2% 64.6 0s
H 190 198 3678.0000000 1432.00000 61.1% 22.6 0s
H 305 314 3637.0000000 1432.00000 60.6% 22.8 0s
H 528 573 3633.0000000 1432.00000 60.6% 25.6 0s
H 681 709 3603.0000000 1432.00000 60.3% 27.1 0s
H 859 819 3591.0000000 1432.00000 60.1% 28.1 0s
7503 1628 infeasible 40 3591.00000 1432.00000 60.1% 49.4 5s
15318 2594 2121.34406 35 111 3591.00000 1432.00000 60.1% 53.2 10s
28354 4674 cutoff 45 3591.00000 1456.00000 59.5% 56.6 15s
Cutting planes:
Gomory: 21
Cover: 1
Projected implied bound: 23
Clique: 11
MIR: 32
StrongCG: 1
Flow cover: 30
Zero half: 2
Relax-and-lift: 6
Explored 30579 nodes (1753434 simplex iterations) in 18.02 seconds (9.17 work units)
Thread count was 8 (of 8 available processors)
Solution count 10: 3591 3603 3633 ... 4065
Optimal solution found (tolerance 1.00e-04)
Best objective 3.591000000000e+03, best bound 3.591000000000e+03, gap 0.0000%-1 -
I had one more generic question. How do you paste the code in python code format? I am unable to paste a in a correct code format .
Thanks in advance!
0 -
I wanted to understand what is the difference between weight and priority in an objective function . How does both of it make a difference in finding the optimal solution?
The weight and priority properties are used to define whether Gurobi should use a blending or a hierarchical approach when solving a multi objective model. You can find all detail in the documentation section Working With Multiple Objectives.
This is the solution my python code gives me currently. How can I know all the solution which Gurobi has to offer. It says there are 10 solution counts (highlighted in black). How can I see all of it ?
All solutions are stored in a so-called Solution Pool. You can find all details how to define and access Solution Pools together with examples in the documentation of the Solution Pool.
I had one more generic question. How do you paste the code in python code format? I am unable to paste a in a correct code format .
You can add a "Code Block" into your post and the HTML script should recognize the Python format once the comment is posted. Please note that it is not 100% bullet proof, thus there certainly are cases where the language recognition does not work.
Best regards,
Jaromił0 -
Hi Jaromil,
Thank you so much for all the clarifications!
Thanks,
Purnima
0 -
Hi Jaromil,
I had a question regarding a bi objective problem that I am solving. I have two objectives: objective 1 minimizes total travel time and objective 2 minimizes total unmet demand. I am using the reltol on objective 1 and allowing to objective 2 to degrade the value by giving a specified relative amount. I am setting the reltol values as 1%,2%,3%,4% and 5% to set the amount for relative degradation. Since the dataset for my problem is very large, I do not want to exhaustively find all optimal solution. I am only interested in finding the Pareto Frontier, for which I am finding using Reltol.
My question was - Are all these value given by Gurobi, the non-dominant solutions for this bi-objective function? When I plot the values in a scatter plot, it does form an inverse relationship graph( as shown in the below image) so it does look like a pareto frontier for this optimization.
Thanks,
Purnima
0 -
I also wanted to added that I am solving the bi objective problem by hierarchical lexicographic method. The priority of objective 1 is 2 and the priority of objective 2 is 1. Here is the piece of code for your reference :
m.setObjectiveN(Obj1, index = 0, priority = 2, name = "Obj1", reltol = 0.01)
m.setObjectiveN(Obj2, index = 1, priority = 1, name = "Obj2")0 -
Hi Purnima,
Are all these value given by Gurobi, the non-dominant solutions for this bi-objective function?
Yes, up to the MIPGap tolerance. Gurobi first minimizes objective 1 and then objective 2 while allowing to degrade objective 1 by at most reltol. Thus, the value for objective 2 and the possibly degraded objective 1 value provide a non-dominant solution. This solution is only non-dominant up to the MIPGap value, because each objective is solved up to the MIPGap meaning that theoretically there might be a solution present which is still slightly better.
Best regards,
Jaromił0
Please sign in to leave a comment.
Comments
8 comments