Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForInventorySpecificationHighLevel (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const LibOpt_Scope scope,
|
const RunContextForCapacityPlanning runcontext,
|
const constcontent ProductInStockingPointInPeriodPlannings pispipsinrun
|
) const
|
{
|
Description: 'adds constraints for inventory target and minimum inventory, for high level products that are aggregates over lower level products'
|
TextBody:
|
[*
|
// These are high level constraints, so leaf pisps should not be considered
|
|
targetconstname := typeof( MPTargetInventoryLevelConstraint );
|
minconstname := typeof( MPMinInventoryLevelConstraint );
|
maxconstname := typeof( MPMaxInventoryLevelConstraint );
|
|
scalefactor_invqtyundertarget_targetconst := this.ScaleConstraintTerm( typeof( MPInvQtyUnderTargetVariable ), targetconstname );
|
scalefactor_mininvqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinInvQtyUnderVariable ), minconstname );
|
scalefactor_maxinvqtyover_maxconst := this.ScaleConstraintTerm( typeof( MPMaxInvQtyOverVariable ), maxconstname );
|
|
scalefactor_rhs_targetconst := this.ScaleConstraintRHS( targetconstname, 1.0 );
|
scalefactor_rhs_minconst := this.ScaleConstraintRHS( minconstname, 1.0 );
|
scalefactor_rhs_maxconst := this.ScaleConstraintRHS( maxconstname, 1.0 );
|
|
demandfulfillmentinpispip_varname := typeof( MPDemandFulfillmentInPISPIPVariable );
|
demandfulfillmentinpispip_constrname := typeof( MPDemandFulfillmentInPISPIPConstraint );
|
// Get scaling factors. For performance we dont want to recompute this for each pispip
|
scalefactor_demandfulfillmentinpispip_constr := this.ScaleConstraintTerm( demandfulfillmentinpispip_varname, demandfulfillmentinpispip_constrname );
|
scalefactor_rhs_constr := this.ScaleConstraintRHS( demandfulfillmentinpispip_constrname, 1.0 );
|
|
scalefactor_invqty_constr_targetconst := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), targetconstname );
|
scalefactor_rhs_constr_targetconst := this.ScaleConstraintRHS( targetconstname, 1.0 );
|
|
scalefactor_invqty_constr_minconst := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), minconstname );
|
scalefactor_rhs_constr_minconst := this.ScaleConstraintRHS( minconstname, 1.0 );
|
|
scalefactor_invqty_constr_maxconst := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), maxconstname );
|
scalefactor_rhs_constr_maxconst := this.ScaleConstraintRHS( maxconstname, 1.0 );
|
|
leafpispips := null( ProductInStockingPointInPeriodPlannings, constcontent, owning );
|
pispips := this.GetPISPIPsForInventorySpecifications( scope, false, &leafpispips )
|
traverse( pispips, Elements.astype( ProductInStockingPointInPeriodPlanningNonLeaf ), pispip, not pispip.IsLeafPlanning() )
|
{
|
// Penalty of not fulfilling the target
|
if( pispip.GetHasTargetInventory()
|
and (pispip.GetHasTargetInDays() or scope.Contains( pispip.PISPIPInOptimizerRun() ) ) )
|
{
|
rhs := ifexpr( not pispip.GetHasTargetInDays(), pispip.TargetInQuantity(), 0.0 ); // If specified in days, the target inventory is calculated based on next period demand fulfillment
|
// targetconst constraint UoM: target PISP
|
targetconst := program.TargetInventoryLevelConstraints().New( pispip );
|
// RHS UoM: target PISP
|
targetconst.RHSValue( rhs * scalefactor_rhs_targetconst );
|
targetconst.Sense( '>=' );
|
// Term UoM: SP
|
targetconst.NewTerm( 1.0 * scalefactor_invqtyundertarget_targetconst, program.InvQtyUnderTargetVariables().Get( pispip ) );
|
// sum of inventory quantity of active pispips
|
this.AddTermsToInventorySpecificationHighLevelConstraint( program, targetconst, pispip, scope, scalefactor_invqty_constr_targetconst, scalefactor_rhs_constr_targetconst );
|
}
|
|
// Penalty of not reaching the minimum inventory level
|
if( pispip.GetHasMinLevel()
|
and ( pispip.InventorySpecification().HasMinLevelInDays() or scope.Contains( pispip.PISPIPInOptimizerRun() ) ) )
|
{
|
rhs := ifexpr( not pispip.GetHasMinLevelInDays(), pispip.MinLevelInQuantity(), 0.0 ); // If specified in days, the target inventory is calculated based on next period demand fulfillment
|
// minconst constraint UoM: target PISP
|
minconst := program.MinInventoryLevelConstraints().New( pispip );
|
minconst.Sense( '>=' );
|
// RHS UoM: target PISP
|
minconst.RHSValue( rhs * scalefactor_rhs_minconst );
|
// Term UoM: target PISP
|
minconst.NewTerm( 1.0 * scalefactor_mininvqtyunder_minconst, program.MinInvQtyUnderVariables().Get( pispip ) );
|
// sum of inventory quantity of active pispips
|
this.AddTermsToInventorySpecificationHighLevelConstraint( program, minconst, pispip, scope, scalefactor_invqty_constr_minconst, scalefactor_rhs_constr_minconst );
|
}
|
|
// Penalty of exceeding the maximum inventory level
|
if( pispip.GetHasMaxLevel()
|
and ( pispip.InventorySpecification().HasMaxLevelInDays() or scope.Contains( pispip.PISPIPInOptimizerRun() ) ) )
|
{
|
rhs := ifexpr( not pispip.GetHasMaxLevelInDays(), pispip.MaxLevelInQuantity(), 0.0 ); // If specified in days, the target inventory is calculated based on next period demand fulfillment
|
// maxconst constraint UoM: target PISP
|
maxconst := program.MaxInventoryLevelConstraints().New( pispip );
|
maxconst.Sense( '<=' );
|
// RHS UoM: target PISP
|
maxconst.RHSValue( rhs * scalefactor_rhs_maxconst );
|
// Term UoM: target PISP
|
maxconst.NewTerm( -1.0 * scalefactor_maxinvqtyover_maxconst, program.MaxInvQtyOverVariables().Get( pispip ) );
|
// sum of inventory quantity of active pispips
|
this.AddTermsToInventorySpecificationHighLevelConstraint( program, maxconst, pispip, scope, scalefactor_invqty_constr_maxconst, scalefactor_rhs_constr_maxconst );
|
}
|
|
// For inventory specifications in days, add terms for the target / min / max inventory level
|
// based on the fulfilled sales demands and dependent demands on next periods
|
this.AddTermsToInventorySpecificationConstraints( program, pispip, scope, scalefactor_demandfulfillmentinpispip_constr, scalefactor_rhs_constr );
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|