Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
Expand all | Collapse all

Obtaining intermediate objective value for Dual Simplex through .NET interface

  • 1.  Obtaining intermediate objective value for Dual Simplex through .NET interface

    Posted 01/09/14 12:45 PM

    Originally posted by: AndrewBullock


    HI there

    When running an LP in the IDE it is possible to see the objective changing through the iterations and approaching the final objective. This is true for Simplex and Dual Simplex.

    When the same is performed through .NET or other interface, reading the Cplex.ObjValue, it works fine for Simplex, but the values for Dual Simplex do not correspond to the values in the IDE and don't seem meaningful / useful. I assume that they are some sort of shifted dual value.

    For example the same LP optimisation using Dual Simplex in the IDE and via .NET:

    IDE:

    Iteration log . . .
    Iteration:     1   Dual infeasibility =        103218.215621
    Iteration:  1380   Dual infeasibility =          6508.780022
    Iteration:  2210   Dual infeasibility =            11.540975
    Iteration:  3239   Dual objective     = -31969542803449029000.000000
    Markowitz threshold set to 0.1
    Iteration:  3308   Dual objective     =       9176048.805463
    Iteration:  5160   Dual objective     =      90464056.134219
    Iteration:  6484   Dual objective     =     110967632.184491
    ...
    ...
    Iteration: 27795   Dual objective     =     179696508.081963
    ...
    ...
    Iteration: 46302   Dual objective     =     180664067.144130
    ...
    ...
    Iteration: 58374   Dual objective     =     180682562.966689
    ...
    ...
    Iteration: 67753   Dual objective     =     180686286.311053
    Removing shift (199).
    Iteration: 68502   Dual infeasibility =             0.000133
    Iteration: 68550   Dual objective     = -1137454031767895.000000
    Iteration: 68588   Dual objective     = 500000180686310.370000
    Removing shift (7).
    Iteration: 68591   Dual infeasibility =             0.000002
    Iteration: 68594   Dual objective     =     180686301.408342

     

    i.e. this steadily approaches 180 million which is the final real objective value.

     

    .NET:

    Iterations Objective
     5000      4.517E-05
    10000      1.642E-05
    15000      3.605E-05
    20000      5.389E-05
    25000      2.279E-05
    30000      4.815E-05
    35000      2.300E-05
    40000      2.863E-05
    45000      1.797E-05
    50000      3.516E-05
    55000      1.650E-05
    60000      2.560E-05
    60744    180686301.5

     

    i.e. completely different values until the final iteration.

    How do I calculate the values that are displayed in the IDE (and are approaching the true final objective) when I am using .NET?

    Thanks

    Andrew

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: Obtaining intermediate objective value for Dual Simplex through .NET interface

    Posted 01/13/14 10:18 AM

    Originally posted by: VincentBeraudier


    Can you please give more details about how you reproduce?

    In the IDE, do you use some settings for the run config, which one?

    With the API, can you please also give the code you use?


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 3.  Re: Obtaining intermediate objective value for Dual Simplex through .NET interface

    Posted 01/14/14 07:55 AM

    Originally posted by: AndrewBullock


    Vincent

    Thanks for the reply.

    The setup is relatively straight foward. Standard LP - but quite a lot of variables.

    Settings are all default bar:

        <setting name="lpmethod" value="2"/> Force it to Dual SImplex
        <setting name="clocktype" value="1"/> CPU rather than clock
        <setting name="threads" value="1"/> Only use one processor
      <category name="run">
        <setting name="run_displaysolution" value="false"/> Avoid the wait
        <setting name="run_displayrelaxations" value="false"/> Avoid the wait

    Invocation over .NET is like this (I've trimmed out a lot of error handling and status reporting to make it more readable):

        Set Factory = New OplFactory ' Create the OPL Factory which creates all the other ILOG objects
        Set Project = Factory.CreateOplProject(Application.ActiveWorkbook.Path) ' Create an empty project
        Set RunConfiguration = Project.MakeRunConfiguration_2(...)
       
    Set Model = RunConfiguration.getOplModel()
        Call Model.Cplex.setOut(Nothing) ' Set the console output from CPLEX to be ignored

        Call Model.Generate ' Generate the OPL model

        Cycle = 0 ' Start at cycle zero
       
        Do While (Cycle < Maximum_Iterations / Iterations_Per_Cycle)
       
            ' Solve or partially solve the model and retrieve information on the solve
            SolveReturn = Model.Cplex.solve()
            SubStatus = Model.Cplex.CplexSubStatus ' Get the status
            Objective = Model.Cplex.ObjValue ' Get the current objective
            Iterations = Model.Cplex.Niterations ' Get the number of iterations in this solve cycle
           
            ' Check and respond to the returned status
            Select Case SubStatus
                Case "Optimal": ' Solver has reached a successful conclusion
                    ...
                    Exit Do ' Leave the cycle loops
                Case "AbortTimeLim": 
                    ...
                    Exit Do
                Case "AbortItLim": ' We've completed the iterations for the cycle with no solution - time for the next cycle
                    Call StatusMessage("In Progress. Iterations = " + CStr(Cycle * Iterations_Per_Cycle + Iterations) + " Objective = " + CStr(Objective))
                Case "Unbounded":
                    ...
                    Exit Do
                Case "Infeasible":
                    ...
                    Exit Do
                Case Else:
                    ...
                    Exit Do
            End Select
       
            Cycle = Cycle + 1 ' Move to the next cycle
        Loop

    The key line in the above is the one in red where I get the objective from Model.Cplex.ObjValue.

    Note that there is the following in the .mod to limit the number of iterations per cycle when running from .NET:

    execute Set_Control_Parameters { // ILOG Script to set the two control parameters
      writeln("Processing script: Set_Control_Parameters")
      if(thisOplModel.settings.skipAssert) { // This is only true when invoked over .NET
        cplex.tilim = TiLim; // Override the time limit and iteration limit from the .ops file with what's in the Control sheet from .NET
        cplex.itlim = ItLim;
      }
    }

    I believe the issue here is one of being able to convert from a Dual objective to a Primal one before the optimisation has reached an optimal state. The IDE manages it somehow, I just need to be able to do the same when running over .NET.

    Let me know your thoughts.

    Thanks
    Andrew

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer