python-2.7cplexdocplexcloud

model.remove_constraint() performance


I'm working with CPLEX/docplex solving an LP problem that has a lot of infeasible constraints, most of the issues in feasibility come from the automated formulation of the model, and its hard to detect a priory the conflicts between constraints.

using the docplex functions ConflictRefiner().refine_conflict(model) im able to found, at least, one set of constraints in conflict.

The problem is that, in order to found all the sets of constraints in conflict, I have to remove some of the constraints in conflict using the function model.remove_constraint(constraint.name) and that function takes a long time to execute.

Edit the timings for 135.000 constraints are:

model.remove_constraint(constraint.name)
time= 124 sec
model.remove_constraint(constraint.element)
time= 126 sec

¿Is there a way to remove a constraint faster than with model.remove_constraint(str_name_constraint)?¿is there a way to get all the sets in conflict without having to remove/refine_conflict() for each set?¿is there a way to use hierarchy in constraints in order to avoid conflicts between constraints?

(last question its a little out of topic, but its related with the original problem)

thanks in advance!


Solution

  • finally I used a workaround,

    I didn't use mdl.remove_constraint(). to all the constraints i added a priority, and then I used the relaxer library provided by [docplex][1]. I couldn't found any example in the docs (or anywhere else) of the use of the relaxer, so i made one on my own (really simple to understand). The relaxer library is a really powerful tool, and its way much more easier to use rather than making all the relaxations by hand, especially when you have to deal with hierarchies in the constraints.

    Example:

    from docplex.mp.model import Model
    import docplex
    
    # we create a simple model
    mdl = Model("relax_model")
    
    x1=mdl.continuous_var(name='X1', lb=0)
    x2=mdl.continuous_var(name='X2', lb=0)
    
    # add conflict constraints
    c1=mdl.add_constraint(x1<=10,'c1_low')
    c2=mdl.add_constraint(x1<=5,'c2_medium')
    c3=mdl.add_constraint(x1>=400,'c3_high')
    c4=mdl.add_constraint(x2>=1,'c4_low')
    
    mdl.minimize(x1+x2)
    
    mdl.solve()
    print mdl.report()
    print mdl.get_solve_status() #infeasible model
    print
    print 'relaxation begin'
    
    from docplex.mp.relaxer import Relaxer
    rx = Relaxer(prioritizer='match')
    rx.relax(mdl,relax_mode= docplex.mp.relaxer.RelaxationMode.OptInf)
    
    print 'number_of_relaxations= ' + str(rx.number_of_relaxations)
    print rx.relaxations()
    
    print mdl.report()
    print mdl.get_solve_status()
    print mdl.solution
    

    I know that this isn't "the solution" for the model.remove_constraint() performance problem, but it fits well when you need to avoid it.