Thanks for the sample. Though is is not self-contained, I was able to reproduce and understand.
The root cause is the "update" you are performing on the variable dict.
This is not really necessary but breaks the internal consistency, as internal container objects keep an iterator on the
dict's values, which your code has modified. Hence this stored iterator crashes when it is executed.
I agree the documentation should make it explicit that variable dicts (and lists) should not be modified after created.
The workaround is simple: do not call "update" on an existing variable dict, create a new one.
With this modification, both `clone` and `relax` work fine:
from docplex.mp.model import Model
from docplex.mp.relax_linear import LinearRelaxer
mdl = Model('LP')
time_periods = [1,2,3]
initial_routes = [10,20]
keys = [(route, t) for route in initial_routes for t in time_periods]
x = mdl.continuous_var_dict(keys, name="x", lb=0, ub=1)
#new_routes_periods = solve_subproblem() # long function basically a labelling algorithm and can assume the output someting like: [(11,2),(13,1)]
#x.update(mdl.continuous_var_dict([4,5] , name="x", lb=0, ub=1))
x2 = mdl.continuous_var_dict([4,5] , name="x", lb=0, ub=1)
mdl2 = mdl.clone() # does not work
mdl2.print_information()
rx=LinearRelaxer()
lm = rx.linear_relaxation(mdl) # doesn't work
lm.print_information()
>>>
Model: Copy of LP
- number of variables: 8
- binary=0, integer=0, continuous=8
- number of constraints: 0
- linear=0
- parameters: defaults
- objective: none
- problem type is: LP
Model: lp_LP
- number of variables: 8
- binary=0, integer=0, continuous=8
- number of constraints: 0
- linear=0
- parameters: defaults
- objective: none
- problem type is: LP
------------------------------
Philippe Couronne
------------------------------
Original Message:
Sent: Mon June 07, 2021 06:33 AM
From: s charaf
Subject: Model from milp to lp docplex
I was using version 2.20 and I just upgraded it to the latest version, but the error remains.
Here is an example
mdl = Model('LP')time_periods = [1,2,3]initial_routes = [10,20]keys = [(route, t) for route in initial_routes for t in time_periods]x = mdl.continuous_var_dict(keys, name="x", lb=0, ub=1)new_routes_periods = solve_subproblem() # long function basically a labelling algorithm and can assume the output someting like: [(11,2),(13,1)]x.update(self.Model.continuous_var_dict(new_routes_periods , name="x", lb=0, ub=1))mdl.clone() # does not work A = mdl.integer_var_dict(time_periods, self.T, lb=0, ub=1, name="A")\mdl.add_constraints(A[t]==mdl.sum(x[route,t] for route in initial_routes+new_routes)) # new_routes = [11,13]mdl.solve()rx=LinearRelaxer()self.Model=rx.linear_relaxation(self.Model) # doesn't work
I can see that the error is thrown because of the update of the x variable because of the error message I get:
container
return self.model.get_var_container(self)
File "C:\Users\Local\Programs\Python\Python37\lib\site-packages\docplex\mp\model.py", line 1312, in get_var_container
ctn_map = self._ensure_var_to_container_map()
File "C:\Users\Local\Programs\Python\Python37\lib\site-packages\docplex\mp\model.py", line 1301, in _ensure_var_to_container_map
for dv in ctn.iter_variables():
RuntimeError: dictionary changed size during iteration
Original Message:
Sent: Mon June 07, 2021 06:10 AM
From: Philippe Couronne
Subject: Model from milp to lp docplex
Are you using a recent version of DOcplex ( I suggest either 2.20 or 2.21)? If not I suggest first upgrade to one those two.
I understand you get two issues:one with the relaxer and another with Model.clone() is that so?
Can you reproduce with a small sample, that would help?
Regards,
Philippe
------------------------------
Philippe Couronne
Original Message:
Sent: Mon June 07, 2021 05:46 AM
From: s charaf
Subject: Model from milp to lp docplex
thanks for your reply.
I tried to use the Linear_relaxer class
rx=LinearRelaxer()
Model=rx.linear_relaxation(Model)
but I get an error:
RuntimeError: dictionary changed size during iteration
I also tried to clone/copy the model before adding the integer variable and I get the same error.
I am adding columns as in a column generation and I suppose that that is the reason of the error message.
Is there a way to fix this?
Thanks!
Original Message:
Sent: Mon June 07, 2021 05:26 AM
From: Philippe Couronne
Subject: Model from milp to lp docplex
Hi,
If you want to solve a linear model, where all discrete variables are fixed to their value sin a previous solve, use solve_fixed.
If you want to solve a linear relaxation of the MILP model, regardless of previous solve values, use the LinearRelaxer class
Attached is a sample with solve fixed.
Regards.
Philippe Couronne
------------------------------
Philippe Couronne
Original Message:
Sent: Mon June 07, 2021 04:54 AM
From: s charaf
Subject: Model from milp to lp docplex
Hi,
I want to solve an integer version of my LP model and for that I had to add a binary variable, say A. After the integer solve, I want to reuse again the LP model. I tried removing the variable A but apparently it is not possible. so I tried changing its type to continuous this way
[Model._set_var_type(i, self.Model.continuous_vartype) for i in A.values()]
however, when I try to get the duals of my model, it says that my model is MILP and duals are not accessible for that type. As if the problem type is not updated after this change. I checked the number of integer/binary variables in my model and it is 0, but the problem type is MILP!
How is possible to inform docplex that the type of the model is actually LP and not MILP?
Thank you!
#DecisionOptimization