Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForServiceLevel (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
const LibOpt_Scope scope,
|
const constcontent ProductInStockingPointInPeriodPlanningLeafs leafpispipsinrun
|
) const
|
{
|
Description: 'Initialize constraints forservice level'
|
TextBody:
|
[*
|
eis := this.MacroPlan().OptimizerMetaEIS();
|
if ( ( runcontext.IsMetaIteration()
|
and ( eis.ServiceLevelWeight() > 0 or eis.FulfillmentTargetWeight() > 0 ) )
|
or not runcontext.IsMetaIteration()
|
or this.IsFullPlanMetaPriorFocus() ) // for performance don't define if we don't have the kpi's in the strategy
|
{
|
constfromtargetname := typeof( MPServiceLevelFromTargetConstraint );
|
constfromsddetname := typeof( MPFulfillmentTargetFromSDQtyConstraint );
|
constfromsdstoname := typeof( MPServiceLevelFromSDQtyConstraint );
|
|
scalefactor_servicelevelqty_constfromtarget := this.ScaleConstraintTerm( typeof( MPFulfillmentTargetVariable ), constfromtargetname );
|
scalefactor_servicelevelqty_constfromsd_det := this.ScaleConstraintTerm( typeof( MPFulfillmentTargetVariable ), constfromsddetname );
|
scalefactor_servicelevelqty_constfromsd_sto := this.ScaleConstraintTerm( typeof( MPServiceLevelQtyVariable ), constfromsdstoname );
|
scalefactor_salesdemandqty_constfromsd_det := this.ScaleConstraintTerm( typeof( MPSalesDemandQtyVariable ), constfromsddetname );
|
scalefactor_salesdemandqty_constfromsd_sto := this.ScaleConstraintTerm( typeof( MPSalesDemandQtyVariable ), constfromsdstoname );
|
|
scalefactor_rhs_constfromtarget := this.ScaleConstraintRHS( constfromtargetname, 1.0 );
|
scalefactor_rhs_constfromsddet := this.ScaleConstraintRHS( constfromsddetname, 1.0 );
|
scalefactor_rhs_constfromsdsto := this.ScaleConstraintRHS( constfromsdstoname, 1.0 );
|
|
//
|
// step 1: created constraints
|
//
|
slbases := selectset( this,
|
MacroPlan.AllServiceLevelBase,
|
sl,
|
sl.GetIsInOptimizerRun( scope ) );
|
traverse( slbases, Elements, sl )
|
{
|
vardummy := program.NewVariable( 'OptimizerConstantTerm', sl ); // workaround for const - cant use attribute
|
vardummy.Enabled( false );
|
this.StoreValueInVariable( vardummy, 0.0 );
|
|
// If this is a fulfillment goal related service level then add the related constraints
|
if( sl.IsUsedForPlanningFulfillmentSystem() )
|
{
|
// two constraints are added:
|
//
|
// constfromtarget, which specifies the fulfilled quantity(sl) is <= target% * total demand qty (sl) (*)
|
//
|
// constfromsd, which specifies fulfilled quantity (sl) <= total demand qty ( sl)
|
|
// constraints to calculate fulfilled part of the fulfillmentgoal
|
// plannedservicelevel <= target% * sum of sd.Quantity
|
// const constraint UoM: Default
|
constfromtarget := program.ServiceLevelFromTargetConstraints().New( sl );
|
constfromtarget.Sense( '<=' );
|
|
// Term UoM: Default
|
constfromtarget.NewTerm( 1.0 * scalefactor_servicelevelqty_constfromtarget, program.FulfillmentTargetVariables().Get( sl ) );
|
|
// ServiceLevel <= sum of SalesDemandQty
|
// const constraint UoM: Default
|
constfromsd := program.FulfillmentTargetFromSDQtyConstraints().New( sl );
|
constfromsd.Sense( '<=' );
|
constfromsd.RHSValue( 0.0 );
|
|
// Term UoM: Default
|
constfromsd.NewTerm( 1.0 * scalefactor_servicelevelqty_constfromsd_det, program.FulfillmentTargetVariables().Get( sl ) );
|
constfromsd.Enabled( false ); // enable once we add a term
|
}
|
// Else, if this is a inventory optimization related service level, add the related constraints
|
else if( sl.IsUsedForSafetyStockCalculation() )
|
{
|
// ServiceLevel <= SUM( SalesDemandQty ) + SUM ( DisaggregatedSalesDemandQty )
|
// const constraint UoM: Default
|
constr := program.ServiceLevelFromSDQtyConstraints().New( sl );
|
constr.Sense( '<=' );
|
constr.RHSValue( 0.0 );
|
|
// Term UoM: Default
|
constr.NewTerm( 1.0 * scalefactor_servicelevelqty_constfromsd_sto , program.ServiceLevelQtyVariables().Get( sl ) );
|
constr.Enabled( false ); // enable once we add a term
|
}
|
}
|
|
//
|
// step 2: add terms to constraint
|
//
|
//bsdips := selectset( this, MacroPlan.SalesDemand.AsMasterSalesDemand, bsdip, true, true );
|
bsdips := selectset( leafpispipsinrun,
|
Elements.PlanningBaseSalesDemandInPeriodForOptimization,
|
bsdip,
|
true,
|
not bsdip.MasterSalesDemand().IsExcludedFromFulfillmentKPI() );
|
this.AddTermsToServiceLevelConstraints( program,
|
bsdips,
|
scalefactor_salesdemandqty_constfromsd_det,
|
scalefactor_salesdemandqty_constfromsd_sto,
|
scope );
|
// step 3: set computed rhs for constraint
|
traverse( slbases, Elements, sl )
|
{
|
opt_constant_term := program.Variable( 'OptimizerConstantTerm', sl ).UpperBound(); // workaround because cannot write to attribute
|
outofscopequantity := sl.TotalFulfilledQuantity() - opt_constant_term; // latter term set in AddTermsToServiceLevelConstraint
|
if( sl.IsUsedForPlanningFulfillmentSystem() )
|
{
|
constfromtarget := program.ServiceLevelFromTargetConstraints().Get( sl );
|
desiredservicelevelpercentage := sl.TargetPercentage();
|
rhsfromtarget := maxvalue( 0.0, sl.TotalDemandQuantity() * ( desiredservicelevelpercentage / 100.0 ) ); //prevent negative goal
|
// RHS UoM: Default
|
constfromtarget.RHSValue( rhsfromtarget * scalefactor_rhs_constfromtarget ); // poses the upper bound mentioned in (*)
|
|
constrfromsd := program.FulfillmentTargetFromSDQtyConstraints().Get( sl );
|
|
newrhs := this.GetConstraintRHS( constrfromsd, scalefactor_rhs_constfromsddet ) + outofscopequantity; // variable is added on the right, so we *add* constantterm to the RHS
|
constrfromsd.RHSValue( newrhs * scalefactor_rhs_constfromsddet );
|
}
|
else
|
{
|
constr := program.ServiceLevelFromSDQtyConstraints().Get( sl );
|
newrhs := this.GetConstraintRHS( constr, scalefactor_rhs_constfromsdsto ) + outofscopequantity; // variable is added on the right, so we *add* constantterm to the RHS
|
constr.RHSValue( newrhs * scalefactor_rhs_constfromsdsto );
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|