Search code examples
linear-programmingcplexdocplex

Understanding DoCPLEX Multi Objective


I am working on Pure LP problem with around 3 Million Constraints and I am currently using objective function with different weights. But to improve run time I am hoping to explore DoCPLEX multi- objective import "ObjectiveSense". Before implementation I wanted to understand how this solve works.

For Example:

My Objective Function is Maximize(-1000B -100C +10A -D -0.1E) Using Multi- Objective it is: ObjectiveSense.Maximize, [-B,A,-C,-D,-E], priorities=[5, 4, 3, 2, 1])

The one of the problem with weights is if 10A gets B1000 (which can be possible in few case) then A gets prioritized over B

Does Multi-Objective prevents this situation? Will it strictly prioritize B over all?


Solution

  • in https://developer.ibm.com/docloud/blog/2019/03/12/multiobjective-optimization-for-lp-and-mip-in-cplex/

    you may read

    Priority: an integer, default 0. Defines the order in which KPIs will be dealt with. If several sub-objectives have the same priority, they are blended together.

    With priorities you get hierarchical KPIs so a less important KPI even with a huge value won t get more important than a less important KPI

    Let me share a tiny example out of the zoo example:

    from docplex.mp.model import Model
    
    mdl = Model(name='buses')
    
    nbbus50 = mdl.integer_var(name='nbBus50')
    nbbus40 = mdl.integer_var(name='nbBus40')
    nbbus30 = mdl.integer_var(name='nbBus30')
    
    cost = mdl.continuous_var(name='cost')
    co2emission = mdl.continuous_var(name='co2emission')
    
    mdl.add_constraint(nbbus50*50+nbbus40*40 + nbbus30*30 >= 200, 'kids')
    mdl.add_constraint(co2emission==nbbus50+nbbus40*1.1+nbbus30*1.2)
    mdl.add_constraint(cost==nbbus40*500 + nbbus30*400+nbbus50*625)
                    
    sense="min"
    exprs=[cost,co2emission]
    priorities=[1,2]
    weights=[1,1]
    mdl.set_multi_objective(sense, exprs, priorities, weights, abstols=None, reltols=None, names=None)
    
    mdl.solve(lex_mipgaps = [0.001, 0.05], log_output=True)
    
    for v in mdl.iter_integer_vars():
        print(v," = ",v.solution_value)
    
    print("The minimum cost is ",cost.solution_value);
    print("CO2 emission is ",co2emission.solution_value);
    

    which gives

    nbBus50  =  4.0
    nbBus40  =  0
    nbBus30  =  0
    The minimum cost is  2500.0
    CO2 emission is  4.0