| Quintiq file version 2.0 | 
| #parent: #root | 
| MethodOverride CreateComponents ( | 
|   LibOpt_Run run | 
| ) | 
| { | 
|   TextBody: | 
|   [* | 
|     rcm := RunContextMeta::GetRunContextMeta( run );  | 
|      | 
|     runcontext := RunContextForCapacityPlanning::GetRunContextCapacityPlanning( run );  | 
|      | 
|     mp := this.Optimization().astype( Optimization ).MacroPlan();  | 
|     maxlevel := max( mp, StrategyMacroPlan.StrategyLevelMacroPlan, slm, true, slm.Level() );  | 
|      | 
|     prepostcomp := run.Component( relnew, OptimizerPrePostProcessing, Name := 'PrePostProcessing_Meta' );  | 
|      | 
|     iteratormeta := this.Iterator( run, 'IteratorLevels' ); // default start component  | 
|     iteratormeta.SetMaxIterations( this.GetNumberOfIterationForRoundRobin( maxlevel, rcm ) ); | 
|      | 
|     prepostcomp.To( iteratormeta );  | 
|                                      | 
|     roundrobin := this.SwitchRoundRobin( run, 'RoundRobinProcessAllLevels' );  | 
|     iteratormeta.To( roundrobin );  | 
|     if ( this.GetRunFullPuzzlePriorToMeta( rcm ) ) | 
|     { | 
|       selectorfullpuzzle := run.Component( relnew, SelectorFullPuzzle, Name := 'SelectorFullPuzzle' );  | 
|       transformerforuserperiodtasks := run.Component( relnew, TransformerFullRun, Name := 'TransformerFullRun'  );  | 
|       roundrobin.Branch( transformerforuserperiodtasks );   | 
|      | 
|       suboptimizer := CapacityPlanningSuboptimizer::Create( rcm.OptionMinimumMetaLevel() - 1,                                                    // focuslevel | 
|                                                             false,                                                // ispriorlevelsfixed | 
|                                                             runcontext.IsAutoScalingEnabled() and rcm.OptionAllowScalingRecompute(),                    // isupdatescaling | 
|                                                             false,                                                // runpastfocuslevel | 
|                                                             run,  | 
|                                                             'CapacityPlanningSubOptimizerForFullRunPriorMetaLevel',  // name | 
|                                                             false,   // user supply correction carried fwd inventory | 
|                                                             false,   // keep total available supply | 
|                                                             false,   // do not get periods by traversal over periodtaskoperation | 
|                                                             false,   // only plan demand smart plan pispips | 
|                                                             rcm.OptionMinimizePTQty(),  // extra level to minimize ptqty | 
|                                                             rcm.OptionMinimizePTQtyDoInventoryBased(),  | 
|                                                             rcm.OptionMinimizePTQTYLevelRelativeGoalSlack(),  | 
|                                                             true,    // apply noise threshold | 
|                                                             rcm.OptionUseHierarchicalCPLEXGoals(),  | 
|                                                             runcontext.SmallestIntegralityTolerance(), | 
|                                                             runcontext.SmallestFeasibilityTolerance(),  | 
|                                                             true,    // full plan for meta   | 
|                                                             false, 0.0 ); // collapse level and weight | 
|      | 
|         transformerforuserperiodtasks.To( selectorfullpuzzle );  | 
|         selectorfullpuzzle.To( suboptimizer ); | 
|          | 
|         RollbackKPIMeta::Create( suboptimizer,  | 
|                                RunContextForCapacityPlanning::GetRunContextCapacityPlanning( run ),  | 
|                                rcm.OptionPrecisionForRollback(),  | 
|                                rcm.OptionToleranceRollback(), | 
|                                rcm.OptionCutOffProcessMinQtyKPI(),  | 
|                                runcontext.SmallestFeasibilityTolerance(), // blending KPI precision  | 
|                                rcm.OptionUseRollBack(),  | 
|                                suboptimizer.FocusLevel(),  | 
|                                true ); // always accept  | 
|          | 
|     } | 
|     for ( focuslevel := rcm.OptionMinimumMetaLevel(); focuslevel <= maxlevel; focuslevel++ )  | 
|     { | 
|       maxdurationforlevel := Duration::Seconds( rcm.GetTotalDurationSecondsForLevel( focuslevel ) );  | 
|       stopmeta := construct( StopCriterionMeta,  | 
|                              FocusLevel := focuslevel,  | 
|                              MaxDurationLocal := maxdurationforlevel,  | 
|                              MaxDurationGlobal := Duration::Seconds( rcm.OptionMaxNumberOfSecondsRun() ),  | 
|                              ConvergenceWindowSize := rcm.OptionConvergenceWindowSize(),  | 
|                              ConvergenceThreshold := rcm.OptionConvergenceThreshold(),  | 
|                              CutOffForOptimal := rcm.OptionCutOffForOptimal(),  | 
|                              MaxError := rcm.OptionMaximumError(),  | 
|                              MaxLevel := maxlevel,  | 
|                              IsEnabledAutoScaling := runcontext.IsAutoScalingEnabled() and rcm.OptionAllowScalingRecompute() );  | 
|      | 
|       stopmeta.SetStopScoreForBenchmarking( run.Optimization().astype( Optimization ).MacroPlan(), runcontext.IsForBenchmarking(), rcm.OptionBenchmarkStopThreshold() ); // note for OTS we need to set it in select scope as workaround (LibOpt_BT_TrackingTableRow::SelectScope )                           | 
|       iteratorconv := this.Iterator(  run,  'IteratorConvergence' + [String] focuslevel, &stopmeta); | 
|        | 
|       roundrobin.Branch( iteratorconv );  | 
|       // create sub tree for level 'focuslevel' | 
|        | 
|       suboptimizerforlevel := CapacityPlanningSuboptimizer::Create( focuslevel,  | 
|                                                                     rcm.OptionFixDecisionVariablesPriorToFocusLevel(),  | 
|                                                                     runcontext.IsAutoScalingEnabled() and rcm.OptionAllowScalingRecompute(), // isupdatescaling,  | 
|                                                                     rcm.OptionRunPastFocusLevel(),  | 
|                                                                     run,  | 
|                                                                     'SubOptimizerLevel'+[String]focuslevel,  | 
|                                                                     false,   // apply user correction carried fwd inventory  | 
|                                                                     false,   // keep total avail supply override  | 
|                                                                     true,    // period for operations from periodtaskoperation like smart plan | 
|                                                                     false,   // only plan demand smart plan pispips | 
|                                                                     rcm.OptionMinimizePTQty(),  // extra level to minimize ptqty | 
|                                                                     rcm.OptionMinimizePTQtyDoInventoryBased(),  | 
|                                                                     rcm.OptionMinimizePTQTYLevelRelativeGoalSlack(),  | 
|                                                                     false,   // do not apply noise treshold during meta iterations | 
|                                                                     rcm.OptionUseHierarchicalCPLEXGoals(),  | 
|                                                                     runcontext.SmallestIntegralityTolerance(), | 
|                                                                     runcontext.SmallestFeasibilityTolerance(),  | 
|                                                                     false,   // full plan for meta   | 
|                                                                     rcm.OptionCollapseLevels(), // collapse level | 
|                                                                     rcm.OptionCollapseLevelWeight() ); // collapse level weight | 
|       RollbackKPIMeta::Create( suboptimizerforlevel,  | 
|                                RunContextForCapacityPlanning::GetRunContextCapacityPlanning( run ),  | 
|                                rcm.OptionPrecisionForRollback(),  | 
|                                rcm.OptionToleranceRollback(), | 
|                                rcm.OptionCutOffProcessMinQtyKPI(),  | 
|                                runcontext.SmallestFeasibilityTolerance(), // blending KPI precision  | 
|                                rcm.OptionUseRollBack(),  | 
|                                focuslevel,  | 
|                                rcm.OptionRollbackAlwaysAccept() );  | 
|          | 
|       startcomponentsubtree := this.CreateComponentTreeForLevel( run, suboptimizerforlevel, focuslevel ); | 
|       iteratorconv.To( startcomponentsubtree );   | 
|     } | 
|      | 
|     startexcludedproducts := Optimization::GetStartComponentForExcludedProductsOptimization( run );  | 
|     if ( not isnull( startexcludedproducts ) )  | 
|     { | 
|       // add to diagram by inserting an iteration up to | 
|       iteratortwotimes := this.Iterator(  run, 'IteratorTwoTimesForExcludedProducts'  );  | 
|       iteratortwotimes.SetMaxIterations( 2 );  | 
|       roundrobinforexcludedproducts := this.SwitchRoundRobin( run, 'RoundRobinForExcludedProducts' );  | 
|       prepostcomp.To( iteratortwotimes ); // redirect from iteratormeta in this case  | 
|       iteratortwotimes.To( roundrobinforexcludedproducts );  | 
|       roundrobinforexcludedproducts.Branch( iteratormeta );  | 
|       roundrobinforexcludedproducts.Branch( startexcludedproducts );  | 
|     } | 
|   *] | 
| } |