haorenhui
2023-10-30 6d6cc10d9e8e242661da7fd655dec155a09d676c
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
Quintiq file version 2.0
#parent: #root
Method InitConstraintsGoalsForSupplySpecifications (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  const RunContextForCapacityPlanning runcontext,
  const LibOpt_Scope scope
) const
{
  Description: 'The constraint to calculate the total supply specification that is used as goal'
  TextBody:
  [*
    collectvaluesmodel := runcontext.IsMetaIteration(); 
    
    totalmaxsupply := 0.0;
    totalminsupply := 0.0;
    totaltargetsupply := 0.0; 
    // calculate the supply target penalty
    // totalconst constraint UoM: Unit --> Please note that this means that if different units have a different UoM,
    //                                     their SupplyTargetQtyUnder will have a different weight in the goal
    totalconst := program.TotalSupplyTargetConstraints().New();
    totalconst.Sense( "=" );
    // using default RHS 0.0
    // Term UoM: Unit
    totalconst.NewTerm( -1.0 * this.ScaleConstraintTerm( typeof( MPTotalSupplyTargetVariable ), typeofexpression( totalconst ) )
                        , program.TotalSupplyTargetVariables().Get() );
    
    // calculate the minimum supply penalty
    // minconst constraint UoM: Unit --> Please note that this means that if different units have a different UoM,
    //                                     their MinSupplyQtyUnder will have a different weight in the goal
    minconst := program.TotalMinimumSupplyConstraints().New();
    minconst.Sense( "=" );
    // using default RHS 0.0
    // Term UoM: Unit
    minconst.NewTerm( -1.0 * this.ScaleConstraintTerm( typeof( MPTotalMinimumSupplyVariable ), typeofexpression( minconst ) )
                      , program.TotalMinimumSupplyVariables().Get() );
    
    // calculate the maximum supply penalty
    // maxconst constraint UoM: Unit --> Please note that this means that if different units have a different UoM,
    //                                   their MaxSupplyQtyOver will have a different weight in the goal
    maxconst := program.TotalMaximumSupplyConstraints().New();
    maxconst.Sense( "=" );
    // using defaul RHS 0.0
    // Term UoM: Unit
    maxconst.NewTerm( -1.0 * this.ScaleConstraintTerm( typeof( MPTotalMaximumSupplyVariable ), typeofexpression( maxconst) )
                      , program.TotalMaximumSupplyVariables().Get() );
    
    scalefactor_supplytargetqtyunder_totalconst := this.ScaleConstraintTerm( typeof( MPSupplyTargetQtyUnderVariable ), typeofexpression( totalconst) );
    scalefactor_minsupplyqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinSupplyQtyUnderVariable ), typeofexpression( minconst ) );
    scalefactor_maxsupplyqtyover_maxconst := this.ScaleConstraintTerm( typeof( MPMaxSupplyQtyOverVariable ), typeofexpression( maxconst ) );
    
    scalefactormaxsupplyover := CapacityPlanningSuboptimizer::GetVariableScaleFactor( typeof( MPMaxSupplyQtyOverVariable ) ); 
    scalefactorminsupplyunder := CapacityPlanningSuboptimizer::GetVariableScaleFactor( typeof( MPMinSupplyQtyUnderVariable ) ); 
    scalefactortargetsupplyunder := CapacityPlanningSuboptimizer::GetVariableScaleFactor( typeof( MPSupplyTargetQtyUnderVariable ) ); 
    
    if( runcontext.UseSupplySpecification() )
    {
      // The supply specification should only be considered if at least one unit in this optimizer runs influences this supply specification
      traverse( this.MacroPlan().GetUnitsConst(), Elements.SupplySpecification, supplyspec,
                exists( supplyspec, Unit.AllChildren.AsChildren, unit,
                        scope.Contains(  unit.UnitInOptimizerRun() )  ) )
      {
        // Penalty for not reaching the supply target
        // Term UoM: Unit
        totalconst.NewTerm( 1.0 * scalefactor_supplytargetqtyunder_totalconst,
                            program.SupplyTargetQtyUnderVariables().Get( supplyspec ) );
    
        // Penalty for not reaching the minimum supply quantity
        // Term UoM: Unit
        minconst.NewTerm( 1.0 * scalefactor_minsupplyqtyunder_minconst,
                            program.MinSupplyQtyUnderVariables().Get( supplyspec ) );
    
        // Penalty for not exceeding the maximum supply quantity
        // Term UoM: Unit
        maxconst.NewTerm( 1.0 * scalefactor_maxsupplyqtyover_maxconst,
                            program.MaxSupplyQtyOverVariables().Get( supplyspec ) );
        if ( collectvaluesmodel ) 
        {
          if ( supplyspec.HasMaxQuantity()  )
          {
            totalmaxsupply := totalmaxsupply 
            + scalefactor_maxsupplyqtyover_maxconst * maxvalue(  0.0, supplyspec.FulfilledQuantity() - supplyspec.MaxQuantity() ) / scalefactormaxsupplyover;
          }
          
          totalminsupply := totalminsupply 
          + scalefactor_minsupplyqtyunder_minconst * maxvalue(  0.0, supplyspec.MinQuantity() - supplyspec.FulfilledQuantity() ) / scalefactorminsupplyunder; 
          
          totaltargetsupply := totaltargetsupply 
          + scalefactor_supplytargetqtyunder_totalconst * maxvalue(  0.0, supplyspec.TargetQuantity() - supplyspec.FulfilledQuantity() ) / scalefactortargetsupplyunder; 
        }                        
      }
    }
    
    // workaround because cannot write to attribute
    this.StoreValueInProgram( program, 'collect_values_model_TotalMaximumSupplyVariables' , totalmaxsupply ); 
    this.StoreValueInProgram( program, 'collect_values_model_TotalMinimumSupplyVariables', totalminsupply );
    this.StoreValueInProgram( program, 'collect_values_model_TotalTargetSupplyVariables', totaltargetsupply );
  *]
  InterfaceProperties { Accessibility: 'Module' }
}