| 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' } | 
| } |