Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForOperationDependentDemands (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
const LibOpt_Scope scope,
|
Number threadnr
|
) const
|
{
|
Description: 'Initialize constraints for dependent demands for operations which does not have an input group'
|
TextBody:
|
[*
|
// dependent demand quantity of input products = pt quantity * factor * relative duration.
|
// relative duration = 1 if there is no pre-processing.
|
// 0 < relative duration <= 1 if there is pre-processing.
|
|
constddqtyname := typeof( MPOperationDependentDemandQtyConstraint );
|
constddpartialname := typeof( MPPartialOperationDependentDemandQtyConstraint );
|
|
scalefactor_operationdemandqty_constddqty := this.ScaleConstraintTerm( typeof( MPOperationDemandQtyVariable ), constddqtyname );
|
scalefactor_periodtask_constddqty := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), constddqtyname );
|
|
scalefactor_partialoperationdemandqty_constddpartial := this.ScaleConstraintTerm( typeof( MPPartialOperationDemandQtyVariable ), constddpartialname );
|
scalefactor_periodtask_constddpartial := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), constddpartialname );
|
|
usingproportialleadtimelogic := this.MacroPlan().GlobalParameters_MP().OperationLeadTimeLogic() = Translations::MP_GlobalParameter_LeadTimeLogic_Proportional()
|
|
traverse( scope.GetOperationInOptimizerRunConst(), Elements, operation, CapacityPlanningSuboptimizer::GetThreadNr( this.ThreadAParameter(), this.ThreadBParameter(), operation.PreThreadNr() ) = threadnr )
|
{
|
if ( operation.HasLeadTime() and this.GetPeriodsFromPeriodTaskOperation() )
|
{
|
traverse( operation, PeriodTaskOperationInScope.DependentDemand, dd )
|
{
|
input := dd.ProcessInput().astype( OperationInput );
|
ddperiod := dd.ProductInStockingPointInPeriodPlanningLeaf().Period_MP();
|
|
if ( input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( runcontext.IsPostProcessing() ) )
|
{
|
pispipperiods := construct( Period_MPs, constcontent );
|
pispipperiods.Add( ddperiod );
|
scaling := guard( input.Operation().OutputQuantity(), 1.0 ); // multiply out the denominator of OperationInput.Factor for better scaling
|
if ( scaling = 0.0 )
|
{
|
scaling := 1.0;
|
}
|
|
depdemandqty := PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, 1.0 /* relative duration param */);
|
|
coef_relduration_partialcase := depdemandqty // in order to become PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, relativeduration ) - we multiply out the relative duration below
|
* scalefactor_periodtask_constddpartial * scaling // (done for efficiency)
|
|
this.InitConstraintsForOperationDependentDemands_Add( program,
|
runcontext,
|
scope,
|
input,
|
dd.PeriodTask_MP().UnitPeriod().Period_MP(),
|
pispipperiods,
|
usingproportialleadtimelogic,
|
scalefactor_partialoperationdemandqty_constddpartial,
|
scaling,
|
coef_relduration_partialcase );
|
}
|
}
|
}
|
else
|
{
|
periods := this.GetPeriodsForOperation( scope, operation ); // these are period task periods
|
|
// Only select the input where the product is included.
|
traverse( operation, OperationInput, input,
|
not input.IsElementOfInputGroup()
|
and ( input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( runcontext.IsPostProcessing() ) ) )
|
{
|
scaling := guard( input.Operation().OutputQuantity(), 1.0 ); // multiply out the denominator of OperationInput.Factor for better scaling
|
if ( scaling = 0.0 )
|
{
|
scaling := 1.0;
|
}
|
|
depdemandqty := PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, 1.0 /* relative duration param */);
|
coef_relduration_norelative := depdemandqty // used for case relative duration = 1.
|
* scalefactor_periodtask_constddqty * scaling;
|
|
coef_relduration_partialcase := depdemandqty // in order to become PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, relativeduration ) - we multiply out the relative duration below
|
* scalefactor_periodtask_constddpartial * scaling // (done for efficiency)
|
|
traverse( periods, Elements, period )
|
{
|
if( operation.HasLeadTime() )
|
// The dependent demand has to takes relative duration of the pispip period (the bucket it belongs) and the pt period into account.
|
{
|
if ( not this.GetPeriodsFromPeriodTaskOperation() )
|
{
|
// To get the period of period tasks from dependent demands, it can be treated as "new supplies" of dependent demands.
|
// Please read the optimizer solution design for more information.
|
pispipperiods := construct( Period_MPs, constcontent );
|
CapacityPlanningSuboptimizer::GetOperationDependentDemandPeriods( period, operation, &pispipperiods, this.GetPeriodsFromPeriodTaskOperation() );
|
|
this.InitConstraintsForOperationDependentDemands_Add( program,
|
runcontext,
|
scope,
|
input,
|
period,
|
pispipperiods,
|
usingproportialleadtimelogic,
|
scalefactor_partialoperationdemandqty_constddpartial,
|
scaling ,
|
coef_relduration_partialcase );
|
}
|
} // end if has lead time
|
else
|
{
|
// constddqty constraint UoM: input PISP
|
constddqty := program.OperationDependentDemandQtyConstraints().New( input, period );
|
constddqty.Sense( '=' );
|
// using default 0.0 RHS for constrddqty
|
|
// Term UoM: input PISP
|
constddqty.NewTerm( -1.0 * scalefactor_operationdemandqty_constddqty * scaling, program.OperationDemandQtyVariables().Get( input, period ) );
|
|
// Term: dependentdemandqty * PTQty variable
|
// UoM: [Unit to input PISP] * [Unit]
|
|
|
constddqty.NewTerm( coef_relduration_norelative, program.PTQtyVariables().Get( operation, period ) );
|
}
|
}
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|