陈清红
2025-04-14 880f3c0257eeb8c37761d484258fdd102a369a19
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
Quintiq file version 2.0
#parent: #root
Method InitConstraintsGoalsForStockingPointInPeriods (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  const RunContextForCapacityPlanning runcontext,
  const LibOpt_Scope scope
) const
{
  Description: 'Init constraints goals for stocking point in periods'
  TextBody:
  [*
    collectvaluesmodel := runcontext.IsMetaIteration(); 
    
    totalstockingpointviolation := 0.0; 
    
    totalstockingpointcapacity_varname := typeof( MPTotalStockingPointCapacityVariable );
    stockingpointcapacityoverloaded_varname := typeof( MPStockingPointCapacityOverloadedVariable );
    
    totalstockingpointcapacity_constname := typeof( MPTotalStockingPointCapacityConstraint );
    
    scalefactor_totalstockingpointcapacity_const := this.ScaleConstraintTerm( totalstockingpointcapacity_varname, totalstockingpointcapacity_constname );
    scalefactor_stockingpointcapacityoverloaded_const := this.ScaleConstraintTerm( stockingpointcapacityoverloaded_varname , totalstockingpointcapacity_constname );
    scalefactor_overmaxvar := CapacityPlanningSuboptimizer::GetVariableScaleFactor( stockingpointcapacityoverloaded_varname ); 
    
    // stocking point capacity overloaded
    // const constraint UoM: SP --> Please note that this means that if different SP have a different UoM,
    //                              their SPCapacityOverloaded will have a different weight in the goal
    const := program.TotalStockingPointCapacityConstraints().New();
    const.Sense( '=' );
    // using default RHS 0.0 
    // Term UoM: SP
    const.NewTerm( 1.0 * scalefactor_totalstockingpointcapacity_const, program.TotalStockingPointCapacityVariables().Get() );
    
    constmeta := null(  MPConstraint ); 
    if ( runcontext.IsMetaIteration() ) 
    {
      constmeta := program.TotalStockingPointCapacityMetaConstraints().New();
      constmeta.Sense( '=' );
      // using default RHS 0.0 
      // Term UoM: SP
      constmeta.NewTerm( 1.0 * scalefactor_totalstockingpointcapacity_const, program.TotalStockingPointCapacityMetaVariables().Get() );
    }
    
    // Overloaded capacity
    traverse( scope.GetStockingPointInPeriodInOptimizerRunConst(), 
              Elements, 
              spip,
              not spip.StockingPoint_MP().IsPlannedInfinite() 
              and not spip.IsPeriodFrozen() )
    {
      // Term UoM: SP
      coefficient := scalefactor_stockingpointcapacityoverloaded_const; 
      
    
      const.NewTerm( -1.0 * coefficient, program.StockingPointCapacityOverloadedVariables().Get( spip ) );
      
      if ( runcontext.IsMetaIteration() ) 
      {
        constmeta.NewTerm( -1.0 * coefficient, program.StockingPointCapacityOverloadedMetaVariables().Get( spip ) );
      }
      
      if ( collectvaluesmodel ) 
      {
        change_inventory := program.Variable(  'UnscaledRHSModificationSPInPeriodInventoryLevelConstraints', spip ).UpperBound();  // we filter RHS of this constraints to remove noise. Need to take this into account to compute existing violation 
        totalstockingpointviolation := totalstockingpointviolation +  coefficient * maxvalue(  0.0, (spip.InventoryLevelEnd() + change_inventory) - spip.MaxCapacity() ) / scalefactor_overmaxvar; 
      }
    }
    
    // workaround because cannot write to attribute
    this.StoreValueInProgram( program,'collect_values_model_TotalStockingPointCapacityVariables', totalstockingpointviolation );
  *]
  InterfaceProperties { Accessibility: 'Module' }
}