陈清红
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 InitConstraintsGoalsForDriverTime (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  const LibOpt_Scope scope
) const
{
  Description: 'Init constraints goals for account depends on time, applicable to unit period time'
  TextBody:
  [*
    // Time accounts
    // Get variable names
    ptqty_varname := typeof( MPPTQtyVariable );
    tvarname := typeof( MPDriverTimeVariable );
    // Get constraint names
    tconstname := typeof( MPDriverTimeConstraint );
    // Get scaling factors
    scalefactor_driver_tconst := this.ScaleConstraintTerm( tvarname, tconstname );
    scalefactor_periodtaskqty_tconst := this.ScaleConstraintTerm( ptqty_varname, tconstname );
    
    scalefactor_rhs_tconst := this.ScaleConstraintRHS( tconstname, 1.0 );
    
    driver := select( this, MacroPlan.AccountCostDriver, driver, driver.Name() = Translations::MP_AccountAssignmentCostDriverTime() ); // unique
    traverse( scope.GetAccountsInOptimizerRunConst(), Elements, account, account.HasTimeAssignment() ) // condition => driver not null
    {
      // tconst constraint UoM: Monetary
      tconst := program.DriverTimeConstraints().New( account, driver );
      tconst.Sense( '=' );
      tconst.RHSValue( 0.0 * scalefactor_rhs_tconst );
      // Term UoM: Monetary
      tconst.NewTerm( 1.0 * scalefactor_driver_tconst, program.DriverTimeVariables().Get( account, driver ) );
    
      traverse( account, AccountAssignment, aa, aa.AccountCostDriver() = driver and aa.AccountCost( relsize ) > 0  )
      {
        traverse( aa, astype( UnitAccount ).UnitAccountInPeriodForTime.UnitPeriod, up,
                  scope.Contains( up.UnitPeriodInOptimizerRun() ) )
        {
          if ( this.GetPeriodsFromPeriodTaskOperation()) 
          {
            period := up.Period_MP(); 
            traverse( up, PeriodTaskOperationInScope.Operation, operation ) 
            {
              ptqtyvar := program.PTQtyVariables().Get( operation, period );
      
              cost := operation.GetBaseCostPerQuantityForHour( aa, up );
              // Term:    -cost       * qtpfactor * PTQty variable
              // UoM: [Monetary/Unit] *    [-]    *    [Unit]
              tconst.NewTerm( -cost * operation.QuantityToProcessFactor() * scalefactor_periodtaskqty_tconst,
                              ptqtyvar );
            }
          }
          else
          {
            traverse( up, Unit.OperationForOptimizationInScope, operation ) 
            {
              ptqtyvar := program.PTQtyVariables().Find( operation, up.Period_MP() );
              // If the ptqtyvar is null then this combination of operation and period is not considered by the optimizer
              if( not isnull( ptqtyvar ) )
              {
                cost := operation.GetBaseCostPerQuantityForHour( aa, up );
                // Term:    -cost       * qtpfactor * PTQty variable
                // UoM: [Monetary/Unit] *    [-]    *    [Unit]
                tconst.NewTerm( -cost * operation.QuantityToProcessFactor() * scalefactor_periodtaskqty_tconst,
                                ptqtyvar );
              }
            }
          }
        }
      }
    }
  *]
  InterfaceProperties { Accessibility: 'Module' }
}