| 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' } | 
| } |