Aaron_Geng
Aaron_Geng

Reputation: 339

What is the efficient way to add new variables using docplex python API?

I have a basic question about docplex library. Does anyone know what is the best way to add/delete variables from existing model? I am using the following code to create decision variables

self.model.continuous_var_dict(self.N, lb=0)

Can I run this line again by just increasing the size of self.N?

I also want to know if there is an efficient way for updating existing constraints, right now, I am deleting all the constraints and adding new ones back using the following code

self.model.remove_constraints(self.constrains)
self.constrains = self.model.add_constraints(
        self.model.sum(self.cons_coef[(i, k, p)] * self.x_mp[(k, p)] for k, p in self.N) == 1 for i in range(N))

What if I only want to add new columns in column generation?

Upvotes: 1

Views: 1493

Answers (2)

rkersh
rkersh

Reputation: 4465

The way that you are adding variables (through continuous_var_dict) is fine. Yes, you can call continuous_var_dict repeatedly to add several batches of variables. In terms of performance, docplex should be adding these to CPLEX in the quickest way possible. If you are surprised by slow performance, please share the specifics.

To remove variables, you remove them from the objective and constraints of the model. For example, using LinearExpr.remove_term.

To modify constraints, you can do something like the following (see LinearConstraint.lhs):

for c in contraints:
   c.lhs += model.sum_vars(newvars)

The docplex "incremental modeling" example demonstrates this (see here).

Upvotes: 0

Alex Fleischer
Alex Fleischer

Reputation: 10062

you may do incremental changes:

 from docplex.mp.model import Model

# original model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

mdl.export("c:\\buses.lp")

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

#now 350 kids instead of 300

print()
print("now 350 kids instead of 300")    

mdl.get_constraint_by_name("kids").rhs=350;
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

# no more than 4 buses 40 seats

print()
print("no more than 4 buses 40 seats")


mdl.get_var_by_name("nbBus40").ub=4
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

#change the objective so that cost for 40 seats is 450
#and remove the limit on the number of buses 40 seats

print()
print("change the objective so that cost for 40 seats is 450")
print("and remove the limit on the number of buses 40 seats  ")  

mdl.get_var_by_name("nbBus40").ub=1000
mdl.set_objective("min",nbbus40*450 + nbbus30*400);
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value) 

which gives

nbBus40  =  6.0
nbBus30  =  2.0

now 350 kids instead of 300
nbBus40  =  8.0
nbBus30  =  1.0

no more than 4 buses 40 seats
nbBus40  =  2.0
nbBus30  =  9.0

change the objective so that cost for 40 seats is 450
and remove the limit on the number of buses 40 seats  
nbBus40  =  8.0
nbBus30  =  1.0

Upvotes: 0

Related Questions