Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method CapacityPlanningAlgorithmHandleFeasible ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  LibOpt_Task task 
 | 
) as CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm 
 | 
{ 
 | 
  Description: 'The method called in "Handle feasible" tab' 
 | 
  TextBody: 
 | 
  [* 
 | 
    scope := task.Scope();  
 | 
    // Program goal value is affected by goal scaling factor. It is intended to show the CPLEX value with scaling applied 
 | 
    goalvalue := program.GoalValue(); 
 | 
    isinventoryoptimization := runcontext.IsInventoryOptimizationRun(); 
 | 
    // We only want to report the progress of the algorithm runs if this is not an autotune copy and this is not an inventory optimization 
 | 
    isdisplay := not isinventoryoptimization 
 | 
                 and not runcontext.IsMetaIteration(); 
 | 
     
 | 
    // Do not report the current level if this is an inventory optimization run 
 | 
    if( isdisplay ) 
 | 
    { 
 | 
      info( Translations::Algorithm_MP_InfoCurrentLevel( [String]this.CurrentSubOptimizerLevel().LevelNumber() ) ); 
 | 
      info( Translations::Algorithm_MP_InfoFeasibleCapacityPlanning( [String]DateTime::ActualTime(), [String]goalvalue ) ); 
 | 
    } 
 | 
     
 | 
    dofinalize := this.CurrentSubOptimizerLevel().IsLast() or ( this.UseHierarchicalCPLEXGoals() );  
 | 
    justoptimizerhiddenslacklevel := this.CurrentSubOptimizerLevel().IsFirst();  
 | 
    algorithmrun := this.MacroPlan().GetLastAlgorithmRun();  
 | 
    iscampainoptimization := runcontext.UseCampaignSequenceOptimizer();  
 | 
     
 | 
    if ( not runcontext.IsMetaIteration() )  
 | 
    { 
 | 
      this.DebugWriteForAutoTestInstances( program, runcontext, scope );  
 | 
      this.AppendLastRunResultToLogFile( program );  // Update the log file with the latest results 
 | 
    } 
 | 
     
 | 
    // Update postprocessing start 
 | 
    algorithmrun.UpdatePostprocessingTime( DateTime::ActualTime(), algorithmrun.PostprocessingEnd() ); 
 | 
     
 | 
    if( isdisplay ) 
 | 
    { 
 | 
      this.DisplayGoalValue( program, runcontext );   // Display scores 
 | 
    } 
 | 
    if( not task.IsAborted() 
 | 
        and dofinalize 
 | 
        and ( not runcontext.IsMetaIteration() or ( this.IsBeyondFirstIteration() or iscampainoptimization)  or this.IsFullPlanMetaPriorFocus() ) ) // first iteration for meta optimizer we don't plan, unless campaign optimization 
 | 
    {                                                                                                                                               // as we need to know feasbility of campaign combis, for level 0 score 
 | 
      pispipsinrun := scope.GetPISPIPInOptimizerRun();  
 | 
      // Handle feasible methods to assign optimizer optimal value to attributes 
 | 
      this.ResetPeriodTaskCampaign( runcontext, scope );  
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleCampaignSequencing( program, runcontext, task ); 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleOperationPeriodTask( program, runcontext, task ); 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleTrip( program, scope ); 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleSalesDemand( program, runcontext, scope, pispipsinrun ); 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleProductInStockingPointInPeriod( program, runcontext, scope, this.Setting_KeepTotAlavailableSupplyOverride(), pispipsinrun ); 
 | 
      this.CapacityPlanningAlgorithmHandleFeasibleShiftPattern( program, runcontext, scope ); 
 | 
      this.SetOptimizerFulfilledTargetInventoryQuantityPastHorizon( runcontext, scope ); 
 | 
      Transaction::Transaction().Propagate();  
 | 
      this.DebugWriteVariables( program, scope, pispipsinrun );  
 | 
      if ( runcontext.IsSlidingWindowsRun() )  
 | 
      { 
 | 
        this.CurrentSubOptimizerLevel( relset, this.FirstSubOptimizerLevel() );  
 | 
      } 
 | 
      else 
 | 
      { 
 | 
        this.CurrentSubOptimizerLevel( relflush ); // signal for post handle results, so we only obtain KPIs all the way at the end (is expensive) 
 | 
      } 
 | 
      if ( this.Optimization().astype( Optimization ).DebugMode() )  
 | 
      { 
 | 
        this.Optimization().astype( Optimization ).CheckOptimizerPuzzle( task );    
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Update postprocessing end 
 | 
    algorithmrun.UpdatePostprocessingTime( algorithmrun.PostprocessingStart(), DateTime::ActualTime() ); 
 | 
     
 | 
    isunfreeze := false; 
 | 
    if ( justoptimizerhiddenslacklevel  
 | 
         and not dofinalize )  
 | 
    { 
 | 
      this.FreezeZeroSlack( program, isunfreeze, runcontext, scope ); 
 | 
    } 
 | 
     
 | 
    if( ( not runcontext.IsMetaIteration() or ( this.IsBeyondFirstIteration() or iscampainoptimization ) or this.IsFullPlanMetaPriorFocus() ) // first iteration of level for meta optimizer we do plan, just record KPI to check skip to next focuslevel  
 | 
        and not task.IsAborted() 
 | 
        and not dofinalize ) 
 | 
    { 
 | 
      this.SetNextSubOptimizerLevelAsCurrent();  
 | 
      this.ActivateGoals( program, runcontext, scope );          //activate terms for next level 
 | 
     
 | 
      if( isdisplay ) 
 | 
      { 
 | 
        info( Translations::Algorithm_MP_InfoReExecuteLevel( [String]DateTime::ActualTime(), [String]( this.CurrentSubOptimizerLevel().LevelNumber() ), [String]goalvalue ) ); 
 | 
        this.AddLogFileMarking( program ); 
 | 
      } 
 | 
       
 | 
      // Re-execute cplex 
 | 
      program.MIPStartSolution( true ); 
 | 
      this.ReExecute( program ); 
 | 
         
 | 
      // Add extension to program file name such that it is postfix with level 
 | 
      filename := program.ProblemFileName(); 
 | 
      if( filename <> Util::Const_EmptyString() ) 
 | 
      { 
 | 
        nextlevel := this.CurrentSubOptimizerLevel().LevelNumber();  
 | 
        strings := filename.Tokenize( Util::Const_Dot() ); 
 | 
        extension := ifexpr( this.IsLPFileExported(), Translations::Algorithm_MP_FileExtensionSav(), guard( strings.Element( strings.Size() - 1 ), Translations::Algorithm_MP_FileExtensionSav() ) ); 
 | 
        program.ProblemFileName( Translations::Algorithm_MP_ProblemFileName( nextlevel.AsQUILL(), extension ) ); 
 | 
        debuginfo( 'Problem file name=', program.ProblemFileName() ); 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Run the autoscaling 
 | 
    if( this.IsAutoScalingEnabled() and dofinalize ) 
 | 
    { 
 | 
      // Update the rest of the statistics and run the autoscaling after the last level 
 | 
      this.RunAutoScaling( program, task, runcontext.IsMetaIteration() ); 
 | 
    } 
 | 
     
 | 
    if ( not runcontext.IsMetaIteration() )  
 | 
    { 
 | 
      algorithmrun.CalcRunUIFeedback(); // AlgorithmRunLevel IsFeasible attribute is set above and this method should be called for propagating 
 | 
    } 
 | 
     
 | 
    if( dofinalize   
 | 
        and not runcontext.IsMetaIteration() ) 
 | 
    { 
 | 
      // If this is a sliding windows run and the last period in the active window is not the last period in the optimizer run 
 | 
      // then slide the window and reexecute the algorithm 
 | 
      lastperiodinwindow := maxselect( scope.GetPeriodInSlidingWindow(), Elements, period, true, period.Start() ); 
 | 
      if( runcontext.IsSlidingWindowsRun() 
 | 
          and lastperiodinwindow <> runcontext.LastPeriod_MP() ) 
 | 
      { 
 | 
        this.ReExecuteOptimizerSlidingWindows( program, runcontext, task ); 
 | 
      } 
 | 
      else 
 | 
      {     
 | 
        if( runcontext.IsInventoryOptimizationRun() ) 
 | 
        { 
 | 
          runcontext_nonconst := select( task, Run.RunContext.astype( RunContextForCapacityPlanning ), rctxt, true, true ); // workaround because we don't want avoid the cascase of const argument down this path 
 | 
          this.CapacityPlanningAlgorithmHandleFeasibleInventoryOptimization( runcontext_nonconst, scope ); 
 | 
        } 
 | 
     
 | 
        if( algorithmrun.IsBenchmark() ) 
 | 
        { 
 | 
          Transaction::Transaction().Propagate(); 
 | 
          algorithmrun.NumberOfSanityCheckErrors( this.MacroPlan().SanityCheckHighestSeverityMsgCount() ); 
 | 
          if(  algorithmrun.NumberOfSanityCheckErrors() > 0 ) 
 | 
          { 
 | 
            algorithmrun.SanityCheckHighestSeverityToolTip( Translations::MP_SanityCheck_Failed( this.MacroPlan().MostSevereSanityCheckCategoryLevel() ) ); 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    return program; 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |