Quintiq file version 2.0
|
#parent: #root
|
Method NextS (
|
Number periodNumber,
|
ProductInStockingPoint_MP pisp
|
) as owning ProbabilityDistribution
|
{
|
TextBody:
|
[*
|
// calculates the starting stock distrbution of given period, at given stockingpoint
|
// if leadtime to stockingpoint is 2 periods
|
// calculation starts at period - 2
|
// start by assuming that at period - 2 there is target left
|
// the loop through periods up to period-1, and at every period
|
// add expected demand and change in target, substract demand distribution and
|
// take maximum with 0, to not allow negative inventory
|
|
dsum := MEIO_Engine::GetZeroDistribution();
|
// if period - stockinpoint.leadtime is after start of planning horizon, we have target set a target that we can use
|
// based on the simulations, mp hardly ever reached the correct target, and interal service level tries to describe this
|
|
if( periodNumber > pisp.MEIO_Leadtime() )
|
{
|
startminleadpispip := pisp.GetPISPIPFromPeriodNumber( periodNumber - pisp.MEIO_Leadtime() );
|
dsum := MEIO_Engine::GetDiracDistribution( MEIO_Engine::GetInternalSeviceLevel() * startminleadpispip.MEIO_Target() );
|
}
|
//# in other cases we start with the target of the first period that we have set earlier (or manually in mp)
|
else
|
{
|
pispip := pisp.FirstPlanningPISPIP();
|
dsum := MEIO_Engine::GetDiracDistribution( pispip.TargetInQuantity() );
|
}
|
// we only really calculate anything if leaditme is >0, if leadimte =0 we dont need safetystock at all
|
if ( pisp.MEIO_Leadtime() > 0)
|
{
|
// we collect all the children of the stockingpoint (we will aggregate the demand from these)
|
listofnodes := MEIO_Engine::GetTreePISP( pisp ); //Traverse(stockingpoint, c('level'))
|
//#start period is leadtime ago or first period,
|
startperiod := maxvalue( periodNumber - pisp.MEIO_Leadtime(), 1 ); //(meio_R_internal_period-pisp.MEIO_Leadtime(), 1)
|
//endperiod is previous period or start period
|
endperiod := maxvalue(startperiod, periodNumber-1)
|
|
//if startperiod is endperiod we would only add the resupply of that and substract the demand
|
//in other cases we loop through all startperiod -> endperiod
|
|
// we will add the expected demand and substract the demand distribution
|
traverse( listofnodes, Elements, nodepisp )
|
{
|
standarddev := MEIO_Engine::GetDemandStandardDeviation( nodepisp, startperiod );
|
dsum := ProbabilityDistribution::Sum( dsum, NormalDistribution::Construct( 0.0, standarddev ), this.MEIO_Parameters().SampleSizeForDistributions() );
|
}
|
//# if there are other periods we do the same as for startperiod
|
for ( p:= startperiod + 1; p<= endperiod; p++ )
|
{
|
supply := 0.0;
|
|
// if period is before leadtime of the stockingpoint, we cannot control the supply anymore and thus we use the values from mp
|
if ( p <= pisp.MEIO_Leadtime() )
|
{
|
supply := maxvalue( pisp.GetPISPIPFromPeriodNumber( p ).NewSupplyQuantity(),
|
MEIO_Engine::GetDemandExpectedValue(pisp, p ) ) //);
|
}
|
//# in other cases we use as a supply the change in targets + expected demand
|
else
|
{
|
supply := maxvalue( MEIO_Engine::GetDemandExpectedValue( pisp, p )
|
+ pisp.GetPISPIPFromPeriodNumber( p ).MEIO_Target()
|
- pisp.GetPISPIPFromPeriodNumber( p - 1 ).MEIO_Target(),
|
0 );
|
}
|
// here we add the supply and substract the demand distribution
|
|
minusdemanddistr := MEIO_Engine::GetDemandDistributionTimesMinusOne( pisp, p ); // workaround because ProbabilityDistribution::Subtract gives verify errors
|
dsum := ProbabilityDistribution::Sum( dsum, minusdemanddistr, this.MEIO_Parameters().SampleSizeForDistributions() );
|
dsum := ProbabilityDistribution::Sum( dsum, DiscreteDistribution::Construct( supply ), this.MEIO_Parameters().SampleSizeForDistributions() );
|
// for the child nodes we do not add change in targets as supply, only the expected demands
|
if(p > pisp.MEIO_Leadtime() )
|
{
|
if(listofnodes.Size() > 1 )
|
{
|
traverse( listofnodes, Elements, node, not node = pisp )
|
{
|
nodeminusdemanddistr := MEIO_Engine::GetDemandDistributionTimesMinusOne( node, p )
|
dsum := ProbabilityDistribution::Sum( dsum, nodeminusdemanddistr, this.MEIO_Parameters().SampleSizeForDistributions() );
|
dsum := ProbabilityDistribution::Sum( dsum, DiscreteDistribution::Construct( MEIO_Engine::GetDemandExpectedValue( node, p ) ), this.MEIO_Parameters().SampleSizeForDistributions() );
|
} // traverse
|
} // if
|
} // if
|
} // for loop
|
} // if
|
|
// we don't allow negative inventory
|
dsum := ProbabilityDistribution::Max( dsum, MEIO_Engine::GetZeroDistribution(), this.MEIO_Parameters().SampleSizeForDistributions() );
|
|
return &dsum;
|
*]
|
}
|