| Quintiq file version 2.0 | 
| #parent: #root | 
| Method CapacityPlanningAlgorithmHandleInFeasible ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   RunContextForCapacityPlanning runcontext, | 
|   LibOpt_Task task | 
| ) | 
| { | 
|   TextBody: | 
|   [* | 
|     // Set end time and status of optimizer run  | 
|      | 
|     status := Translations::MP_GlobalParameters_GetOptimizerInfeasibleStatus(); | 
|      | 
|     algorithmrun := this.MacroPlan().GetLastAlgorithmRun();  | 
|     algorithmrun.Update( algorithmrun.Notes(), status ); | 
|      | 
|     info( 'Remark:', program.Remark() ); | 
|      | 
|     canrescue := this.CanRescueSolution( program, task )  | 
|     if( canrescue  ) | 
|     { | 
|       status := Translations::MP_GlobalParameters_GetOptimizerFeasibleWithNumericalWarnings(); | 
|       algorithmrun.Update( algorithmrun.Notes(), status ); | 
|      | 
|       info( 'Quality high enough, trying to use solution despite partial infeasibility.' );        | 
|        | 
|       algorithmrun.UpdateWorstStatus( status, program.Remark() );  | 
|       this.HandleFeasible( program, task );  | 
|     } | 
|     else  | 
|     { | 
|       isfirsthandleinfeasiblecall := this.CurrentSubOptimizerLevel().IsFirst();  | 
|       if ( isfirsthandleinfeasiblecall ) // initialize of cplex needs to be const for paralellization. Any non-const processing is moved into the delayed initialization called on return of first handle feasible/infeasible.  | 
|       { | 
|         this.DelayedInitialization( program, task, runcontext, false );    | 
|       } | 
|       if( not runcontext.IsMetaIteration() ) | 
|       { | 
|         info( 'Quality is not meeting expectation, solution will not be used.' ); | 
|          | 
|         level := algorithmrun.GetAlgorithmRunLevel( this.CurrentSubOptimizerLevel().LevelNumber() ); | 
|         level.Update( level.Start(), DateTime::ActualTime(), false, program.AbsoluteGap(), program.RelativeGap(), program.GoalValue(), program.Optimal() ); | 
|         level.UpdateStatistics( program, this.IsAutoScalingEnabled() ); | 
|         algorithmrun.UpdateWorstStatus( status, program.Remark() ); | 
|         algorithmrun.CalcRunUIFeedback(); // AlgorithmRunLevel IsFeasible attribute is set above and this method should be called for propagating | 
|         if( program.Remark() = CapacityPlanningSuboptimizer::GetTimeLimitExceededRemark() ) | 
|         { | 
|           status := Translations::MP_GlobalParameters_GetOptimizerTimeLimitExceededStatus();     | 
|         }  | 
|          | 
|          | 
|          | 
|         // Save the number of sanity check errors and the tooltip text on algorithm run for the benchmark problems | 
|         Transaction::Transaction().Propagate(); | 
|         algorithmrun.NumberOfSanityCheckErrors( this.MacroPlan().SanityCheckHighestSeverityMsgCount() ); | 
|         if( algorithmrun.NumberOfSanityCheckErrors() > 0 ) | 
|         { | 
|           algorithmrun.SanityCheckHighestSeverityToolTip( Translations::MP_SanityCheck_Failed( this.MacroPlan().MostSevereSanityCheckCategoryLevel() ) ); | 
|         } | 
|       } | 
|        | 
|       // Run the automatic scaling if it is enabled and the solution could not be rescued | 
|       // If it could be rescued, it will be run in the HandleFeasible method | 
|       if( this.IsAutoScalingEnabled() ) | 
|       { | 
|         this.RunAutoScaling( program, task, runcontext.IsMetaIteration() );  | 
|       } | 
|        | 
|       snapshotkpi := this.LogKPI( task, Translations::LibOpt_SnapshotMP_Details_NoSolutions() );  | 
|       snapshotkpi.astype( SnapshotMacroPlannerOptimizer ).IsAccepted( true );  | 
|      | 
|       if ( runcontext.IsMetaIteration() and RunContextMeta::GetRunContextMeta( task.Run( )).OptionStopOnInfeasible() )  | 
|       { | 
|         this.Run().BreakpointEvent( relnew ); | 
|         program.ProblemFileName( 'infeasible.sav' );  | 
|       } | 
|     } | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |