Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method CanRescueSolution ( 
 | 
  MathematicalProgram program, 
 | 
  LibOpt_Task task 
 | 
) as Boolean 
 | 
{ 
 | 
  Description: 'In MathematicalProgram Handle Infeasible tab, this method can be called to check if your infeasible solution has sufficient quality to try using it despite the reported infeasibility with CPLEX default settings.' 
 | 
  TextBody: 
 | 
  [* 
 | 
    // lauri Feb-24-2014 (created) 
 | 
    statistics := program.Statistics(); 
 | 
    feasabilitytolerance := 100 * guard( select( this.CurrentSubOptimizerLevel().GetStrategyLevelMacroPlan(), SolverSettingGroupMacroPlan.SolverSettingMacroPlan, s, s.ParameterNumber() = 1016 ).ParameterValue(),  
 | 
                                        1e-6 ); // cplex default if 1016 is not set 
 | 
     
 | 
    info( 'goal value:', guard( [String]program.GoalValue(), 'not available' ) );  
 | 
    info(  'Feasibility tolerance = ', feasabilitytolerance );  
 | 
    info( 'Solver has the following bound violation statistics:' ); 
 | 
    info( 'primal infeasibility: ', statistics.MaxPrimalInfeasibility().Format( 'N(Scientific)' ), 'scaled:', statistics.MaxScaledPrimalInfeasibility().Format( 'N(Scientific)' ) ); 
 | 
    info( 'primal residual: ', statistics.MaxPrimalResidual().Format( 'N(Scientific)' ), 'scaled:', statistics.MaxScaledPrimalResidual().Format( 'N(Scientific)' ) ); 
 | 
     
 | 
    info( 'dual infeasibility: ', statistics.MaxDualInfeasibility().Format( 'N(Scientific)' ), 'scaled:', statistics.MaxScaledDualInfeasibility().Format( 'N(Scientific)' ) ); 
 | 
    info( 'dual residual: ', statistics.MaxDualResidual().Format( 'N(Scientific)' ), 'scaled:', statistics.MaxScaledDualResidual().Format( 'N(Scientific)' ) ); 
 | 
     
 | 
    info( 'max integer infeasibility: ', statistics.MaxIntInfeasibility().Format( 'N(Scientific)' ), '[tolerance=', program.MIPIntegralityTolerance(), ']' ); 
 | 
     
 | 
    maxboundviolation := maxvalue( statistics.MaxScaledPrimalInfeasibility(), 
 | 
                                   statistics.MaxScaledPrimalResidual(), 
 | 
                                   statistics.MaxScaledDualInfeasibility(),   //only for LP 
 | 
                                   statistics.MaxScaledDualResidual() );         //only for LP 
 | 
     
 | 
     
 | 
     
 | 
     
 | 
    canberescued := program.HasSolution() and maxboundviolation <= feasabilitytolerance and statistics.MaxIntInfeasibility() <= program.MIPIntegralityTolerance(); 
 | 
     
 | 
    task.Log( 'hassoln=' + [String] program.HasSolution() + 'feas(scaled)='+ [String] maxboundviolation + 'intfeas=' + [String] statistics.MaxIntInfeasibility() );  
 | 
     
 | 
    info(  ifexpr(  canberescued, 'Solution accepted', 'Solution discarded' ) );  
 | 
     
 | 
    if(  not canberescued  
 | 
         and this.GetRunContextConst().IsMetaIteration()  
 | 
         and this.GetRunContextMeta().OptionDebugCPLEXVariablesConstraints() )  
 | 
    { 
 | 
      snapshot := task.Run().Snapshot( relnew, SnapshotMacroPlannerOptimizer );  
 | 
      OptimizerDebugCPLEXLogEntry::CheckVariables( snapshot, program.astype( CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm ) );  
 | 
      OptimizerDebugCPLEXLogEntry::CheckConstraints( snapshot, program.astype( CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm ) );  
 | 
    } 
 | 
     
 | 
    return canberescued; 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |