Quintiq file version 2.0
|
#parent: #root
|
Method CapacityPlanningAlgorithmHandleFeasible (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
LibOpt_Task task
|
) as CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm
|
{
|
Description: 'The method called in "Handle feasible" tab'
|
TextBody:
|
[*
|
scope := task.Scope();
|
// Program goal value is affected by goal scaling factor. It is intended to show the CPLEX value with scaling applied
|
goalvalue := program.GoalValue();
|
isinventoryoptimization := runcontext.IsInventoryOptimizationRun();
|
// We only want to report the progress of the algorithm runs if this is not an autotune copy and this is not an inventory optimization
|
isdisplay := not isinventoryoptimization
|
and not runcontext.IsMetaIteration();
|
|
// Do not report the current level if this is an inventory optimization run
|
if( isdisplay )
|
{
|
info( Translations::Algorithm_MP_InfoCurrentLevel( [String]this.CurrentSubOptimizerLevel().LevelNumber() ) );
|
info( Translations::Algorithm_MP_InfoFeasibleCapacityPlanning( [String]DateTime::ActualTime(), [String]goalvalue ) );
|
}
|
|
dofinalize := this.CurrentSubOptimizerLevel().IsLast() or ( this.UseHierarchicalCPLEXGoals() );
|
justoptimizerhiddenslacklevel := this.CurrentSubOptimizerLevel().IsFirst();
|
algorithmrun := this.MacroPlan().GetLastAlgorithmRun();
|
iscampainoptimization := runcontext.UseCampaignSequenceOptimizer();
|
|
if ( not runcontext.IsMetaIteration() )
|
{
|
this.DebugWriteForAutoTestInstances( program, runcontext, scope );
|
this.AppendLastRunResultToLogFile( program ); // Update the log file with the latest results
|
}
|
|
// Update postprocessing start
|
algorithmrun.UpdatePostprocessingTime( DateTime::ActualTime(), algorithmrun.PostprocessingEnd() );
|
|
if( isdisplay )
|
{
|
this.DisplayGoalValue( program, runcontext ); // Display scores
|
}
|
if( not task.IsAborted()
|
and dofinalize
|
and ( not runcontext.IsMetaIteration() or ( this.IsBeyondFirstIteration() or iscampainoptimization) or this.IsFullPlanMetaPriorFocus() ) ) // first iteration for meta optimizer we don't plan, unless campaign optimization
|
{ // as we need to know feasbility of campaign combis, for level 0 score
|
pispipsinrun := scope.GetPISPIPInOptimizerRun();
|
// Handle feasible methods to assign optimizer optimal value to attributes
|
this.ResetPeriodTaskCampaign( runcontext, scope );
|
this.CapacityPlanningAlgorithmHandleFeasibleCampaignSequencing( program, runcontext, task );
|
this.CapacityPlanningAlgorithmHandleFeasibleOperationPeriodTask( program, runcontext, task );
|
this.CapacityPlanningAlgorithmHandleFeasibleTrip( program, scope );
|
this.CapacityPlanningAlgorithmHandleFeasibleSalesDemand( program, runcontext, scope, pispipsinrun );
|
this.CapacityPlanningAlgorithmHandleFeasibleProductInStockingPointInPeriod( program, runcontext, scope, this.Setting_KeepTotAlavailableSupplyOverride(), pispipsinrun );
|
this.CapacityPlanningAlgorithmHandleFeasibleShiftPattern( program, runcontext, scope );
|
this.SetOptimizerFulfilledTargetInventoryQuantityPastHorizon( runcontext, scope );
|
Transaction::Transaction().Propagate();
|
this.DebugWriteVariables( program, scope, pispipsinrun );
|
if ( runcontext.IsSlidingWindowsRun() )
|
{
|
this.CurrentSubOptimizerLevel( relset, this.FirstSubOptimizerLevel() );
|
}
|
else
|
{
|
this.CurrentSubOptimizerLevel( relflush ); // signal for post handle results, so we only obtain KPIs all the way at the end (is expensive)
|
}
|
if ( this.Optimization().astype( Optimization ).DebugMode() )
|
{
|
this.Optimization().astype( Optimization ).CheckOptimizerPuzzle( task );
|
}
|
}
|
|
// Update postprocessing end
|
algorithmrun.UpdatePostprocessingTime( algorithmrun.PostprocessingStart(), DateTime::ActualTime() );
|
|
isunfreeze := false;
|
if ( justoptimizerhiddenslacklevel
|
and not dofinalize )
|
{
|
this.FreezeZeroSlack( program, isunfreeze, runcontext, scope );
|
}
|
|
if( ( not runcontext.IsMetaIteration() or ( this.IsBeyondFirstIteration() or iscampainoptimization ) or this.IsFullPlanMetaPriorFocus() ) // first iteration of level for meta optimizer we do plan, just record KPI to check skip to next focuslevel
|
and not task.IsAborted()
|
and not dofinalize )
|
{
|
this.SetNextSubOptimizerLevelAsCurrent();
|
this.ActivateGoals( program, runcontext, scope ); //activate terms for next level
|
|
if( isdisplay )
|
{
|
info( Translations::Algorithm_MP_InfoReExecuteLevel( [String]DateTime::ActualTime(), [String]( this.CurrentSubOptimizerLevel().LevelNumber() ), [String]goalvalue ) );
|
this.AddLogFileMarking( program );
|
}
|
|
// Re-execute cplex
|
program.MIPStartSolution( true );
|
this.ReExecute( program );
|
|
// Add extension to program file name such that it is postfix with level
|
filename := program.ProblemFileName();
|
if( filename <> Util::Const_EmptyString() )
|
{
|
nextlevel := this.CurrentSubOptimizerLevel().LevelNumber();
|
strings := filename.Tokenize( Util::Const_Dot() );
|
extension := ifexpr( this.IsLPFileExported(), Translations::Algorithm_MP_FileExtensionSav(), guard( strings.Element( strings.Size() - 1 ), Translations::Algorithm_MP_FileExtensionSav() ) );
|
program.ProblemFileName( Translations::Algorithm_MP_ProblemFileName( nextlevel.AsQUILL(), extension ) );
|
debuginfo( 'Problem file name=', program.ProblemFileName() );
|
}
|
}
|
|
// Run the autoscaling
|
if( this.IsAutoScalingEnabled() and dofinalize )
|
{
|
// Update the rest of the statistics and run the autoscaling after the last level
|
this.RunAutoScaling( program, task, runcontext.IsMetaIteration() );
|
}
|
|
if ( not runcontext.IsMetaIteration() )
|
{
|
algorithmrun.CalcRunUIFeedback(); // AlgorithmRunLevel IsFeasible attribute is set above and this method should be called for propagating
|
}
|
|
if( dofinalize
|
and not runcontext.IsMetaIteration() )
|
{
|
// If this is a sliding windows run and the last period in the active window is not the last period in the optimizer run
|
// then slide the window and reexecute the algorithm
|
lastperiodinwindow := maxselect( scope.GetPeriodInSlidingWindow(), Elements, period, true, period.Start() );
|
if( runcontext.IsSlidingWindowsRun()
|
and lastperiodinwindow <> runcontext.LastPeriod_MP() )
|
{
|
this.ReExecuteOptimizerSlidingWindows( program, runcontext, task );
|
}
|
else
|
{
|
if( runcontext.IsInventoryOptimizationRun() )
|
{
|
runcontext_nonconst := select( task, Run.RunContext.astype( RunContextForCapacityPlanning ), rctxt, true, true ); // workaround because we don't want avoid the cascase of const argument down this path
|
this.CapacityPlanningAlgorithmHandleFeasibleInventoryOptimization( runcontext_nonconst, scope );
|
}
|
|
if( algorithmrun.IsBenchmark() )
|
{
|
Transaction::Transaction().Propagate();
|
algorithmrun.NumberOfSanityCheckErrors( this.MacroPlan().SanityCheckHighestSeverityMsgCount() );
|
if( algorithmrun.NumberOfSanityCheckErrors() > 0 )
|
{
|
algorithmrun.SanityCheckHighestSeverityToolTip( Translations::MP_SanityCheck_Failed( this.MacroPlan().MostSevereSanityCheckCategoryLevel() ) );
|
}
|
}
|
}
|
}
|
|
return program;
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|