Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method InitConstraintsForDependentDemandsInPISPIP ( 
 | 
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, 
 | 
  const RunContextForCapacityPlanning runcontext, 
 | 
  const LibOpt_Scope scope, 
 | 
  const constcontent ProductInStockingPointInPeriodPlanningLeafs leafpispipsinrun, 
 | 
  const constcontent ProductInTrips pitinrun, 
 | 
  Number threadnr 
 | 
) const 
 | 
{ 
 | 
  Description: 'Initialize the constraint to compute the total dependent demands in a pispip, also adding a slack (if utilize, penalize high cost) to prevent infeasibility when balancing the demands and supplies' 
 | 
  TextBody: 
 | 
  [* 
 | 
    constname := typeof( MPDependentDemandInPISPIPConstraint ); 
 | 
     
 | 
    scalefactor_dependentdemandinpispip_const := this.ScaleConstraintTerm( typeof( MPDependentDemandInPISPIPVariable ), constname ); 
 | 
    scalefactor_operationdemandqty_const := this.ScaleConstraintTerm( typeof( MPOperationDemandQtyVariable ), constname ); 
 | 
    scalefactor_tripdemandqty_const := this.ScaleConstraintTerm( typeof( MPTripDemandQtyVariable ), constname ); 
 | 
    scalefactor_rhs_const := this.ScaleConstraintRHS( constname, 1.0 ); 
 | 
    ispostprocessing := runcontext.IsPostProcessing();  
 | 
     
 | 
    getperiodsfromptop := this.GetPeriodsFromPeriodTaskOperation();  
 | 
     
 | 
    // To calculate the total dependent demand quantity in a pispip 
 | 
    traverse( leafpispipsinrun, Elements, pispip, CapacityPlanningSuboptimizer::GetThreadNr( this.ThreadAParameter(), this.ThreadBParameter(), pispip.PreThreadNr() ) = threadnr  ) 
 | 
    { 
 | 
      // const constraint UoM: PISP 
 | 
      const := program.DependentDemandInPISPIPConstraints().New( pispip ); 
 | 
      const.Sense( '=' ); 
 | 
     
 | 
      // Inventory supply that is greater than 0. If the supply is less than 0, it will be treated as a "must be fulfilled" demands 
 | 
      supplyquantity := ifexpr( pispip.InventorySupplyQuantity() < 0, pispip.InventorySupplyQuantity(), 0 ); 
 | 
     
 | 
      // RHS UoM: PISP 
 | 
      const.RHSValue( supplyquantity * scalefactor_rhs_const ); 
 | 
      // term UoM: PISP 
 | 
      const.NewTerm( -1.0 * scalefactor_dependentdemandinpispip_const, 
 | 
                     program.DependentDemandInPISPIPVariables().Get( pispip ) ); 
 | 
     
 | 
       
 | 
      // Dependent demands for operations 
 | 
      if ( not getperiodsfromptop ) // for performance if we know periodtasks are there we can traverse those and add to the constraints 
 | 
      { 
 | 
        period := pispip.Period_MP();  
 | 
        traverse( pispip, ProductInStockingPoint_MP.OperationInputAvailableForOptimization, input, 
 | 
                  scope.Contains( input.Operation().OperationInOptimizerRun() )  
 | 
                  and input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( ispostprocessing ) ) 
 | 
        { 
 | 
          operationdemandqtyvar := program.OperationDemandQtyVariables().Find( input, period ) 
 | 
          // If the variable does not exists, it indicates that this operation-period combination is not included in the optimizer run 
 | 
          // Therefore, this variable should then also not be added to this constraint 
 | 
          if( not isnull( operationdemandqtyvar ) ) 
 | 
          { 
 | 
            // Term UoM: PISP 
 | 
            const.NewTerm( scalefactor_operationdemandqty_const, operationdemandqtyvar ); 
 | 
          } 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    if ( getperiodsfromptop )  
 | 
    { 
 | 
      traverse(  scope.GetPeriodTaskOperationInOptimizerRunConst(), Elements.DependentDemand, dd )  
 | 
      { 
 | 
        pispip := dd.ProductInStockingPointInPeriodPlanningLeaf();  
 | 
        if ( CapacityPlanningSuboptimizer::GetThreadNr( this.ThreadAParameter(), this.ThreadBParameter(), pispip.PreThreadNr() ) = threadnr  )  
 | 
        { 
 | 
          input := dd.ProcessInput().astype( OperationInput );  
 | 
          if ( input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( ispostprocessing ) ) 
 | 
          { 
 | 
            period := pispip.Period_MP();  
 | 
            operationdemandqtyvar := program.OperationDemandQtyVariables().Get( input, period ) 
 | 
            { 
 | 
              const := program.DependentDemandInPISPIPConstraints().Get( pispip ); 
 | 
              // Term UoM: PISP 
 | 
              if ( const.Term( operationdemandqtyvar ).Coefficient() = 0 )  
 | 
              { 
 | 
                const.NewTerm( scalefactor_operationdemandqty_const, operationdemandqtyvar ); 
 | 
              }  
 | 
            } 
 | 
          } 
 | 
        } 
 | 
      }     
 | 
    } 
 | 
     
 | 
    traverse( pitinrun, Elements, pit )  
 | 
    { 
 | 
      pispip := pit.DeparturePISPIP();  
 | 
      if ( CapacityPlanningSuboptimizer::GetThreadNr( this.ThreadAParameter(), this.ThreadBParameter(), pispip.PreThreadNr() ) = threadnr )  
 | 
      { 
 | 
        const := program.DependentDemandInPISPIPConstraints().Get( pispip ); 
 | 
        const.NewTerm( scalefactor_tripdemandqty_const, program.TripDemandQtyVariables().Get( pit ) ); 
 | 
      } 
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |