Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForDependentDemandsInPISPIPForShelfLife (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
const LibOpt_Scope scope,
|
const constcontent ProductInStockingPoint_MPs pispsinrun
|
) const
|
{
|
Description: 'Initialize the constraint to compute the total dependent demands in a pispip for shelflife, also adding a slack (if utilize, penalize high cost) to prevent infeasibility when balancing the demands and supplies'
|
TextBody:
|
[*
|
constname := typeof( MPDependentDemandInPISPIPConstraint );
|
|
scalefactor_dependentdemandinpispip_const := this.ScaleConstraintTerm( typeof( MPDependentDemandInPISPIPVariable ), constname );
|
scalefactor_operationdemandqty_const := this.ScaleConstraintTerm( typeof( MPOperationDemandQtyVariable ), constname );
|
scalefactor_tripdemandqty_const := this.ScaleConstraintTerm( typeof( MPTripDemandQtyVariable ), constname );
|
|
scalefactor_rhs_const := this.ScaleConstraintRHS( constname, 1.0 );
|
|
// To calculate the total dependent demand quantity in a pispip
|
traverse( pispsinrun, Elements, pisp, pisp.IsOptMaturation() or pisp.IsOptShelfLife() )
|
{
|
pispipsforstockingpoint_shelflifeormaturation := pisp.PISPInOptimizerRun().GetPISPIPForShelfLifeOptimizer( scope ); // included extra pispips prior to optimizer scope
|
traverse( pispipsforstockingpoint_shelflifeormaturation, Elements, pispip )
|
{
|
traverse( pisp, OutgoingShelfLifeDay, oslday )
|
{
|
// Defining DD(pispip, oslday). Note we don't have a variable for this but we use sum_i DD(pispip, i, osld) and this is what we want to constrain
|
// const constraint UoM: PISP
|
const := program.DependentDemandInPISPIPShelfLifeConstraints().New( pispip, oslday );
|
const.Sense( '=' );
|
|
// Inventory supply that is greater than 0. If the supply is less than 0, it will be treated as a "must be fulfilled" demands. This is considered to have outgoing leadtime 0
|
supplyquantity := ifexpr( pispip.InventorySupplyQuantity() < 0 and oslday.ShelfLifeDays() = 0 and not oslday.IsZeroShelfLifeDaysForTrips(), pispip.InventorySupplyQuantity(), 0 );
|
|
// RHS UoM: PISP
|
const.RHSValue( supplyquantity * scalefactor_rhs_const );
|
// term UoM: PISP
|
traverse( pisp, IncomingShelfLifeDay, islday )
|
{
|
const.NewTerm( -1.0 * scalefactor_dependentdemandinpispip_const,
|
program.DependentDemandInPISPIPShelfLifeVariables().Get( pispip, islday, oslday ) );
|
}
|
// Dependent demands for operations - considered outgoing leadtime 0. Note we distinguish between 0 outgoing leadtime for operations and trips using the attribute IsZeroShelfLifeDaysForTrips
|
if ( oslday.ShelfLifeDays() = 0 and not oslday.IsZeroShelfLifeDaysForTrips() )
|
{
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) ) // same transaction, equivalent to scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
ispostprocessing := runcontext.IsPostProcessing();
|
traverse( pispip, ProductInStockingPoint_MP.OperationInputAvailableForOptimization, input,
|
guard( scope.Contains( input.Operation().OperationInOptimizerRun() ), false )
|
and input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( ispostprocessing ) )
|
{
|
operationdemandqtyvar := program.OperationDemandQtyVariables().Find( input, pispip.Period_MP() )
|
|
// If the variable does not exists, it indicates that this operation-period combination is not included in the optimizer run
|
// Therefore, this variable should then also not be added to this constraint
|
if( not isnull( operationdemandqtyvar ) )
|
{
|
// Term UoM: PISP
|
const.NewTerm( 1.0 * scalefactor_operationdemandqty_const, operationdemandqtyvar );
|
}
|
}
|
}
|
else // we have pispips prior to the optimizer scope where we just want to set constant values from the model
|
{
|
operationdemandfulfilled := pispip.DependentDemandNonTripFulfilledQuantity();
|
const.RHSValue( const.RHSValue() - scalefactor_rhs_const * operationdemandfulfilled );
|
}
|
}
|
|
// Dependent demands for trips
|
// Only consider those productintrips that are part of the optimizer run
|
if ( oslday.ShelfLifeDays() > 0 or oslday.IsZeroShelfLifeDaysForTrips() )
|
{
|
if ( scope.Contains( pispip.PISPIPInOptimizerRun() ) ) // same transaction, equivalent scope.Contains( pispip.PISPIPInOptimizerRun() ) )
|
{
|
traverse( pispip, astype( ProductInStockingPointInPeriodPlanningLeaf ).DependentDemand.ProductInTrip, productintrip,
|
scope.Contains( productintrip.ProductInTripInOptimizerRun() )
|
and productintrip.Trip().GetShelfLifeAgeToAdd() = oslday.ShelfLifeDays()
|
)
|
{
|
// Term UoM: PISP
|
const.NewTerm( 1.0 * scalefactor_tripdemandqty_const, program.TripDemandQtyVariables().Get( productintrip ) );
|
}
|
}
|
else
|
{
|
ddoutgoingtrip := sum( pispip,
|
Demand_MP.astype( DependentDemand ),
|
dd,
|
guard( dd.ProductInTrip().Trip().GetShelfLifeAgeToAdd() = oslday.ShelfLifeDays(), false ), dd.Quantity() );
|
const.RHSValue( const.RHSValue() - scalefactor_rhs_const * ddoutgoingtrip );
|
}
|
}
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|