Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForUserTotalSupply (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
const LibOpt_Scope scope,
|
const constcontent ProductInStockingPointInPeriodPlannings pispipsinrun
|
) const
|
{
|
Description:
|
[*
|
Initialize the constraint related to the total (user) supply in a base PISPIP
|
This constraint is used in the Smart plan functionality.
|
*]
|
TextBody:
|
[*
|
// For each PISPIP, if it has a total user supply and it should be considered in this run
|
// Then the sum of all supply into this pispip ( Inventory Supply, TripNewSupply, OperationNewSupply and InvQty of the previous period)
|
// should be equal to the total supply user
|
|
if( runcontext.GetConsiderTotalUserSupply( scope ) )
|
{
|
pispipsforconstraint := runcontext.GetPISPISPForUserSupplyConstraint( scope, pispipsinrun );
|
|
constrname := typeof( MPUserTotalSupplyConstraint );
|
|
scalefactor_invqty_constr := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), constrname );
|
scalefactor_tripnewsupply_constr := this.ScaleConstraintTerm( typeof( MPTripNewSupplyVariable ), constrname );
|
scalefactor_usertotalsupplyover_constr := this.ScaleConstraintTerm( typeof( MPUserTotalSupplyOverVariable ), constrname );
|
scalefactor_usertotalsupplyunder_constr := this.ScaleConstraintTerm( typeof( MPUserTotalSupplyUnderVariable ), constrname );
|
scalefactor_periodtaskqty_constr := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), constrname );
|
|
scalefactor_rhs_constr := this.ScaleConstraintRHS( constrname, 1.0 );
|
|
traverse( pispipsforconstraint, Elements, pispip )
|
{
|
// constr constraint UoM: PISP
|
constr := program.UserTotalSupplyConstraints().New( pispip );
|
constr.Sense( '=' );
|
|
rhs := pispip.TotalSupplyUser() - pispip.InventorySupplyQuantity();
|
// RHS UoM: PISP
|
constr.RHSValue( rhs * scalefactor_rhs_constr );
|
|
previouspispip := pispip.PreviousPlanningPISPIP();
|
|
// Inventory end of the previous period
|
if( not isnull( previouspispip ) )
|
{
|
// If the previous pipsip is part of the optimizer run, add the inventory quantity variable to the constraint
|
if( scope.Contains( previouspispip.PISPIPInOptimizerRun() ) )
|
{
|
// Term UoM: PISP
|
constr.NewTerm( scalefactor_invqty_constr,
|
program.InvQtyVariables().Get( previouspispip ) );
|
if ( pispip.ProductInStockingPoint_MP().IsOptShelfLife() )
|
{
|
constr.NewTerm( -scalefactor_invqty_constr, program.ExpiredVariables().Get( pispip ) );
|
}
|
}
|
// Otherwise update the RHS to include the frozen inventory end
|
else
|
{
|
newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) - previouspispip.InventoryLevelEnd();
|
constr.RHSValue( newrhs * scalefactor_rhs_constr );
|
}
|
}
|
|
// New supplies from trips
|
traverse( pispip, astype(ProductInStockingPointInPeriodPlanningLeaf ).NewSupply.ProductInTrip, productintrip )
|
{
|
// If the productintrip is part of the optimizer run, add its tripnewsupply quantity variable to the constraint
|
if( scope.Contains( productintrip.ProductInTripInOptimizerRun() ) )
|
{
|
// Term UoM: Output PISP
|
constr.NewTerm( scalefactor_tripnewsupply_constr, program.TripNewSupplyVariables().Get( productintrip ) );
|
}
|
// Otherwise update the RHS with the frozen productintrip supply quantity
|
else
|
{
|
newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) - productintrip.Quantity();
|
constr.RHSValue( newrhs * scalefactor_rhs_constr );
|
}
|
}
|
|
// New supplies from operations
|
traverse( pispip, ProductInStockingPoint_MP.OperationOutputAvailableForOptimization, output )
|
{
|
// Term UoM: Output PISP
|
this.AddConstraintForOperationNewSupplies( output, pispip.Period_MP(), null( Period_MP ),
|
program, 1.0, constr, scalefactor_periodtaskqty_constr, scope );
|
|
// If there is a new supply of this output in this pispips that is not part of the optimization run, then this new supply should be subtracted from the RHS
|
// Comment from MvE: this should follow the summing of RHS new supply in GetInventoryRHSForBalanceConstraint
|
traverse( output, NewSupply, newsupply,
|
newsupply.PeriodTask_MP().UnitPeriod().Period_MP() = pispip.Period_MP()
|
and( not scope.Contains( newsupply.PeriodTaskOperation().PeriodTaskOperationInOptimizerRun() )
|
and not scope.Contains( newsupply.PeriodTask_MP().UnitPeriod().UnitPeriodInOptimizerRun() ) ) // If this is a regular optimizer run, the PTOperations are not added to the algorithm run
|
or ( ifexpr( runcontext.IsSmartPlanForPeriodTask(), not newsupply.GetHasAllDDInOptimizerScope( runcontext, scope ), false ) ) // Only check this for period task smart plan
|
)
|
{
|
newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constr ) - newsupply.Quantity();
|
constr.RHSValue( newrhs * scalefactor_rhs_constr );
|
}
|
}
|
|
// Add slack variables
|
// Term UoM: Output PISP
|
constr.NewTerm( -1.0 * scalefactor_usertotalsupplyover_constr, program.UserTotalSupplyOverVariables().Get( pispip ) );
|
constr.NewTerm( scalefactor_usertotalsupplyunder_constr, program.UserTotalSupplyUnderVariables().Get( pispip ) );
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|