yanweiyuan3
2023-08-09 588bc7829387dfc761cc25f06f77d4c81818bd10
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
Quintiq file version 2.0
#parent: #root
Method Evaluate
{
  Description: 'Evaluate whether this iteration is better than the previous best iteration'
  TextBody:
  [*
    // edz1 Sep-2-2016 (created)
    
    // Mark the iteration as complete
    this.IsFinished( true );
    
    isfirstiteration := this.Start() = this.DEPRECATED_InventoryOptimization().StartInventoryOptimization();
    
    // Correct the total KPI value for the service level (Inventory Optimization KPI)
    traverse( this, IterationLevel, iterationlevel )
    {
      iterationlevel.SetCorrectedExpectedTotalKPIValue();
    }
    
    // If this is the first iteration, then it is the best iteration
    if( isfirstiteration )
    {
      this.SetAsBestIteration();
    }
    // Otherwise we will evaluate the iteration
    else
    {
      // Select the previous best iteration
      prevbestiteration := select( this, DEPRECATED_InventoryOptimization.Iteration, iteration, iteration.IsBestIteration() );  
          
      if( this.GetIsImprovement() )
      {
        // If this is an improvement, it is the best iteration
        this.SetAsBestIteration();
        
        // Since this is an improvement, reset the number of consecutive failures
        traverse( this, Move, move )
        {
          move.NumberOfConsecutiveRejections( 0 );
        }
        
        // Since we have found an improvement, all other moves that had previously already been tried may now give an improvement again
        // So we no longer mark them as has been tried
        traverse( this, DEPRECATED_InventoryOptimization.Move, move, move.HasBeenTried() )
        {
          move.HasBeenTried( false );
        }
      }    
      // Otherwise undo the move and mark it as has been tried
      else
      {
        traverse( this, Move, move )
        {
          move.UndoMove();
        }
      }
    
      // Update the benefit of the latest attempt for the step moves
      traverse( this, Move.astype( MoveStep ), move )
      {
        previousavgservicelevel := average( move, InventorySpecification.InventorySpecificationInServiceLevel.ServiceLevelBase.IterationServiceLevel, itsl,
                                            itsl.Iteration() = prevbestiteration,
                                            itsl.AchievedServiceLevel() );
        // Update the achieved service levels of the current iteration
        traverse( this, IterationServiceLevel, itsl )
        {
          traverse( itsl, IterationPISPIP, itpispip )
          {
            itpispip.CalcTotalDemand();
            itpispip.CalcAchievedServiceLevel();
          }
          itsl.CalcAchievedServiceLevel();
        }
    
        newavgservicelevel := average( move, InventorySpecification.InventorySpecificationInServiceLevel.ServiceLevelBase.IterationServiceLevel, itsl,
                                       itsl.Iteration() = this,
                                       itsl.AchievedServiceLevel() );
    
        benefit := 0.0;
        if( move.QuantityForUndo() > 0 )
        {
          benefit := ( newavgservicelevel - previousavgservicelevel ) / move.QuantityForUndo();
        }
        
        if( not move.IsIncrease() )
        {
          benefit := -benefit;
        }
        move.BenefitPerQtyLatestAttempt( benefit );              
      }
    }
    
    // If this is the best iteration and we should automatically select the best iteration
    // Then select this iteration and update the expected KPIs on the PISPs
    if( this.IsBestIteration() and this.DEPRECATED_InventoryOptimization().IsSelectBestIteration() )
    { 
      this.SelectIterationAndInventorySpecifications();
    }
  *]
}