yanweiyuan3
2023-08-09 588bc7829387dfc761cc25f06f77d4c81818bd10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Quintiq file version 2.0
#parent: #root
Method SelectScope (
  LibOpt_Optimizer optimizer,
  LibOpt_Run run
) #extension
{
  TextBody:
  [*
    // This needs to be overridden and implemented by the AE. 
    // The scope needs to be set on the Run here and it also needs to be returned.
    
    defaultscope := optimizer.DefaultScope(); 
    scope := LibOpt_Scope::Create( run, defaultscope ); 
    
    periods := selectsortedset( scope.GetPeriodInOptimizerRun(), Elements, p, true, p.Start() ); 
                
    optimizer.IsAutoCleanupSnapshots( false ); 
    optimizer.IsAutoCleanupRunsOnNrOfRuns( false ); 
    optimizer.IsAutoCleanupRunsOnRunAge( false );       
    runcontext := select(  run, RunContext.astype( RunContextForCapacityPlanning ), rc, true ); 
    runcontext.IsOTS( true ); 
    runcontext.IsOTSCollectAllKPIData( guard(  optimizer.ActiveSettings().astype( OptimizerMetaSettings ).OptionCollectionAllKPIData(), true ) ); // main because this signals we collect ALL kpis in the capture ( which is expensive )
    runcontext.IsForBenchmarking( true ); 
    runcontext.OTSFocusLevelTargetScore( guard( ifexpr( optimizer.ActiveSettings().astype( OptimizerMetaSettings ).UseFocusLevelTargetScore(), 
                                                        optimizer.ActiveSettings().astype( OptimizerMetaSettings ).FocusLevelTargetScore(), 
                                                        Real::MaxReal() ), 
                                                Real::MaxReal() ) ); // if not meta then set to maxreal(feature unused)
    
    // workaround for setting early stoppage based on reached score. Infinite means not using the feature
    if ( runcontext.OTSFocusLevelTargetScore().IsFinite() ) 
    {
      traverse(  run, Component.astype( LibOpt_IteratorUntil ).StopCriterion.astype( StopCriterionMeta ), stopmeta ) 
      {
        rcm := select(  run, RunContext.astype( RunContextMeta ), r, true, true ); 
        stopmeta.BenchmarkingStopScore( runcontext.OTSFocusLevelTargetScore() );
        stopmeta.BenchmarkingStopFraction( rcm.OptionBenchmarkStopThreshold() ); 
      }
    }
    
    // to define sub puzzles for OTS, it is done by unplanning some number of periods at the end of the horizon. We remove the periods prior to this part from the scope
    size := this.Size(); // value in between 0 and 1. See e.g. https://support.quintiq.com/doc/libopt/how_to/benchmarking/table/subpuzzle
    nrperiods := periods.Size(); 
    unplanfterindex := nrperiods - floor( nrperiods * size ); // size = 1 means unplanafterindex = 0, size = 0 means unplanafterindex = nrperiods. 
    index := 1;  
    traverse( periods, Elements, period, index <= nrperiods-1 )  //Always leave at least 1 period
    {
      if ( index <= unplanfterindex ) 
      {
        scope.Remove( period.PeriodInOptimizerRun() ); 
      }
      index++; 
    }
    run.SetStartScope( scope ); 
    
    // reset first and last period on runcontext
    periodstart := minselect( scope.GetPeriodInOptimizerRun(), Elements, p, true, p.Start() ); 
    periodend := maxselect( scope.GetPeriodInOptimizerRun(), Elements, p, true, p.Start() ); 
    runcontext.FirstPeriod_MP( relset, periodstart ); 
    runcontext.LastPeriod_MP( relset, periodend ); 
    
    return scope;
  *]
}