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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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 );
  *]
}