Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method InitConstraintsGoalsForTotalSlacks ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  const LibOpt_Scope scope, 
 | 
  const constcontent ProductInStockingPointInPeriodPlanningLeafs leafpispipsinrun, 
 | 
  const constcontent ProductInStockingPoint_MPs pispsinrun 
 | 
) const 
 | 
{ 
 | 
  Description: 'The constraint to compute the total slacks used in the algorithm.' 
 | 
  TextBody: 
 | 
  [* 
 | 
    // calculate penalty of using slack 
 | 
    // slackconst constraint UoM: Default 
 | 
    slackconst := program.TotalSlackConstraints().New(); 
 | 
    slackconst.Sense( '=' ); 
 | 
    slackconst.RHSValue( this.ScaleConstraintRHS( typeofexpression( slackconst ), 0.0 ) ); 
 | 
    // Term UoM: Default 
 | 
     
 | 
    slackconst.NewTerm( 1.0 * this.ScaleConstraintTerm( typeof( MPTotalSlackVariable ), typeofexpression( slackconst ) ), program.TotalSlackVariables().Get() ); 
 | 
     
 | 
    // TotalSupplyUser slack 
 | 
    // Currently, a higher weight than the demandslack is used, which will always force the optimizer to fulfill the user defined total supply 
 | 
    // Term UoM: Default 
 | 
    slackconst.NewTerm( -2.0 * this.ScaleConstraintTerm( typeof( MPTotalSlackUserSupplyVariable ), typeofexpression( slackconst ) ) 
 | 
                        , program.TotalSlackUserSupplyVariables().Get() ); 
 | 
     
 | 
    targetuom := this.MacroPlan().DefaultUnitOfMeasure(); 
 | 
           
 | 
    scalefactor_demandslack_const := this.ScaleConstraintTerm( typeof( MPDemandSlackVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_invpriorspec_const := this.ScaleConstraintTerm( typeof( MPInvQtySpecPriorToHorizonSlackVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_spinvoutofscope_const := this.ScaleConstraintTerm( typeof( MPSPInvOutOfScopeSlackVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_liminv_const := this.ScaleConstraintTerm( typeof( MPMetaLimitMaxInventoryPastHorizonSlackVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_maturationslack_const := this.ScaleConstraintTerm( typeof( MPMaturationSlackVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_operationinputgroupover_const := this.ScaleConstraintTerm( typeof( MPOperationInputGroupOverVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_operationinputgroupunder_const := this.ScaleConstraintTerm( typeof( MPOperationInputGroupUnderVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_operationinputsetover_const := this.ScaleConstraintTerm( typeof( MPOperationInputSetOverVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_operationinputsetunder_const := this.ScaleConstraintTerm( typeof( MPOperationInputSetUnderVariable ), typeofexpression( slackconst ) ); 
 | 
    scalefactor_shiftdurationslack_constr := this.ScaleConstraintTerm( typeof( MPShiftPatternDurationSlackVariable ), typeofexpression( slackconst ) ); 
 | 
     
 | 
     
 | 
    if( runcontext.UseCampaignSequenceOptimizer() and runcontext.UseCampaign() ) 
 | 
    { 
 | 
      vartotalcombislack := program.TotalCampaignSequencingCombiSlackVariables().Get();  
 | 
      slackconst.NewTerm( -1.0 * CapacityPlanningSuboptimizer::OptCampaignCombiSlackWeight(), vartotalcombislack );  // take absolute penalty of 1000 per combi sequence or coverage problem                                             
 | 
     
 | 
      scalefactor_overloadedvar_const := this.ScaleConstraintTerm( typeof( MPCampaignElementTypePeriodOverloadedStartVariable ), typeofexpression( slackconst ) );  
 | 
       
 | 
      traverse( scope.GetUnitPeriodInOptimizerRunConst(), Elements.OptCampaignUnitSubPeriod, ocusp ) 
 | 
      { 
 | 
        traverse( ocusp, OptCampaignCombiElement.OptCampaignElementType, ocet ) 
 | 
        { 
 | 
          varperiodoverloadstart := program.CampaignElementTypePeriodOverloadedStartVariables().Get( ocet, ocusp ); 
 | 
          varperiodoverloadmid := program.CampaignElementTypePeriodOverloadedMidVariables().Get( ocet, ocusp ); 
 | 
          varperiodoverloadend := program.CampaignElementTypePeriodOverloadedEndVariables().Get( ocet, ocusp ); 
 | 
           
 | 
          slackconst.NewTerm(  -1.0 * scalefactor_overloadedvar_const, varperiodoverloadstart ); 
 | 
          slackconst.NewTerm(  -1.0 * scalefactor_overloadedvar_const, varperiodoverloadmid ); 
 | 
          slackconst.NewTerm(  -1.0 * scalefactor_overloadedvar_const, varperiodoverloadend ); 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Penalty for using supply slack in balance constraint 
 | 
    traverse( leafpispipsinrun, Elements, pispip ) 
 | 
    { 
 | 
      uomconversion := pispip.ProductInStockingPoint_MP().DefaultUOMConversionFactor(); 
 | 
      // Term: -uomconversion  * DemandSlack variable 
 | 
      // UoM:  [PISP to Default] *        [PISP] 
 | 
      slackconst.NewTerm( -uomconversion * scalefactor_demandslack_const, 
 | 
                          program.DemandSlackVariables().Get( pispip ) ); 
 | 
     
 | 
      if ( runcontext.IsMetaIteration() )  
 | 
      {                                            
 | 
        slackvar := program.MetaLimitMaxInventoryPastHorizonSlackVariables().Find( pispip ); 
 | 
        if ( not isnull( slackvar ) )  
 | 
        { 
 | 
        slackconst.NewTerm( -uomconversion * scalefactor_liminv_const, slackvar );   
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    leafpispips := null( ProductInStockingPointInPeriodPlannings, constcontent, owning ); 
 | 
    pispips := this.GetPISPIPsForInventorySpecifications( scope, false, &leafpispips ); 
 | 
    startoptscope := runcontext.FirstPeriod_MP().Start();  
 | 
    traverse( pispips, Elements, pispip, pispip.Start() < startoptscope )  
 | 
    { 
 | 
      var := program.InvQtySpecPriorToHorizonSlackVariables().Find( pispip );  
 | 
      if ( not isnull( var ) ) 
 | 
      { 
 | 
        uomconversion := pispip.ProductInStockingPoint_MP().DefaultUOMConversionFactor(); 
 | 
        slackconst.NewTerm( -uomconversion * scalefactor_invpriorspec_const, var );  
 | 
      } 
 | 
    } 
 | 
     
 | 
    traverse( scope.GetStockingPointInPeriodInOptimizerRunConst(), Elements, spip,  
 | 
              not spip.StockingPoint_MP().IsPlannedInfinite() ) 
 | 
    { 
 | 
      nextspip :=  spip.GetNextPlanningSPIP();  
 | 
      if ( not runcontext.IsSmartPlan()  
 | 
           and not isnull( nextspip )  
 | 
           and not scope.Contains( nextspip.SPIPInOptimizerRun() ) )  
 | 
      { 
 | 
        slackconst.NewTerm( -1.0 * scalefactor_spinvoutofscope_const, program.SPInvOutOfScopeSlackVariables().Get( spip ) ); 
 | 
      } 
 | 
    } 
 | 
     
 | 
     
 | 
    // Penalty for using maturation slack in maturation constraint 
 | 
    traverse( pispsinrun, Elements, pisp, pisp.IsOptMaturation() )  
 | 
    { 
 | 
      pispips := pisp.GetPISPIPForShelfLifeOptimizer( scope );  
 | 
      traverse( pispips, Elements, pispip )  
 | 
      { 
 | 
        uomconversion := pispip.ProductInStockingPoint_MP().DefaultUOMConversionFactor(); 
 | 
        traverse( pisp, OutgoingShelfLifeDay, oslday )  
 | 
        { 
 | 
          slackconst.NewTerm( -uomconversion * scalefactor_maturationslack_const, program.MaturationSlackVariables().Get( pispip, oslday ) );  
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    traverse( pispsinrun, Elements, pisp, pisp.IsOptShelfLife() )  
 | 
    { 
 | 
      pispips := pisp.PISPInOptimizerRun().GetPISPIPForShelfLifeOptimizer( scope );  
 | 
      traverse( pispips, Elements, pispip )  
 | 
      { 
 | 
        uomconversion := pispip.ProductInStockingPoint_MP().DefaultUOMConversionFactor(); 
 | 
        traverse( pisp, IncomingShelfLifeDay, islday )  
 | 
        { 
 | 
          splitdemandslackvar := program.DemandSlackShelfLifeVariables().Get( pispip, islday );  
 | 
          slackconst.NewTerm( -uomconversion * scalefactor_demandslack_const, splitdemandslackvar );  
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Penalty for violating the operation input group min/max 
 | 
    traverse( scope.GetOperationInputGroupInOptimizerRunConst(), Elements, group )  
 | 
    { 
 | 
      operation := group.Operation(); 
 | 
     
 | 
      periods := this.GetPeriodsForOperation( scope, operation ); 
 | 
     
 | 
      traverse( periods, Elements, period ) 
 | 
      { 
 | 
        sourceuom := guard( operation.Unit().UnitOfMeasure_MP(), this.MacroPlan().DefaultUnitOfMeasure() ); 
 | 
        uomconversion := guard( sourceuom.GetConversionFactor( targetuom, null( Product_MP ) ), 1.0 ); 
 | 
     
 | 
        // Term: -uomconversion   * OperationInputGroupOver/Under variable 
 | 
        // UoM: [Unit to Default] *           [Unit] 
 | 
        traverse( group, OperationInput, input, 
 | 
                  input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( runcontext.IsPostProcessing() )  
 | 
                  ) 
 | 
        { 
 | 
          slackconst.NewTerm( -uomconversion * scalefactor_operationinputgroupover_const, 
 | 
                              program.OperationInputGroupOverVariables().Get( input, period ) ); 
 | 
          slackconst.NewTerm( -uomconversion * scalefactor_operationinputgroupunder_const, 
 | 
                              program.OperationInputGroupUnderVariables().Get( input, period ) ); 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Penalty for violating the operation input set min/max 
 | 
     
 | 
    traverse( scope.GetOperationInputSetInOptimizerRunConst(), Elements, set ) 
 | 
    { 
 | 
      operation := set.Operation(); 
 | 
      sourceuom := guard( set.UnitOfMeasure_MP(), this.MacroPlan().DefaultUnitOfMeasure() ); 
 | 
      periods := this.GetPeriodsForOperation( scope, operation ); 
 | 
     
 | 
      traverse( periods, Elements, period) 
 | 
      { 
 | 
        uomconversion := guard( sourceuom.GetConversionFactor( targetuom, null( Product_MP ) ), 1.0 ); 
 | 
     
 | 
        // Term: -uomconversion    * OperationInputGroupOver/Under variable 
 | 
        // UoM: [Input Set to Default]  *           [Unit] 
 | 
        slackconst.NewTerm( -uomconversion * scalefactor_operationinputsetover_const, program.OperationInputSetOverVariables().Get( set, period ) ); 
 | 
        slackconst.NewTerm( -uomconversion * scalefactor_operationinputsetunder_const, program.OperationInputSetUnderVariables().Get( set, period ) ); 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Penalty for violating the minimum shift pattern duration constraint 
 | 
    if( runcontext.UseShiftOptimization() ) 
 | 
    { 
 | 
      traverse( scope.GetUnitInOptimizerRunConst(), Elements, unit, unit.GetUseShiftOptimization() ) 
 | 
      { 
 | 
        traverse( unit.GetUnitForShiftOptimization(), Elements.UnitPeriod.astype( UnitPeriodTime ), up ) 
 | 
        { 
 | 
          traverse( up, Unit.UnitShiftPatternAllowed.ShiftPattern, sp ) 
 | 
          { 
 | 
            slackconst.NewTerm( -1.0 * scalefactor_shiftdurationslack_constr, program.ShiftPatternDurationSlackVariables().Get( sp, up ) ); 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |