陈清红
2025-04-14 880f3c0257eeb8c37761d484258fdd102a369a19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
Quintiq file version 2.0
#parent: #root
Method CapacityPlanningAlgorithmHandleInFeasible (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  RunContextForCapacityPlanning runcontext,
  LibOpt_Task task
)
{
  TextBody:
  [*
    // Set end time and status of optimizer run 
    
    status := Translations::MP_GlobalParameters_GetOptimizerInfeasibleStatus();
    
    algorithmrun := this.MacroPlan().GetLastAlgorithmRun(); 
    algorithmrun.Update( algorithmrun.Notes(), status );
    
    info( 'Remark:', program.Remark() );
    
    canrescue := this.CanRescueSolution( program, task ) 
    if( canrescue  )
    {
      status := Translations::MP_GlobalParameters_GetOptimizerFeasibleWithNumericalWarnings();
      algorithmrun.Update( algorithmrun.Notes(), status );
    
      info( 'Quality high enough, trying to use solution despite partial infeasibility.' );       
      
      algorithmrun.UpdateWorstStatus( status, program.Remark() ); 
      this.HandleFeasible( program, task ); 
    }
    else 
    {
      isfirsthandleinfeasiblecall := this.CurrentSubOptimizerLevel().IsFirst(); 
      if ( isfirsthandleinfeasiblecall ) // initialize of cplex needs to be const for paralellization. Any non-const processing is moved into the delayed initialization called on return of first handle feasible/infeasible. 
      {
        this.DelayedInitialization( program, task, runcontext, false );   
      }
      if( not runcontext.IsMetaIteration() )
      {
        info( 'Quality is not meeting expectation, solution will not be used.' );
        
        level := algorithmrun.GetAlgorithmRunLevel( this.CurrentSubOptimizerLevel().LevelNumber() );
        level.Update( level.Start(), DateTime::ActualTime(), false, program.AbsoluteGap(), program.RelativeGap(), program.GoalValue(), program.Optimal() );
        level.UpdateStatistics( program, this.IsAutoScalingEnabled() );
        algorithmrun.UpdateWorstStatus( status, program.Remark() );
        algorithmrun.CalcRunUIFeedback(); // AlgorithmRunLevel IsFeasible attribute is set above and this method should be called for propagating
        if( program.Remark() = CapacityPlanningSuboptimizer::GetTimeLimitExceededRemark() )
        {
          status := Translations::MP_GlobalParameters_GetOptimizerTimeLimitExceededStatus();    
        } 
        
        
        
        // Save the number of sanity check errors and the tooltip text on algorithm run for the benchmark problems
        Transaction::Transaction().Propagate();
        algorithmrun.NumberOfSanityCheckErrors( this.MacroPlan().SanityCheckHighestSeverityMsgCount() );
        if( algorithmrun.NumberOfSanityCheckErrors() > 0 )
        {
          algorithmrun.SanityCheckHighestSeverityToolTip( Translations::MP_SanityCheck_Failed( this.MacroPlan().MostSevereSanityCheckCategoryLevel() ) );
        }
      }
      
      // Run the automatic scaling if it is enabled and the solution could not be rescued
      // If it could be rescued, it will be run in the HandleFeasible method
      if( this.IsAutoScalingEnabled() )
      {
        this.RunAutoScaling( program, task, runcontext.IsMetaIteration() ); 
      }
      
      snapshotkpi := this.LogKPI( task, Translations::LibOpt_SnapshotMP_Details_NoSolutions() ); 
      snapshotkpi.astype( SnapshotMacroPlannerOptimizer ).IsAccepted( true ); 
    
      if ( runcontext.IsMetaIteration() and RunContextMeta::GetRunContextMeta( task.Run( )).OptionStopOnInfeasible() ) 
      {
        this.Run().BreakpointEvent( relnew );
        program.ProblemFileName( 'infeasible.sav' ); 
      }
    }
  *]
  InterfaceProperties { Accessibility: 'Module' }
}