Hi everyone,
I have started to use BilevelJuMP and I’m really beginning to enjoy its flexibility!
I’m trying to solve a larger scale calibration problem, where the lower level is a QP with affine (in-)equality constraints, and the top-level tries to minimize the squared euclidean distance between some lower level variables and their target values. The problem is fairly complicated to solve at full size, which is why I wanted to use the following approach to ProductMode():
Since the lower level is quick to solve, run it as a separate baseline model with fixed upper level parameters and use primal/dual values as a starting point for the bilevel model.
To set the primal lower variables of the bilevel problem “GGM_calibrator” to the baseline results of “GGM_Baseline”, I used the following code:
for var in all_variables(GGM_Baseline)
set_start_value(variable_by_name(GGM_calibrator, name(var)), value(variable_by_name(GGM_Baseline, name(var)) ) )
end
In addition, I set the upper level variable start to their fixed value of the baseline run, they are not further restricted by any additional constraints.
This seems to work fine, the objective value at this starting point is approximately as expected (according to the Ipopt log).
However, setting duals of the lower level does not seem to have the desired effect, as there still is a significant primal infeasibility for the single level ProductMode() reformulation:
for (F, S) in list_of_constraint_types(GGM_Baseline)
if F != VariableRef && S == MOI.EqualTo{Float64}
for ctr in all_constraints(GGM_Baseline, F, S)
set_dual_start_value(constraint_by_name(GGM_calibrator, name(ctr)), dual(constraint_by_name(GGM_Baseline, name(ctr)) ) )
end
elseif F != VariableRef && S == MOI.LessThan{Float64}
for ctr in all_constraints(GGM_Baseline, F, S)
set_dual_start_value(constraint_by_name(GGM_calibrator, name(ctr)), dual(constraint_by_name(GGM_Baseline, name(ctr)) ) )
end
end
end
The reason for separating equalities from inequalities is to be able to manipulate them individually.
Checking the dual starts using dual_start_value() shows, that the code above seems to do the job as well.
However, Ipopt seems to indicate that the ProductMode() reformulation starting point is still not feasible.
I tried playing around with signs of the equality duals, but this does not help either.
Am I missing something here? Could it be that set_dual_start_value() is an inappropriate choice and does not work as I think it does?
Thanks very much in advance, any help is appreciated.
Also, thanks to @joaquimg and colleagues for this amazing package
PS: In addition, I was wondering about what would be the most elegant way to use an iterative procedure, i.e. to decrease the regularization parameter of ProductMode(), while using results from the previous iteration as a starting point?