Quintiq file version 2.0 
 | 
#parent: #root 
 | 
MethodOverride Operation ( 
 | 
  LibOpt_Task task 
 | 
) as stream[JSON] 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    debuginfo(  'ITERATION START >>>>>>>>>>>>>>>>>>>>>>. Previous accepted seqnr =', guard( task.Run().LastAcceptedSnapshotMacroPlannerOptimizer().SequenceNr(), -1 ), 'objtype=', this.DefinitionName() );  
 | 
    start := OS::PrecisionCounter();  
 | 
    out_scope := LibOpt_Scope::Create( task.Run(), task.Scope().ScopeElements() ); // copy because periods are already in there  
 | 
    out_scope.EstimatedNrPISPIPs( 0 );  
 | 
     
 | 
    lanelegsforopt := selectset(  out_scope.GetLaneLegForOptimization(), Elements, ll, true, true );  
 | 
     
 | 
    periods := selectset(  out_scope.GetPeriodInOptimizerRun(), Elements, p, true, true );  
 | 
    SelectorMeta::ResetAllPISPAttributes( this.Optimization().astype( Optimization ).MacroPlan() ); // for estimated counting puzzle size in #of pispips while we build up the puzzle ( takes into account gap filling is still to happen) 
 | 
    runcontextmeta := this.GetRunContextMeta();  
 | 
    runcontextmeta.SelectorAddedFriends( false ); 
 | 
    iscampaignoptimization :=  this.Optimization().astype( Optimization ).MacroPlan().StrategyMacroPlan().UseCampaignSequenceOptimizer();  
 | 
    /* debugging - single level cplex. Example growing constraint weights as follows:  
 | 
     
 | 
    weightlevels := select(  task, Run.RunContext.astype( RunContextForCapacityPlanning ).WeightLevelNonFinancial, wl, true, true );  
 | 
    growthfactor := runcontextmeta.OptionGrowthFactorConstraintWeights();  
 | 
     
 | 
    if ( not growthfactor = 1 )  
 | 
    { 
 | 
      weightlevels.UnitCapacityWeight( minvalue(  1e6, weightlevels.UnitCapacityWeight() * growthfactor) );  
 | 
      weightlevels.StockingPointCapacityWeight( minvalue( 1e6, weightlevels.StockingPointCapacityWeight() * growthfactor ) );  
 | 
      weightlevels.SlackWeight( minvalue(  1e6, weightlevels.SlackWeight() * growthfactor ) );  
 | 
       
 | 
      debuginfo(  ' ################ unit cap wt=', weightlevels.UnitCapacityWeight(), '######' );  
 | 
      debuginfo(  ' ################ stpt cap wt=', weightlevels.StockingPointCapacityWeight(), '######' );  
 | 
      debuginfo(  ' ################    slack wt=', weightlevels.SlackWeight(), '######' );  
 | 
    } 
 | 
    */ 
 | 
    if(  runcontextmeta.IsSelectorBeyondFirstIteration() or iscampaignoptimization ) // for campaign optimization we need to run cplex because level 0 score depends on feasbility of combis 
 | 
    { 
 | 
      // build up neighborhood until size at limit 
 | 
      if ( runcontextmeta.OptionDebugCopyDataSetForSaveRollback() )  
 | 
      { 
 | 
        this.DebugCopyDataSet( task );  
 | 
      } 
 | 
      runcontext := this.GetRunContextCapacityPlanning();  
 | 
       
 | 
      this.AdaptNeighborhoodSize( task, runcontext, runcontextmeta );  
 | 
       
 | 
      debuginfo( 'Size limit = ', runcontextmeta.OptionMaxNumberOfPISPIPSForNeighborhood() );  
 | 
      task.Log( 'Size limit' + [String] runcontextmeta.OptionMaxNumberOfPISPIPSForNeighborhood() );  
 | 
      this.DescriptionSelectedAnchor( '' );  
 | 
       
 | 
      anchorpispips := this.GetAnchorPISPIPs( out_scope, runcontext, runcontextmeta ); // ordinary operation  
 | 
       
 | 
      task.Log( 'ANCHOR ' + this.DescriptionSelectedAnchor() );  
 | 
      debuginfo( 'ANCHOR', this.DescriptionSelectedAnchor() );    
 | 
         
 | 
      this.IncreaseTriedCount( anchorpispips );  
 | 
       
 | 
      this.BuildBasicNeighborhood( anchorpispips, task, out_scope, lanelegsforopt, periods, runcontext, runcontextmeta ); // this method build the basic neighborhood, excluded gap fill + nonleaf pispips 
 | 
       
 | 
      this.PISPGapFill( out_scope, runcontext ); 
 | 
     
 | 
      this.ShelfLifeCompleteSimple( out_scope, runcontext );  
 | 
         
 | 
      this.AddNonLeafPlanning( out_scope ); 
 | 
       
 | 
      // Handle sales demand before the optimization horizon, including those before the planning horizon. 
 | 
      TransformerSmartPlan::AddSalesDemandsBeforeScope( out_scope, runcontext ); 
 | 
       
 | 
      this.CompleteForSmallPuzzle( task, runcontext, out_scope ); 
 | 
       
 | 
      out_scope.CompleteForPTO_PIT(); // add in unitperiods, units, operations, trips based on pto and pit  
 | 
      out_scope.CompleteFor_PISPIP(); // ensure scope contains period, pisp, spip and sales demand objects for pispip in scope 
 | 
        
 | 
      out_scope.CompleteForCampaignSequencingSimple( this, runcontextmeta, runcontext ); // simple completion of neighborhood for campaign sequencing            
 | 
       
 | 
      this.ActivateUnitShiftPatterns( runcontext, runcontextmeta, out_scope );  
 | 
                                                                                                                                                                         
 | 
      if ( this.Optimization().astype( Optimization ).DebugMode() )  
 | 
      { 
 | 
        SelectorMeta::ComputeFirstLastPISPIPInScope( out_scope ); // make sure first last relations are set 
 | 
        SelectorMeta::CheckNoGap( out_scope ); // in debug mode check gap property 
 | 
      } 
 | 
       
 | 
      analysis := MathematicalProgramAnalysis::Analysis();  
 | 
      if ( guard( analysis.Active(), false ) )  
 | 
      { 
 | 
        info(  'Resetting math program analsyis for iteration' );  
 | 
        analysis.ResetAnalysis(); // only keep for last iteration so we can run extended nr of iteration until running into trouble 
 | 
      } 
 | 
    } 
 | 
    else 
 | 
    { 
 | 
      debuginfo(  'Skipping first iteration ', this.DefinitionName() );  
 | 
    } 
 | 
    runcontextmeta.IsSelectorBeyondFirstIteration( true ); // first iteration we don't optimize 
 | 
     
 | 
    this.StoreKPIForSubOptimizer( task, out_scope );  
 | 
    this.CollectDebugInFormation( task );  
 | 
    this.IncreaseInScopeCount( out_scope );  
 | 
     
 | 
    this.ReducePeriodDecay( task, runcontextmeta );  
 | 
     
 | 
    end := OS::PrecisionCounter();  
 | 
    durationselector := (end-start)/ OS::PrecisionCounterFrequency();  
 | 
    debuginfo( 'Done =', DateTime::ActualTime(), 'Duration = ', durationselector );  
 | 
    task.Log( 'Selector Duration = ' + [String] durationselector + 'estimate pispips = ' + [String] out_scope.GetEstimatedNrPISPIPs( ));  
 | 
    return this.Continue( task, out_scope ); 
 | 
  *] 
 | 
} 
 |