Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForInventorySpecification (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const LibOpt_Scope scope,
|
const RunContextForCapacityPlanning runcontext,
|
const constcontent ProductInStockingPointInPeriodPlannings pispipsinrun
|
) const
|
{
|
Description: 'The constraint for target inventory on the active pispip'
|
TextBody:
|
[*
|
|
targetconstname := typeof( MPTargetInventoryLevelConstraint );
|
minconstname := typeof( MPMinInventoryLevelConstraint );
|
maxconstname := typeof( MPMaxInventoryLevelConstraint );
|
|
scalefactor_targetinvqty_targetconst := this.ScaleConstraintTerm( typeof( MPTargetInvQtyVariable ), targetconstname );
|
scalefactor_invqtyundertarget_targetconst := this.ScaleConstraintTerm( typeof( MPInvQtyUnderTargetVariable ), targetconstname );
|
scalefactor_invqty_minconst := this.ScaleConstraintTerm( typeof( MPTargetInvQtyVariable ), minconstname );
|
scalefactor_mininvqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinInvQtyUnderVariable ), minconstname );
|
scalefactor_invqty_maxconst := this.ScaleConstraintTerm( typeof( MPTargetInvQtyVariable ), maxconstname );
|
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 );
|
|
leafpispips := null( ProductInStockingPointInPeriodPlannings, constcontent, owning );
|
pispips := this.GetPISPIPsForInventorySpecifications( scope, true, &leafpispips );
|
traverse( pispips, Elements.astype( ProductInStockingPointInPeriodPlanningLeaf ), pispip )
|
{
|
// Penalty of not fulfilling the target
|
if( pispip.GetTargetUnderDefined( scope, runcontext ) )
|
{
|
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: PISP
|
targetconst := program.TargetInventoryLevelConstraints().New( pispip );
|
targetconst.Sense( '=' );
|
|
// Term UoM: PISP
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
targetconst.NewTerm( 1.0 * scalefactor_targetinvqty_targetconst, program.TargetInvQtyVariables().Get( pispip ) );
|
}
|
else // pispips is prior to scope, but still needs to be considered because it has a target in days that is affected
|
{
|
targetconst.Sense( '>=' );
|
rhs := rhs - pispip.InventoryLevelEnd();
|
}
|
// Term UoM: PISP
|
targetconst.NewTerm( 1.0 * scalefactor_invqtyundertarget_targetconst, program.InvQtyUnderTargetVariables().Get( pispip ) );
|
|
// RHS UoM: PISP
|
targetconst.RHSValue( rhs * scalefactor_rhs_targetconst );
|
}
|
|
// Penalty of not reaching the minimum inventory level
|
if( pispip.GetMinUnderDefined( scope, runcontext ) )
|
{
|
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: PISP
|
minconst := program.MinInventoryLevelConstraints().New( pispip );
|
minconst.Sense( '>=' );
|
// Term UoM: PISP
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
minconst.NewTerm( 1.0 * scalefactor_invqty_minconst, program.InvQtyVariables().Get( pispip ) );
|
}
|
else
|
{
|
rhs := rhs - pispip.InventoryLevelEnd();
|
}
|
// Term UoM: PISP
|
minconst.NewTerm( 1.0 * scalefactor_mininvqtyunder_minconst, program.MinInvQtyUnderVariables().Get( pispip ) );
|
|
// RHS UoM: PISP
|
minconst.RHSValue( rhs * scalefactor_rhs_minconst );
|
}
|
|
// Penalty of exceeding the maximum inventory level
|
if( pispip.GetMaxOverDefined( scope, runcontext ) )
|
{
|
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: PISP
|
maxconst := program.MaxInventoryLevelConstraints().New( pispip );
|
maxconst.Sense( '<=' );
|
|
// Term UoM: PISP
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
maxconst.NewTerm( 1.0 * scalefactor_invqty_maxconst, program.InvQtyVariables().Get( pispip ) );
|
}
|
else
|
{
|
rhs := rhs - pispip.InventoryLevelEnd();
|
}
|
// Term UoM: PISP
|
maxconst.NewTerm( -1.0 * scalefactor_maxinvqtyover_maxconst, program.MaxInvQtyOverVariables().Get( pispip ) );
|
|
// RHS UoM: PISP
|
maxconst.RHSValue( rhs * scalefactor_rhs_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
|
// Get variable names
|
demandfulfillmentinpispip_varname := typeof( MPDemandFulfillmentInPISPIPVariable );
|
// Get constraint namea
|
demandfulfillmentinpispip_constrname := typeof( MPDemandFulfillmentInPISPIPConstraint );
|
// Get scaling factors - for performance we dont want to recompute for each pispip
|
scalefactor_demandfulfillmentinpispip_constr := this.ScaleConstraintTerm( demandfulfillmentinpispip_varname, demandfulfillmentinpispip_constrname );
|
scalefactor_rhs_constr := this.ScaleConstraintRHS( demandfulfillmentinpispip_constrname, 1.0 );
|
this.AddTermsToInventorySpecificationConstraints( program, pispip, scope, scalefactor_demandfulfillmentinpispip_constr, scalefactor_rhs_constr );
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|