| Quintiq file version 2.0 | 
| #parent: #root | 
| StaticMethod CreateAlgorithmRunLevelsAndKPIResults (AlgorithmRun owner, StrategyMacroPlan strategymacroplan, LibOBT_RunTaskSetting benchmarksetting) | 
| { | 
|   Description: | 
|   [* | 
|     Create algorithm levels and kpi results instances for each strategy level owned by passed in strategy | 
|     LibMIP: this method should be used only in MacroPlan dataset. | 
|   *] | 
|   TextBody: | 
|   [* | 
|     // soh yee Nov-20-2013 (created) | 
|      | 
|     // Delete all records for easier maintenance, as we do not need to create / update / reset value for every level. | 
|     owner.AlgorithmRunLevel( relflush ); | 
|      | 
|     // Martijn van Elzakker Aug-06-2015 | 
|     // The last level is equal to the last level defined in the benchmarker | 
|     // or if "setting" is empty to the default number of strategy levels | 
|     // This last level is used to only optimize the strategy levels up to the level currently being autotuned | 
|     lastlevel := GlobalParameters_MP::GetDefaultNumberOfStrategyLevel(); | 
|      | 
|     if( not isnull( benchmarksetting ) ) | 
|     { | 
|       benchmarker := benchmarksetting.LibOBT_RunTask().LibOBT_Benchmarker(); | 
|      | 
|       if( benchmarker.LibOBT_BenchmarkerParameter().IsAutoTunerRun() ) | 
|       { | 
|         lastlevel := benchmarker.ActiveLevelAutoTuner(); | 
|       } | 
|     } | 
|      | 
|     // The levels could be discontinuous where there could be no goal assigned to the level. | 
|     // However, the level without goal will only take seconds for CPLEX to return the result. | 
|     // Thus the optimizer can be still run if the levels are discontinuous. | 
|     maxlevel := minvalue( strategymacroplan.MaxActiveLevel(), lastlevel ); | 
|     maxlevel := maxvalue( maxlevel, 1 );           // There must be at least one algorithm run level to run the optimizer. | 
|     traverse( strategymacroplan,  | 
|               StrategyLevelMacroPlan,  | 
|               strategylevelmacroplan,  | 
|               strategylevelmacroplan.Level() <= maxlevel ) | 
|     { | 
|       result := AlgorithmRunLevel::Create( owner, | 
|                                            strategylevelmacroplan.Level(), | 
|                                            strategylevelmacroplan.UseAbsoluteGap(), | 
|                                            strategylevelmacroplan.AbsoluteGap(), | 
|                                            strategylevelmacroplan.RelativeGap(), | 
|                                            strategylevelmacroplan.TimeLimit(), | 
|                                            strategylevelmacroplan.GoalScaling(), | 
|                                            strategylevelmacroplan.RelativeGoalSlack() ); | 
|      | 
|       AlgorithmRunSolverSetting::CreateAlgorithmRunSolverSettings( result, strategylevelmacroplan, benchmarksetting ); | 
|      | 
|       // create instances to store non financial kpi goal value obtained from optimizer | 
|       OptimizerNonFinancialKPIResult::Create( result ); | 
|      | 
|       // create instances to store account kpi goal value obtained from optimizer | 
|       // Non-active account is created for debugging purpose | 
|       traverse( strategymacroplan.MacroPlan().GetOptimizerAccounts(), Elements, account ) | 
|       { | 
|         OptimizerAccountKPIResult::Create( result, | 
|                                            account.Name(), | 
|                                            account.Level(), | 
|                                            account.Weight(),  | 
|                                            account.IsMaximize() ); | 
|       } | 
|     } | 
|      | 
|     Transaction::Transaction().Propagate( relation( StrategyLevelMacroPlan, SolverSettingGroupMacroPlan ) ); // make sure for autotuner solver setting ovveride is propagated | 
|   *] | 
| } |