Decision Optimization

 View Only
  • 1.  cplex.dualFarkas is not working

    Posted Tue February 09, 2021 12:58 AM
    Hi Cplex community,

    I am trying to learn to retrieve the Farkas certificates in Cplex, but I have not managed to do it.

    I created this simple toy model, but when I call the .dualFarkas method the arrayValues (the array in which I am planning to store the Farkas certificates), elements are null. I am attaching this same model as .mod file to this message.

    Am I missing something?

    I read that I should turn presolve off and that I needed to choose the dual simplex algorithm, but it is still not working. 

    Thanks in advance.



    dvar float+ x1;

    maximize 2*x1;
    subject to
    {
    ct1: -x1<=-5;
    ct2: x1<=2;
    }

    main
    {
    thisOplModel.generate();


    var modelDef = thisOplModel.modelDefinition;
    var modelData = thisOplModel.dataElements;
    var cplex1 = new IloCplex();
    var model = new IloOplModel(modelDef,cplex1);

    model.addDataSource(modelData);
    model.generate();
    //set the optimisation method to dual simplex
    cplex1.LPMethod = 2;
    //Turn off presolve because we need to solve the problem in order to realise the infeasability and
    //to get Farkas certificate. If we leave it on, it will prevent us from trying to solve the problem
    cplex1.preind = 0;

    cplex1.solve();

    var nRows = cplex1.getNrows();
    writeln("number of rows = " + nRows);
    var arrayConstraints = new Array(nRows);
    var arrayValues = new Array(nRows);

    writeln("cplex status = " + cplex1.status);
    cplex1.dualFarkas(arrayConstraints, arrayValues);
    writeln(arrayValues[1]);
    }



    ------------------------------
    Juan Esteban Calle Salazar
    ------------------------------

    #DecisionOptimization


  • 2.  RE: cplex.dualFarkas is not working

    Posted Tue February 09, 2021 08:59 AM
    This is a bug in the way this method is implemented in OPL script.
    It will be corrected in a next release.

    A possible workaround is to use the opl.IloCplex object with the method
    public double dualFarkas(IloConstraint[] rng, double[] y) throws IloExceptio
    through an external Java call. (see opl\examples\opl_interfaces\java\externaldataread sample for this).

    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 3.  RE: cplex.dualFarkas is not working

    Posted Thu February 11, 2021 11:26 PM
    Hi Vincent, thanks so much for your message.

    Your suggestion has made me think if I should redefine the approach I was thinking to implement a Customised Benders Algorithm. 

    To implement this type algorithm do you recommend me to go for a full  Concert-Technology based approach?

    Another question. If I decided to go through Docplex instead of Concert-Technology may I face some limitations as I do in OPL or the Docplex interface is well developed as it is Concert-technology. 

    Thanks in advance, I really appreciate any guidance on this.



    ------------------------------
    Juan Esteban Calle Salazar
    ------------------------------



  • 4.  RE: cplex.dualFarkas is not working

    Posted Fri February 12, 2021 03:30 AM
    If you are ok with using APIs, then you can stick to OPL. You will write your base model in OPL, then via C++ API, which are concert based, generate it (see for example oplrunsampl or mulprod in the C++ examples).
    Once it is generated, you can access all the OPL elements to manipulate them as IloNumExpr, IloNumVar, ...

    About docplex, this is also a good alternative with nearly no limitation: you use this api, with its expressions, operators... to create the model and manipulate it.
    If at any point, you face a limitation, you can then use the CPLEX Python wrappers which are a binding to the C API by getting the indexes of the docplex objects.
    I will ask Philippe to give more details about this.

    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 5.  RE: cplex.dualFarkas is not working

    Posted Fri February 12, 2021 05:50 AM
    Hi Juan,

      DOcplex provides a simple, operator-based API to cplex. However, as Vincent said, whenever you need some functionality which is not (yet) directly supported
    in Docplex, you can access the `cplex` object inside, and use the Python wrappers around the C API, giving you unlimited access to CPLEX API.
    For example, dual farkas is not documented in DOcplex, but you can very easily access the wrapper API to use it, as shown in the example below:

    from docplex.mp.model import Model

    def build_dual_farkas1():
    m = Model()
    x1 = m.continuous_var(name='x1')
    m.add( - x1 <= -5 , "x1_ge_5")
    m.add( x1 <= 2, "x1_less_2")
    m.maximize(2*x1)
    return m

    fk1 = build_dual_farkas1()
    fk1.parameters.lpmethod = 2
    fk1.parameters.preprocessing.presolve = 0
    assert fk1.solve(log_output=True) is None
    dfk = fk1.cplex.solution.advanced.dual_farkas()
    print(f"-- dual farkas returns: {dfk}")

    Let me know if you have any questions regarding Docplex or the Python API.


        Philippe.

    ------------------------------
    Philippe Couronne
    ------------------------------



  • 6.  RE: cplex.dualFarkas is not working

    Posted Mon April 12, 2021 09:15 PM
    Hi Philippe,

    Thanks for your answer.

    I decided to move to full python implementation. So, I might be asking you things in the near future.

    Juan

    ------------------------------
    Juan Esteban Calle Salazar
    ------------------------------



  • 7.  RE: cplex.dualFarkas is not working

    Posted Mon April 12, 2021 09:12 PM
    Hi Vincent.

    Thanks for your answer. Finally, I decided to move to a full python implementation of the model. 

    And I am working in the translation.

    Thanks!


    ------------------------------
    Juan Esteban Calle Salazar
    ------------------------------