Quintiq file version 2.0
|
#parent: #root
|
Method InitConstraintsForCampaignsManualSequenced (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
const LibOpt_Scope scope
|
) const
|
{
|
Description: 'Initialize constraints for campaign, which must be adhered'
|
TextBody:
|
[*
|
if( not runcontext.UseCampaignSequenceOptimizer() and runcontext.UseCampaign() )
|
{
|
totalptconstname := typeof( MPPTQtyCampaignsTotalConstraint );
|
cpcapconstname := typeof( MPCampaignPeriodCapacityConstraint );
|
tpcapconstname := typeof( MPTransitionPeriodCapacityConstraint );
|
minconstname := typeof( MPMinCampaignQuantityConstraint );
|
maxconstname := typeof( MPMaxCampaignQuantityConstraint );
|
|
scalefactor_periodtaskqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), totalptconstname );
|
scalefactor_ptcampaignqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), totalptconstname );
|
scalefactor_pttransitionqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTTransitionQtyVariable ), totalptconstname );
|
scalefactor_campaignperiodoverloaded_cpcapconst := this.ScaleConstraintTerm( typeof( MPCampaignPeriodOverloadedVariable ), cpcapconstname );
|
scalefactor_transitionperiodoverloaded_tpcapconst := this.ScaleConstraintTerm( typeof( MPTransitionPeriodOverloadedVariable ), tpcapconstname );
|
scalefactor_ptcampaignqty_cpcapconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), cpcapconstname );
|
scalefactor_pttransqty_tpcapconst := this.ScaleConstraintTerm( typeof( MPPTTransitionQtyVariable ), tpcapconstname );
|
scalefactor_mincampaignqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinCampaignQtyUnderVariable ), minconstname );
|
scalefactor_maxcampaignqtyover_maxconst := this.ScaleConstraintTerm( typeof( MPMaxCampaignQtyOverVariable ), maxconstname );
|
scalefactor_ptcampaignqty_minconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), minconstname );
|
scalefactor_ptcampaignqty_maxconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), maxconstname );
|
|
scalefactor_rhs_totalptconst := this.ScaleConstraintRHS( totalptconstname, 1.0 );
|
scalefactor_rhs_cpcapconst := this.ScaleConstraintRHS( cpcapconstname, 1.0 );
|
scalefactor_rhs_tpcapconst := this.ScaleConstraintRHS( tpcapconstname, 1.0 );
|
scalefactor_rhs_minconst := this.ScaleConstraintRHS( minconstname, 1.0 );
|
scalefactor_rhs_maxconst := this.ScaleConstraintRHS( maxconstname, 1.0 );
|
|
traverse( scope.GetOperationInOptimizerRunConst(), Elements, operation,
|
operation.OperationInCampaignType( relsize ) > 0
|
or operation.OperationInTransitionType( relsize ) > 0 )
|
{
|
// Only select those periods that are relevant for this operation for the optimizer run
|
periods := this.GetPeriodsForOperation( scope, operation );
|
|
traverse( periods, Elements, period,
|
period.GetIsInCampaignTypeHorizonUnit( operation.Unit() ) )
|
{
|
// total quantity planned in different campaign (pt in campaign) and transitions ( pt in transition) must match period task quantity
|
// Totalptconst constraint UoM: Unit
|
totalptconst := program.PTQtyCampaignsTotalConstraints().New( operation, period );
|
totalptconst.Sense( '=' );
|
totalptconst.RHSValue( 0.0 * scalefactor_rhs_totalptconst );
|
|
// Term UoM: Unit
|
totalptconst.NewTerm( -1.0 * scalefactor_periodtaskqty_totalptconst, program.PTQtyVariables().Get( operation, period ) );
|
|
traverse( operation, OperationInCampaign, operationincampaign,
|
exists( operationincampaign, Campaign_MP.PlanningCampaignPeriod, cperiod,
|
cperiod.Campaign_MP().IsWithinCampaignHorizon()
|
and cperiod.UnitPeriod().Period_MP() = period ) )
|
{
|
// Term UoM: Unit
|
totalptconst.NewTerm( 1.0 * scalefactor_ptcampaignqty_totalptconst, program.PTCampaignQtyVariables().Get( operationincampaign, period ) );
|
}
|
|
traverse( operation,
|
OperationInTransitionType.OperationInTransition,
|
oit
|
)
|
{
|
if ( exists( oit, Transition_MP.TransitionPeriod_MP, tperiod, tperiod.UnitPeriod().Period_MP() = period ) )
|
{
|
totalptconst.NewTerm( 1.0 * scalefactor_pttransitionqty_totalptconst, program.PTTransitionQtyVariables().Get( oit, period ) );
|
}
|
}
|
}
|
}
|
|
// Select those campaign periods for which the unit period is part of optimization
|
// and for which the unit period is within the campaign horizon
|
// and at least one operation is in the optimizer run
|
campaignperiods := selectset( scope.GetUnitInOptimizerRunConst(), Elements.CampaignType_MP.Campaign_MP.PlanningCampaignPeriod, cp,
|
cp.Campaign_MP().IsWithinCampaignHorizon()
|
and guard( scope.Contains( cp.UnitPeriod().UnitPeriodInOptimizerRun() ), false )
|
and guard( cp.UnitPeriod().GetIsWithinCampaignHorizonConstraint(), false )
|
and exists( cp.Campaign_MP(), OperationInCampaign.Operation, operation,
|
scope.Contains( operation.OperationInOptimizerRun() ) ) )
|
|
// max quantity plannable on period tasks per campaign
|
// If campaign overlap partially with period, we can only plan overlap ratio * up.TotalAvailableCapacity quantity at that period
|
// if no campaign exists (ratio = 0), the period task cannot planned on this campaign.
|
traverse( campaignperiods, Elements, cperiod )
|
{
|
period := cperiod.UnitPeriod().Period_MP();
|
up := cperiod.UnitPeriod();
|
|
if( not up.IsPlannedInfinite() )
|
{
|
//cpcapconst constraint UoM: Unit or Time
|
cpcapconst := program.CampaignPeriodCapacityConstraints().New( cperiod );
|
cpcapconst.Sense( '<=' );
|
// RHS: availablecapratio * totalavailablecap
|
// UoM: [-] * [Unit or Time]
|
value := guard( cperiod.AvailableCapacityRatio() * up.GetTotalAvailableCapacity(), 0 );
|
cpcapconst.RHSValue( value * scalefactor_rhs_cpcapconst );
|
|
// Term UoM: Unit or Time
|
cpcapconst.NewTerm( -1.0 * scalefactor_campaignperiodoverloaded_cpcapconst,
|
program.CampaignPeriodOverloadedVariables().Get( cperiod ) );
|
|
// Only consider those operation that are relevant for this unit period for the optimizer run
|
operations := this.GetOperationsForUnitPeriod( scope, up );
|
|
// The operation must be part of the same campaign as the campaign period
|
traverse( operations, Elements.OperationInCampaign, oic,
|
oic.Campaign_MP() = cperiod.Campaign_MP() )
|
{
|
// Term: capacityusagequantity * PTQtyCampaign variable
|
// UoM: [- or Time/Unit ] * [Unit]
|
cpcapconst.NewTerm( oic.Operation().GetCapacityUsagePerQuantity( up )
|
* scalefactor_ptcampaignqty_cpcapconst,
|
program.PTCampaignQtyVariables().Get( oic, period ) );
|
}
|
}
|
}
|
|
transitionperiods := selectset( scope.GetUnitInOptimizerRunConst(),
|
Elements.TransitionType_MP.Transition_MP.TransitionPeriod_MP,
|
tp,
|
tp.Transition_MP().IsWithinCampaignHorizon()
|
and guard( scope.Contains( tp.UnitPeriod().UnitPeriodInOptimizerRun() ), false )
|
and guard( tp.UnitPeriod().GetIsWithinCampaignHorizonConstraint(), false )
|
and exists( tp.Transition_MP(), OperationInTransition.OperationInTransitionType.Operation, operation,
|
scope.Contains( operation.OperationInOptimizerRun() ) ) )
|
|
traverse( transitionperiods, Elements, tperiod )
|
{
|
period := tperiod.UnitPeriod().Period_MP();
|
up := tperiod.UnitPeriod();
|
|
if( not up.IsPlannedInfinite() )
|
{
|
//cpcapconst constraint UoM: Unit or Time
|
tpcapconst := program.TransitionPeriodCapacityConstraints().New( tperiod );
|
tpcapconst.Sense( '<=' );
|
// RHS: availablecapratio * totalavailablecap
|
// UoM: [-] * [Unit or Time]
|
value := guard( tperiod.AvailableCapacityRatio() * up.GetTotalAvailableCapacity(), 0 );
|
tpcapconst.RHSValue( value * scalefactor_rhs_tpcapconst );
|
|
// Term UoM: Unit or Time
|
tpcapconst.NewTerm( -1.0 * scalefactor_transitionperiodoverloaded_tpcapconst,
|
program.TransitionPeriodOverloadedVariables().Get( tperiod ) );
|
|
// Only consider those operation that are relevant for this unit period for the optimizer run
|
operations := this.GetOperationsForUnitPeriod( scope, up );
|
|
// The operation must be part of the same campaign as the campaign period
|
traverse( operations, Elements.OperationInTransitionType.OperationInTransition, oit,
|
oit.Transition_MP() = tperiod.Transition_MP() )
|
{
|
// Term: capacityusagequantity * PTQtyCampaign variable
|
// UoM: [- or Time/Unit ] * [Unit]
|
tpcapconst.NewTerm( oit.OperationInTransitionType().Operation().GetCapacityUsagePerQuantity( up )
|
* scalefactor_pttransqty_tpcapconst,
|
program.PTTransitionQtyVariables().Get( oit, period ) );
|
}
|
}
|
}
|
|
// Quantity planned on campaign must be within the defined min and max quantity of campaign
|
// Campaign spans multiple periods, thus performing selectset
|
campaigns := selectset( campaignperiods, Elements.Campaign_MP, campaign,
|
|
campaign.IsWithinCampaignHorizon()
|
and exists( campaign, OperationInCampaign.Operation, operation,
|
scope.Contains( operation.OperationInOptimizerRun() ) ) );
|
|
traverse( campaigns, Elements, campaign, campaign.MinQuantity() > 0 )
|
{
|
|
// minconst constraint UoM: Unit
|
minconst := program.MinCampaignQuantityConstraints().New( campaign );
|
minconst.Sense( '>=' );
|
// RHS UoM: Unit
|
minconst.RHSValue( campaign.MinQuantity() * scalefactor_rhs_minconst );
|
// Term UoM: Unit
|
minconst.NewTerm( 1.0 * scalefactor_mincampaignqtyunder_minconst, program.MinCampaignQtyUnderVariables().Get( campaign ) );
|
|
traverse( campaignperiods, Elements, campaignperiod,
|
campaignperiod.Campaign_MP() = campaign )
|
{
|
// Only consider those operation that are relevant for this unit period for the optimizer run
|
operations := this.GetOperationsForUnitPeriod( scope, campaignperiod.UnitPeriod() );
|
|
// The operation must be part of the same campaign as the campaign period
|
traverse( operations, Elements.OperationInCampaign, oic,
|
oic.Campaign_MP() = campaignperiod.Campaign_MP() )
|
{
|
ptcampaignqtyvar := program.PTCampaignQtyVariables().Get( oic, campaignperiod.UnitPeriod().Period_MP() );
|
|
processfactor := oic.Operation().QuantityToProcessFactor();
|
// Term: processfactor * PTQtyCampaign variable
|
// UoM: [-] * [Unit]
|
minconst.NewTerm( processfactor * scalefactor_ptcampaignqty_minconst, ptcampaignqtyvar );
|
|
}
|
}
|
}
|
traverse( campaigns, Elements, campaign, campaign.HasInputMaxQuantity() )
|
{
|
// maxconst constraint UoM: Unit
|
maxconst := program.MaxCampaignQuantityConstraints().New( campaign );
|
maxconst.Sense( '<=' );
|
// RHS UoM: Unit
|
maxconst.RHSValue( campaign.MaxQuantity() * scalefactor_rhs_maxconst );
|
// Term UoM: Unit
|
maxconst.NewTerm( -1.0 * scalefactor_maxcampaignqtyover_maxconst, program.MaxCampaignQtyOverVariables().Get( campaign ) );
|
|
traverse( campaignperiods, Elements, campaignperiod,
|
campaignperiod.Campaign_MP() = campaign )
|
{
|
// Only consider those operation that are relevant for this unit period for the optimizer run
|
operations := this.GetOperationsForUnitPeriod( scope, campaignperiod.UnitPeriod() );
|
|
// The operation must be part of the same campaign as the campaign period
|
traverse( operations, Elements.OperationInCampaign, oic,
|
oic.Campaign_MP() = campaignperiod.Campaign_MP() )
|
{
|
ptcampaignqtyvar := program.PTCampaignQtyVariables().Get( oic, campaignperiod.UnitPeriod().Period_MP() );
|
|
processfactor := oic.Operation().QuantityToProcessFactor();
|
// Term: processfactor * PTQtyCampaign variable
|
// UoM: [-] * [Unit]
|
maxconst.NewTerm( processfactor * scalefactor_ptcampaignqty_maxconst, ptcampaignqtyvar );
|
}
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|