admin
2025-01-22 7e31442f0e9b07764e9c6a9680d3d4aeba5fe1de
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
111
112
113
Quintiq file version 2.0
#parent: #root
Method InitConstraintsGoalsForDriverLot (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  const RunContextForCapacityPlanning runcontext,
  const LibOpt_Scope scope
) const
{
  Description: 'Init constraints goals for account depends on lotsize.'
  TextBody:
  [*
    // Lot accounts
    
    if( runcontext.UseLotCost() )
    {
      driver := select( this, MacroPlan.AccountCostDriver, driver, driver.Name() = Translations::MP_AccountAssignmentCostDriverLot() );
      traverse( scope.GetAccountsInOptimizerRunConst(), Elements, account, account.HasLotAssignment() )
      {
        // Get mathematical program variable names
        driverlot_varname := typeof( MPDriverLotVariable );
        ptnroflots_varname := typeof( MPPTNrOfLotsVariable );
        operationinputnroflotsvarname := typeof(  MPOperationInputNrOfLotsVariable );
        tripnroflots_varname := typeof( MPTripNrOfLotsVariable );
        // Get the name of the constraints
        driverlot_constname := typeof( MPDriverLotConstraint );
        // Get the constraint term scale factors
        scale_dcconst_ptnroflotsvar := this.ScaleConstraintTerm( ptnroflots_varname, driverlot_constname );
        scale_dcconst_tripnroflotsvar := this.ScaleConstraintTerm( tripnroflots_varname, driverlot_constname );
        scale_dcconst_operationinputnroflotsvar := this.ScaleConstraintTerm( operationinputnroflotsvarname, driverlot_constname );
        scale_driverlotvar_driverlotconstr := this.ScaleConstraintTerm( driverlot_varname, driverlot_constname )
        
        // dcconst constraint UoM: Monetary
        dcconst := program.DriverLotConstraints().New( account, driver );
        dcconst.Sense( '=' );
        dcconst.RHSValue( this.ScaleConstraintRHS( driverlot_constname, 0.0 ) );
        // Term UoM: Monetary
        dcconst.NewTerm( 1.0 * scale_driverlotvar_driverlotconstr, program.DriverLotVariables().Get( account, driver ) );
      
        traverse( account, AccountAssignment, aa, aa.AccountCostDriver() = driver and aa.AccountCost( relsize ) > 0  )
        {
          // Operation (only include those that are part of this optimizer run and related to a unit period that is part of this optimizer run)
          traverse( aa, astype( UnitAccount ).UnitAccountInPeriodForLot.UnitPeriod, up, scope.Contains( up.UnitPeriodInOptimizerRun() ) )
          {
            period := up.Period_MP();
            
            traverse( up, Unit.OperationForOptimizationInScope, operation ) 
            {
              cost := operation.GetBaseCostPerLot( aa, up ); 
              
              ptnroflotsvar := program.PTNrOfLotsVariables().Find( operation, up.Period_MP() );
              if( not isnull( ptnroflotsvar ) )
              {
                dcconst.NewTerm( -cost * scale_dcconst_ptnroflotsvar, ptnroflotsvar );          
              }
              
              // Input lot terms
              if ( operation.HasInputLotSize() ) 
              {
                periodsfordd := construct( Period_MPs, constcontent ); // periods for dependent demand
                
                // Consider all relevant periods for the dependent demand
                if ( this.GetPeriodsFromPeriodTaskOperation() ) 
                {
                  traverse( operation, PeriodTaskOperationInScope.DependentDemand.ProductInStockingPointInPeriodPlanningLeaf.Period_MP, ddperiod )
                  {
                    periodsfordd.Add(  ddperiod );
                  }
                }
                else
                {
                  CapacityPlanningSuboptimizer::GetOperationDependentDemandPeriods( period, operation, &periodsfordd, this.GetPeriodsFromPeriodTaskOperation() ); // period may be included twice 
                }
                periodsfordd := periodsfordd.Unique();
                
                traverse( periodsfordd, Elements, ddperiod,
                          ddperiod.IsWithinLotSizeHorizon() )
                {
                  traverse( operation, 
                            OperationInput, 
                            input,
                            input.ProductInStockingPoint_MP().HasInputLotSize()
                            and ( input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( runcontext.IsPostProcessing() ) ) ) 
                  {
                    operationinputnroflotsvar := program.OperationInputNrOfLotsVariables().Find( input, period );
                    if( not isnull( operationinputnroflotsvar ) )
                    {
                      dcconst.NewTerm( -cost * scale_dcconst_operationinputnroflotsvar, operationinputnroflotsvar );
                    }
                  }
                }
              }    
            }
          }
      
          // Trip
          traverse( aa, astype( UnitAccount ).Unit.LaneLegForOptimization.Trip, trip, trip.HasValidDeparture() 
                                                                                      and scope.Contains(  trip.TripInOptimizerRun() )
                                                                                      and trip.DepartureUnitPeriod().HasLotSize()
                                                                                      and trip.DepartureUnitPeriod().Period_MP().IsWithinLotSizeHorizon() )
          {
            laneleg := trip.LaneLeg();
            cost := laneleg.GetBaseCostPerLot( aa, trip.DepartureUnitPeriod() );
            tripnroflotsvar := program.TripNrOfLotsVariables().Find( trip );
            if( not isnull( tripnroflotsvar ) )
            {
              dcconst.NewTerm( -cost * scale_dcconst_tripnroflotsvar, tripnroflotsvar );
            }
          }
        }
      }
    }
  *]
}