Quintiq file version 2.0
|
#parent: #root
|
Method ActivateUnitShiftPatterns (
|
RunContextForCapacityPlanning runcontext,
|
RunContextMeta rcm,
|
LibOpt_Scope scope
|
)
|
{
|
TextBody:
|
[*
|
if ( runcontext.UseShiftOptimization() )
|
{
|
isoptimizeshiftchanges := runcontext.WeightLevelNonFinancial().ShiftPatternChangesPenaltyLevel() <= this.FocusLevel() and runcontext.WeightLevelNonFinancial().ShiftPatternChangesPenaltyWeight() > 0.0;
|
isoptimizershiftcost := exists( scope.GetAccountsInOptimizerRun(), Elements, account, account.HasStaffingAssignment(), account.Level() <= this.FocusLevel() and account.Weight() > 0.0 );
|
isneedoptimizershift := isoptimizeshiftchanges or isoptimizershiftcost or this.FocusLevel() = 0; // also include level 0 in case of fixing min shift durations.
|
|
maxnrunits := rcm.OptionShiftPatternMaxUnits();
|
maxshiftpatternsperunit := rcm.OptionShiftPatternMaxActive();
|
|
// first set all to not active
|
traverse( scope.GetUnitInOptimizerRun(), Elements, unit )
|
{
|
traverse( unit, UnitShiftPatternAllowed, usa )
|
{
|
usa.IsActive( false );
|
}
|
|
traverse( unit.GetAllChildren(), Elements.UnitShiftPatternAllowed, usa )
|
{
|
usa.IsActive( false );
|
}
|
}
|
|
// activate all for 'max nr units' problem units
|
problemups := selectset( scope.GetUnitInOptimizerRun(), Elements.UnitPeriod.astype( UnitPeriodTime ), up, true, not up.IsFulfilledMinimumShiftPatternDuration() );
|
problemunits := selectset( problemups, Elements.Unit, u, true, true ).SelectFirst( maxnrunits );
|
traverse( problemunits, Elements.UnitShiftPatternAllowed, usa )
|
{
|
usa.IsActive( true );
|
}
|
|
// activate all for 'max nr units' problem units of time aggregation type
|
problemupagg := selectset( scope.GetUnitInOptimizerRun(),
|
Elements.UnitPeriod.astype( UnitPeriodTimeAggregation ),
|
up,
|
true,
|
not up.GetAllChildrenOfUnitDimensionMinShiftPatternDurationFulfilled() );
|
|
|
traverse( problemupagg, Elements, up ) { debuginfo( up.UnitID(), up.Start() ) } ;
|
problemunitsagg := selectset( problemupagg, Elements.Unit, u, true, true ).SelectFirst( maxnrunits );
|
traverse( problemunitsagg, Elements, unit )
|
{
|
traverse( unit.GetAllChildren(), Elements.UnitShiftPatternAllowed, usa )
|
{
|
usa.IsActive( true );
|
}
|
}
|
|
// active for units without problem, make some random selection
|
unitsactive := selectsortedset( scope.GetUnitInOptimizerRun(),
|
Elements,
|
unit,
|
unit.UnitShiftPatternAllowed( relsize ) > 1
|
or exists( unit.GetAllChildren(), Elements, child, true, child.UnitShiftPatternAllowed( relsize ) > 1 ),
|
Real::Random() ).SelectFirst( maxnrunits );
|
|
|
// activate 'maxshiftpatternperunit' shift patterns for 'max nr unit' many units
|
counterchild := 0; // avoid selecting uncontrolled neighborhood size for puzzles with large number of child units
|
traverse( unitsactive, Elements, unit )
|
{
|
spactive := null( UnitShiftPatterns );
|
if ( isneedoptimizershift )
|
{
|
spactive := selectsortedset( unit, UnitShiftPatternAllowed, activeusa, true, Real::Random() ).SelectFirst( maxshiftpatternsperunit );
|
}
|
else
|
{
|
spactive := selectsortedset( unit, UnitShiftPatternAllowed, activeusa, true, -activeusa.ShiftPattern().TotalCapacity() ).SelectFirst( 1 );
|
}
|
traverse( spactive, Elements, sp )
|
{
|
sp.IsActive( true );
|
}
|
|
traverse( unit.GetAllChildren(), Elements, child, counterchild <= maxnrunits )
|
{
|
counterchild++;
|
|
spactivechild := null( UnitShiftPatterns );
|
if ( isneedoptimizershift )
|
{
|
spactivechild := selectsortedset( child, UnitShiftPatternAllowed, usa, true, Real::Random() ).SelectFirst( maxshiftpatternsperunit );
|
}
|
else
|
{
|
spactivechild := selectsortedset( child, UnitShiftPatternAllowed, usa, true, -usa.ShiftPattern().TotalCapacity() ).SelectFirst( 1 );
|
}
|
traverse( spactivechild, Elements, sp )
|
{
|
sp.IsActive( true );
|
}
|
}
|
}
|
|
totalallowedcombinations := counter( this.Optimization().astype( Optimization ).MacroPlan(), Unit.UnitShiftPatternAllowed, usa, true, usa.Unit().IsInOptimizerPuzzle() );
|
totalactive := counter( this.Optimization().astype( Optimization ).MacroPlan(), Unit.UnitShiftPatternAllowed, usa, true, usa.IsActive() and usa.Unit().IsInOptimizerPuzzle() );
|
nolimit := guard( totalactive / totalallowedcombinations > 0.95, true ) // just complete to unrestricted if some extraneous not activated
|
|
if ( nolimit )
|
{
|
// first set all to not active
|
traverse( this.Optimization().astype( Optimization ).MacroPlan(), Unit, unit )
|
{
|
traverse( unit, UnitShiftPatternAllowed, usa )
|
{
|
usa.IsActive( true );
|
}
|
|
traverse( unit.GetAllChildren(), Elements.UnitShiftPatternAllowed, usa )
|
{
|
usa.IsActive( true );
|
}
|
}
|
}
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|