Quintiq file version 2.0
|
#parent: #root
|
Method ActivateNonHierarchicalGoals (
|
CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
|
const RunContextForCapacityPlanning runcontext,
|
const LibOpt_Scope scope
|
) const
|
{
|
Description: 'Activate goal of current level, deactivate previous level goal, and freeze total goal value of previous goal'
|
TextBody:
|
[*
|
// Set time limit and gap according to selected algorithm run level
|
if ( not this.CurrentSubOptimizerLevel().IsExtraPTQTYLevelMetaOptimizer() )
|
{
|
this.SetCPLEXParametersNonHierarchicalGoal( program, this.CurrentSubOptimizerLevel().GetStrategyLevelMacroPlan(), scope );
|
}
|
|
// Freeze total value of goals at previous level
|
previouslevel := this.CurrentSubOptimizerLevel().PreviousSubOptimizerLevel();
|
previouslevel_slmp := guard( previouslevel.GetStrategyLevelMacroPlan(), constnull( StrategyLevelMacroPlan ) );
|
|
if( not isnull( previouslevel ) ) // for the very first initialization from the algorithm tab currentrunlevel will be null (nothing to remove/freeze).
|
{
|
debuginfo( 'removing goal term for ', previouslevel.LevelNumber(), ' currentrunlevelkey = ', previouslevel.Key() );
|
goalvar := program.GoalForLevelVariables().Get( previouslevel_slmp );
|
debuginfo( 'goal var optimal val = ', goalvar.OptimalValue(), ' program goal = ', program.GoalValue() );
|
|
// remove goal var from goal
|
program.Goal().Term( goalvar ).Coefficient( 0.0 );
|
|
// Set lower bound for removed goal var
|
goalvalue := program.GoalValue();
|
// The goal slack is the relative slack times the goal value
|
// To avoid problems related to very small goal values, the relative goal slack is also used as a lowerbound of the slack
|
slackformeta := ifexpr( this.CurrentSubOptimizerLevel().IsExtraPTQTYLevelMetaOptimizer(), this.IsExecutePTQTYRelativeGoalSlack(), 0.0 ); // adding some slack in case of ptqty goal to avoid numerical issues
|
slackfactor := ifexpr( runcontext.IsMetaIteration(), slackformeta, previouslevel_slmp.RelativeGoalSlack() );
|
slack := abs( slackfactor * goalvalue );
|
if ( slack < previouslevel_slmp.FeasibilityTolerance() )
|
{
|
slack := 100.0; // avoid epsilon logic Quintiq
|
slack := 0.0;
|
}
|
|
lowerbound := goalvalue - slack;
|
|
if ( this.CurrentSubOptimizerLevel().LevelNumber() = 0 or guard( previouslevel_slmp.KPIUpperBound() = 0, false ) ) // guard for case we have the extra PTQTY level (has no corresponding slevel mp)
|
{
|
lowerbound := minvalue( lowerbound, 0.0 ); // never fix more than >= 0 when we know this is optimal
|
}
|
|
goalvar.LowerBound( lowerbound );
|
debuginfo( 'Setting lowerbound' , lowerbound, ' for goal var level ', previouslevel.LevelNumber(), 'slack=', slack, 'slackfactor=', slackfactor, 'goalvar name=', goalvar.Name() );
|
}
|
|
// add variable for next level to goal
|
if ( this.CurrentSubOptimizerLevel().IsExtraPTQTYLevelMetaOptimizer() )
|
{
|
this.AddPTQtyGoal( scope, program, program.Goal() );
|
}
|
else
|
{
|
nextgoalvar := program.GoalForLevelVariables().Get( this.CurrentSubOptimizerLevel().GetStrategyLevelMacroPlan() );
|
program.Goal().NewTerm( 1.0, nextgoalvar );
|
}
|
|
if ( this.DoLevelCollapse( runcontext ) )
|
{
|
slackgoal := program.GoalForLevelVariables().Get( this.GetRunLevel( 0 ) );
|
program.Goal().NewTerm( this.OptionCollapseLevelWeight(), slackgoal );
|
program.Goal().Term( slackgoal ).Coefficient( this.OptionCollapseLevelWeight() ); // ensure we don't keep adding it
|
}
|
*]
|
InterfaceProperties { Accessibility: 'Module' }
|
}
|