Quintiq file version 2.0
|
#parent: #root
|
Method AdditionalConstraintMaxInventory (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const LibOpt_Scope scope,
|
const RunContextForCapacityPlanning runcontext,
|
const RunContextMeta runcontextmeta
|
) const
|
{
|
TextBody:
|
[*
|
if ( runcontext.IsMetaIteration() and runcontextmeta.OptionUseAdditonalMaxInventoryConstraint() )
|
{
|
constname := typeof( MPMetaLimitMaxInventoryPastHorizonConstraint );
|
scalefactor_invqty_const := this.ScaleConstraintTerm( typeof( MPInvQtyVariable ), constname );
|
scalefactor_slack_const := this.ScaleConstraintTerm( typeof( MPMetaLimitMaxInventoryPastHorizonSlackVariable ), constname );
|
scalefactor_rhs_const := this.ScaleConstraintRHS( constname, 1.0 );
|
|
traverse( scope.GetProductInStockingPointInOptimizerRunConst(), Elements.LatestPISPIPInScope, pispip )
|
{
|
smallestgap := pispip.GetSmallestMaxGap();
|
|
// we only allow the inventory level to increase by smallest gap at the pispip so we do not introduce additional constraints.
|
currentlevelincludesmaxinventorylevelgoal := runcontext.WeightLevelNonFinancial().MaximumInventoryLevel() <= this.FocusLevel()
|
and runcontext.WeightLevelNonFinancial().MaximumInventoryLevelWeight() > 0.0;
|
if ( smallestgap.IsFinite() and currentlevelincludesmaxinventorylevelgoal )
|
{
|
|
constr := program.MetaLimitMaxInventoryPastHorizonConstraints().New( pispip );
|
slackvar := program.MetaLimitMaxInventoryPastHorizonSlackVariables().New( pispip );
|
constr.Sense( '<=' );
|
constr.NewTerm( -1.0 * scalefactor_slack_const, slackvar );
|
|
|
pispipinvend := pispip.InventoryLevelEnd();
|
rhs := maxvalue( 0.0, pispipinvend + smallestgap );
|
// We only update the RHS if the quantity is larger than the feasibility tolerance to avoid numerical instability
|
rhs := ifexpr( abs( rhs * scalefactor_rhs_const ) >= this.SmallestFeasibilityTolerance(), rhs, 0.0 ) ;
|
constr.RHSValue( rhs * scalefactor_rhs_const );
|
|
// Term UoM: PISP
|
if ( pispip.IsLeafPlanning() )
|
{
|
constr.NewTerm( 1.0 * scalefactor_invqty_const, program.InvQtyVariables().Get( pispip ) );
|
}
|
else
|
{
|
this.AddTermsToInventorySpecificationHighLevelConstraint( program, constr, pispip, scope, scalefactor_invqty_const, scalefactor_rhs_const );
|
}
|
|
lowerlimitconstr := program.FindConstraint( CapacityPlanningSuboptimizer::ConstraintNameLowerBoundLastPeriodInventory(), pispip ); // need to be consistent with this lower bound due to pre solve numerical issues
|
if ( not isnull( lowerlimitconstr ) )
|
{
|
lowerlimit := -lowerlimitconstr.RHSValue();
|
upperlimit := constr.RHSValue();
|
if ( lowerlimit >= upperlimit )
|
{
|
lowerlimitconstr.RHSValue( 1000.0 ); // work around epsilon logic
|
lowerlimitconstr.RHSValue( -upperlimit );
|
}
|
}
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|